IR: Conservatively verify inalloca arguments
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 30 Apr 2014 17:22:00 +0000 (17:22 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 30 Apr 2014 17:22:00 +0000 (17:22 +0000)
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
test/Transforms/ArgumentPromotion/inalloca.ll
test/Transforms/InstCombine/call-cast-target-inalloca.ll
test/Verifier/inalloca3.ll [new file with mode: 0644]

index 43534385f385f2a04d8ef880553a93e038ba3fb0..1a8fb0a1f4715c608fcf050b46f3ce30226e731f 100644 (file)
@@ -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;
index 513a968255e736fac4690adcb5d8d7703132b13b..089a78f6b319569a8fa5d75bf1a4af9db14e1b21 100644 (file)
@@ -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
index baf97e0ce9a12923cbd196efab42c49c554ef870..90289e2468f85b161b012713cdbfbc40893232ca 100644 (file)
@@ -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 (file)
index 0000000..c09ce10
--- /dev/null
@@ -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
+}