From bf741d2bddfa75babd032db3039064746a8f86ba Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 30 Apr 2014 17:22:00 +0000 Subject: [PATCH] IR: Conservatively verify inalloca arguments Summary: Try to spot obvious mismatches with inalloca use. Reviewers: rnk Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D3572 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207676 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Verifier.cpp | 10 ++++++++++ test/Transforms/ArgumentPromotion/inalloca.ll | 4 ++-- .../InstCombine/call-cast-target-inalloca.ll | 2 +- test/Verifier/inalloca3.ll | 13 +++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test/Verifier/inalloca3.ll diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 43534385f38..1a8fb0a1f47 100644 --- a/lib/IR/Verifier.cpp +++ b/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(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/test/Transforms/ArgumentPromotion/inalloca.ll b/test/Transforms/ArgumentPromotion/inalloca.ll index 513a968255e..089a78f6b31 100644 --- a/test/Transforms/ArgumentPromotion/inalloca.ll +++ b/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/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/test/Transforms/InstCombine/call-cast-target-inalloca.ll index baf97e0ce9a..90289e2468f 100644 --- a/test/Transforms/InstCombine/call-cast-target-inalloca.ll +++ b/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/test/Verifier/inalloca3.ll b/test/Verifier/inalloca3.ll new file mode 100644 index 00000000000..c09ce100849 --- /dev/null +++ b/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 +} -- 2.34.1