-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[msan] Add 32-bit platforms support #109284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
a9bbb7e
8c8ca4a
d183648
58eb2ac
b832f46
2776315
fc61594
715df4b
94ba759
a069e4c
140f33d
7b7fddb
7fc981c
9fdb85e
1c3fcab
a2bd2ad
e4ebee1
83763f3
c15c29f
ef030a6
18b6d5e
1fe3a4e
f71ef90
95c8c2b
7c425cf
4ad58c8
3415aa5
c8ec352
9e108b0
92c419c
7b03354
fda60eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -559,6 +559,7 @@ class MemorySanitizer { | |
friend struct VarArgAArch64Helper; | ||
friend struct VarArgPowerPCHelper; | ||
friend struct VarArgSystemZHelper; | ||
friend struct VarArgI386Helper; | ||
friend struct VarArgGenericHelper; | ||
|
||
void initializeModule(Module &M); | ||
|
@@ -5595,6 +5596,8 @@ struct VarArgPowerPCHelper : public VarArgHelperBase { | |
: VarArgHelperBase(F, MS, MSV, VAListTagSize) {} | ||
|
||
void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override { | ||
const DataLayout &DL = F.getDataLayout(); | ||
|
||
// For PowerPC, we need to deal with alignment of stack arguments - | ||
// they are mostly aligned to 8 bytes, but vectors and i128 arrays | ||
// are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes, | ||
|
@@ -5606,12 +5609,16 @@ struct VarArgPowerPCHelper : public VarArgHelperBase { | |
// Parameter save area starts at 48 bytes from frame pointer for ABIv1, | ||
// and 32 bytes for ABIv2. This is usually determined by target | ||
// endianness, but in theory could be overridden by function attribute. | ||
if (TargetTriple.getArch() == Triple::ppc64) | ||
VAArgBase = 48; | ||
else | ||
VAArgBase = 32; | ||
if (TargetTriple.isPPC64()) { | ||
if (TargetTriple.isPPC64ELFv2ABI()) | ||
VAArgBase = 32; | ||
else | ||
VAArgBase = 48; | ||
} else { | ||
// Parameter save area is 8 bytes from frame pointer in PPC32 | ||
VAArgBase = 8; | ||
} | ||
unsigned VAArgOffset = VAArgBase; | ||
const DataLayout &DL = F.getDataLayout(); | ||
for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) { | ||
bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams(); | ||
bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal); | ||
|
@@ -5674,7 +5681,7 @@ struct VarArgPowerPCHelper : public VarArgHelperBase { | |
} | ||
|
||
Constant *TotalVAArgSize = | ||
ConstantInt::get(IRB.getInt64Ty(), VAArgOffset - VAArgBase); | ||
ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase); | ||
// Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of | ||
// a new class member i.e. it is the total size of all VarArgs. | ||
IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); | ||
|
@@ -5684,7 +5691,7 @@ struct VarArgPowerPCHelper : public VarArgHelperBase { | |
assert(!VAArgSize && !VAArgTLSCopy && | ||
"finalizeInstrumentation called twice"); | ||
IRBuilder<> IRB(MSV.FnPrologueEnd); | ||
VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS); | ||
VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS); | ||
Value *CopySize = | ||
IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); | ||
|
||
|
@@ -5709,11 +5716,26 @@ struct VarArgPowerPCHelper : public VarArgHelperBase { | |
for (CallInst *OrigInst : VAStartInstrumentationList) { | ||
NextNodeIRBuilder IRB(OrigInst); | ||
Value *VAListTag = OrigInst->getArgOperand(0); | ||
Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr( | ||
IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), MS.PtrTy); | ||
Value *RegSaveAreaPtrPtr; | ||
|
||
Triple TargetTriple(F.getParent()->getTargetTriple()); | ||
|
||
// In PPC32 va_list_tag is a struct, whereas in PPC64 it's a pointer | ||
if (TargetTriple.isPPC64()) { | ||
RegSaveAreaPtrPtr = IRB.CreateIntToPtr( | ||
IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), MS.PtrTy); | ||
} else { | ||
RegSaveAreaPtrPtr = IRB.CreateIntToPtr( | ||
IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), | ||
ConstantInt::get(MS.IntptrTy, 8)), | ||
MS.PtrTy); | ||
} | ||
|
||
Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr); | ||
Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr; | ||
const Align Alignment = Align(8); | ||
const DataLayout &DL = F.getDataLayout(); | ||
unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy); | ||
const Align Alignment = Align(IntptrSize); | ||
std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) = | ||
MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), | ||
Alignment, /*isStore*/ true); | ||
|
@@ -6004,8 +6026,122 @@ struct VarArgSystemZHelper : public VarArgHelperBase { | |
} | ||
}; | ||
|
||
/// MIPS-specific implementation of VarArgHelper. | ||
/// NOTE: This is also used for LoongArch64. | ||
/// i386-specific implementation of VarArgHelper. | ||
struct VarArgI386Helper : public VarArgHelperBase { | ||
k-kashapov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
AllocaInst *VAArgTLSCopy = nullptr; | ||
Value *VAArgSize = nullptr; | ||
|
||
VarArgI386Helper(Function &F, MemorySanitizer &MS, | ||
MemorySanitizerVisitor &MSV) | ||
: VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/4) {} | ||
|
||
void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override { | ||
const DataLayout &DL = F.getDataLayout(); | ||
unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy); | ||
unsigned VAArgOffset = 0; | ||
for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) { | ||
bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams(); | ||
bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal); | ||
if (IsByVal) { | ||
assert(A->getType()->isPointerTy()); | ||
Type *RealTy = CB.getParamByValType(ArgNo); | ||
uint64_t ArgSize = DL.getTypeAllocSize(RealTy); | ||
Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize)); | ||
if (ArgAlign < IntptrSize) | ||
ArgAlign = Align(IntptrSize); | ||
VAArgOffset = alignTo(VAArgOffset, ArgAlign); | ||
if (!IsFixed) { | ||
Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize); | ||
if (Base) { | ||
Value *AShadowPtr, *AOriginPtr; | ||
std::tie(AShadowPtr, AOriginPtr) = | ||
MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), | ||
kShadowTLSAlignment, /*isStore*/ false); | ||
|
||
IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr, | ||
kShadowTLSAlignment, ArgSize); | ||
} | ||
VAArgOffset += alignTo(ArgSize, Align(IntptrSize)); | ||
} | ||
} else { | ||
Value *Base; | ||
uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); | ||
Align ArgAlign = Align(IntptrSize); | ||
VAArgOffset = alignTo(VAArgOffset, ArgAlign); | ||
if (DL.isBigEndian()) { | ||
// Adjusting the shadow for argument with size < IntptrSize to match | ||
// the placement of bits in big endian system | ||
if (ArgSize < IntptrSize) | ||
VAArgOffset += (IntptrSize - ArgSize); | ||
} | ||
if (!IsFixed) { | ||
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize); | ||
if (Base) | ||
IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); | ||
VAArgOffset += ArgSize; | ||
VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize)); | ||
} | ||
} | ||
} | ||
|
||
Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset); | ||
// Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of | ||
// a new class member i.e. it is the total size of all VarArgs. | ||
IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); | ||
} | ||
|
||
void finalizeInstrumentation() override { | ||
assert(!VAArgSize && !VAArgTLSCopy && | ||
"finalizeInstrumentation called twice"); | ||
|
||
IRBuilder<> IRB(MSV.FnPrologueEnd); | ||
VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS); | ||
Value *CopySize = IRB.CreateAdd( | ||
ConstantInt::get(MS.IntptrTy, 0), | ||
IRB.CreateIntCast(VAArgSize, MS.IntptrTy, /*isSigned*/ false)); | ||
|
||
if (!VAStartInstrumentationList.empty()) { | ||
// If there is a va_start in this function, make a backup copy of | ||
// va_arg_tls somewhere in the function entry block. | ||
VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); | ||
VAArgTLSCopy->setAlignment(kShadowTLSAlignment); | ||
IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()), | ||
CopySize, kShadowTLSAlignment, false); | ||
|
||
Value *SrcSize = IRB.CreateBinaryIntrinsic( | ||
Intrinsic::umin, CopySize, | ||
ConstantInt::get(MS.IntptrTy, kParamTLSSize)); | ||
IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS, | ||
kShadowTLSAlignment, SrcSize); | ||
} | ||
|
||
// Instrument va_start. | ||
// Copy va_list shadow from the backup copy of the TLS contents. | ||
for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { | ||
CallInst *OrigInst = VAStartInstrumentationList[i]; | ||
NextNodeIRBuilder IRB(OrigInst); | ||
Value *VAListTag = OrigInst->getArgOperand(0); | ||
Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); | ||
Value *RegSaveAreaPtrPtr = | ||
IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), | ||
PointerType::get(RegSaveAreaPtrTy, 0)); | ||
Value *RegSaveAreaPtr = | ||
IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr); | ||
Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr; | ||
const DataLayout &DL = F.getDataLayout(); | ||
unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy); | ||
const Align Alignment = Align(IntptrSize); | ||
std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) = | ||
MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), | ||
Alignment, /*isStore*/ true); | ||
IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment, | ||
CopySize); | ||
} | ||
} | ||
}; | ||
|
||
/// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV, | ||
/// LoongArch64. | ||
struct VarArgGenericHelper : public VarArgHelperBase { | ||
AllocaInst *VAArgTLSCopy = nullptr; | ||
Value *VAArgSize = nullptr; | ||
|
@@ -6017,24 +6153,25 @@ struct VarArgGenericHelper : public VarArgHelperBase { | |
void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override { | ||
unsigned VAArgOffset = 0; | ||
const DataLayout &DL = F.getDataLayout(); | ||
unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy); | ||
for (Value *A : | ||
llvm::drop_begin(CB.args(), CB.getFunctionType()->getNumParams())) { | ||
uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); | ||
if (DL.isBigEndian()) { | ||
// Adjusting the shadow for argument with size < 8 to match the | ||
// Adjusting the shadow for argument with size < IntptrSize to match the | ||
// placement of bits in big endian system | ||
if (ArgSize < 8) | ||
VAArgOffset += (8 - ArgSize); | ||
if (ArgSize < IntptrSize) | ||
VAArgOffset += (IntptrSize - ArgSize); | ||
} | ||
Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize); | ||
VAArgOffset += ArgSize; | ||
VAArgOffset = alignTo(VAArgOffset, 8); | ||
VAArgOffset = alignTo(VAArgOffset, IntptrSize); | ||
if (!Base) | ||
continue; | ||
IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); | ||
} | ||
|
||
Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset); | ||
vitalybuka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset); | ||
// Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of | ||
// a new class member i.e. it is the total size of all VarArgs. | ||
IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); | ||
|
@@ -6043,8 +6180,9 @@ struct VarArgGenericHelper : public VarArgHelperBase { | |
void finalizeInstrumentation() override { | ||
assert(!VAArgSize && !VAArgTLSCopy && | ||
"finalizeInstrumentation called twice"); | ||
|
||
IRBuilder<> IRB(MSV.FnPrologueEnd); | ||
VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we change runtime to uptr? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is also unclear, could you specify your question please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is
which can be Actually changing this if follow up PR is better |
||
VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS); | ||
Value *CopySize = | ||
IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); | ||
|
||
|
@@ -6068,11 +6206,16 @@ struct VarArgGenericHelper : public VarArgHelperBase { | |
for (CallInst *OrigInst : VAStartInstrumentationList) { | ||
NextNodeIRBuilder IRB(OrigInst); | ||
Value *VAListTag = OrigInst->getArgOperand(0); | ||
Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr( | ||
IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), MS.PtrTy); | ||
Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr); | ||
Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); | ||
Value *RegSaveAreaPtrPtr = | ||
IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), | ||
PointerType::get(RegSaveAreaPtrTy, 0)); | ||
Value *RegSaveAreaPtr = | ||
IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr); | ||
Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr; | ||
const Align Alignment = Align(8); | ||
const DataLayout &DL = F.getDataLayout(); | ||
unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy); | ||
const Align Alignment = Align(IntptrSize); | ||
std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) = | ||
MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), | ||
Alignment, /*isStore*/ true); | ||
|
@@ -6082,8 +6225,10 @@ struct VarArgGenericHelper : public VarArgHelperBase { | |
} | ||
}; | ||
|
||
// Loongarch64 is not a MIPS, but the current vargs calling convention matches | ||
// the MIPS. | ||
// ARM32, Loongarch64, MIPS and RISCV share the same calling conventions | ||
// regarding VAArgs. | ||
using VarArgARM32Helper = VarArgGenericHelper; | ||
using VarArgRISCVHelper = VarArgGenericHelper; | ||
using VarArgMIPSHelper = VarArgGenericHelper; | ||
using VarArgLoongArch64Helper = VarArgGenericHelper; | ||
|
||
|
@@ -6108,18 +6253,39 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, | |
// VarArg handling is only implemented on AMD64. False positives are possible | ||
// on other platforms. | ||
Triple TargetTriple(Func.getParent()->getTargetTriple()); | ||
|
||
if (TargetTriple.getArch() == Triple::x86) | ||
return new VarArgI386Helper(Func, Msan, Visitor); | ||
|
||
if (TargetTriple.getArch() == Triple::x86_64) | ||
return new VarArgAMD64Helper(Func, Msan, Visitor); | ||
|
||
if (TargetTriple.isARM()) | ||
return new VarArgARM32Helper(Func, Msan, Visitor, /*VAListTagSize=*/4); | ||
|
||
if (TargetTriple.isAArch64()) | ||
return new VarArgAArch64Helper(Func, Msan, Visitor); | ||
|
||
if (TargetTriple.isSystemZ()) | ||
return new VarArgSystemZHelper(Func, Msan, Visitor); | ||
|
||
// On PowerPC32 VAListTag is a struct | ||
// {char, char, i16 padding, char *, char *} | ||
if (TargetTriple.isPPC32()) | ||
return new VarArgPowerPCHelper(Func, Msan, Visitor, /*VAListTagSize=*/12); | ||
|
||
if (TargetTriple.isPPC64()) | ||
return new VarArgPowerPCHelper(Func, Msan, Visitor, /*VAListTagSize=*/8); | ||
|
||
if (TargetTriple.isRISCV32()) | ||
return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/4); | ||
|
||
if (TargetTriple.isRISCV64()) | ||
return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/8); | ||
|
||
if (TargetTriple.isMIPS32()) | ||
return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/4); | ||
|
||
if (TargetTriple.isMIPS64()) | ||
return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/8); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s | ||
; RUN: opt < %s -S -passes=msan -msan-origin-base=0x40000000 -msan-and-mask=0x80000000 2>&1 | FileCheck %s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove those and add proper consts into msan pass? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can, but this will require some research on where to put shadow and origin. Currently, I cannot say what their proper addresses will be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then I afraid if someone decide to fix them will forget to update tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do, thanks |
||
|
||
target datalayout = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128" | ||
target triple = "mips64--linux" | ||
target triple = "arm--linux" | ||
|
||
define i32 @foo(i32 %guard, ...) { | ||
vitalybuka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
; CHECK-LABEL: define i32 @foo( | ||
|
@@ -16,20 +16,20 @@ define i32 @foo(i32 %guard, ...) { | |
; CHECK-NEXT: call void @llvm.donothing() | ||
; CHECK-NEXT: [[VL:%.*]] = alloca ptr, align 8 | ||
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[VL]] to i64 | ||
; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], 549755813888 | ||
; CHECK-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], -2147483649 | ||
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr | ||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP7]], i8 0, i64 8, i1 false) | ||
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[VL]]) | ||
; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[VL]] to i64 | ||
; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], 549755813888 | ||
; CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], -2147483649 | ||
; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr | ||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 8, i1 false) | ||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP10]], i8 0, i64 4, i1 false) | ||
; CHECK-NEXT: call void @llvm.va_start.p0(ptr [[VL]]) | ||
; CHECK-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[VL]] to i64 | ||
; CHECK-NEXT: [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to ptr | ||
; CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP12]], align 8 | ||
; CHECK-NEXT: [[TMP14:%.*]] = ptrtoint ptr [[TMP13]] to i64 | ||
; CHECK-NEXT: [[TMP15:%.*]] = xor i64 [[TMP14]], 549755813888 | ||
; CHECK-NEXT: [[TMP15:%.*]] = and i64 [[TMP14]], -2147483649 | ||
; CHECK-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr | ||
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP16]], ptr align 8 [[TMP3]], i64 [[TMP2]], i1 false) | ||
; CHECK-NEXT: call void @llvm.va_end.p0(ptr [[VL]]) | ||
|
Uh oh!
There was an error while loading. Please reload this page.