diff options
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/ArgumentPromotion/inalloca.ll | 4 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll | 2 | ||||
-rw-r--r-- | llvm/test/Verifier/inalloca3.ll | 13 |
4 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 43534385f38..1a8fb0a1f47 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1494,6 +1494,16 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); + // Conservatively check the inalloca argument. + // We have a bug if we can find that there is an underlying alloca without + // inalloca. + if (CS.hasInAllocaArgument()) { + Value *InAllocaArg = CS.getArgument(FTy->getNumParams() - 1); + if (auto AI = dyn_cast<AllocaInst>(InAllocaArg->stripInBoundsOffsets())) + Assert2(AI->isUsedWithInAlloca(), + "inalloca argument for call has mismatched alloca", AI, I); + } + if (FTy->isVarArg()) { // FIXME? is 'nest' even legal here? bool SawNest = false; diff --git a/llvm/test/Transforms/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/ArgumentPromotion/inalloca.ll index 513a968255e..089a78f6b31 100644 --- a/llvm/test/Transforms/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/ArgumentPromotion/inalloca.ll @@ -20,7 +20,7 @@ entry: define i32 @main() { entry: - %S = alloca %struct.ss + %S = alloca inalloca %struct.ss %f0 = getelementptr %struct.ss* %S, i32 0, i32 0 %f1 = getelementptr %struct.ss* %S, i32 0, i32 1 store i32 1, i32* %f0, align 4 @@ -42,7 +42,7 @@ entry: define i32 @test() { entry: - %S = alloca %struct.ss + %S = alloca inalloca %struct.ss %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) ; CHECK: call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) ret i32 0 diff --git a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll index baf97e0ce9a..90289e2468f 100644 --- a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll +++ b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll @@ -8,7 +8,7 @@ declare void @takes_i32_inalloca(i32* inalloca) define void @f() { ; CHECK-LABEL: define void @f() - %args = alloca i32 + %args = alloca inalloca i32 call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca %args) ; CHECK: call void bitcast ret void diff --git a/llvm/test/Verifier/inalloca3.ll b/llvm/test/Verifier/inalloca3.ll new file mode 100644 index 00000000000..c09ce100849 --- /dev/null +++ b/llvm/test/Verifier/inalloca3.ll @@ -0,0 +1,13 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + + +declare void @doit(i64* inalloca %a) + +define void @a() { +entry: + %a = alloca [2 x i32] + %b = bitcast [2 x i32]* %a to i64* + call void @doit(i64* inalloca %b) +; CHECK: inalloca argument for call has mismatched alloca + ret void +} |