OSDN Git Service

Don't insert lifetime end markers on deoptimizing returns
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 1 Apr 2016 02:51:26 +0000 (02:51 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 1 Apr 2016 02:51:26 +0000 (02:51 +0000)
They're not necessary (since the lifetime of the alloca is trivially
over due to the return), and the way LLVM inserts the lifetime.end
markers breaks the IR (we get a lifetime end marker between the
deoptimize call and the return).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265100 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/InlineFunction.cpp
test/Transforms/Inline/deoptimize-intrinsic.ll

index 50eff52..4217985 100644 (file)
@@ -1703,11 +1703,14 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
 
       builder.CreateLifetimeStart(AI, AllocaSize);
       for (ReturnInst *RI : Returns) {
-        // Don't insert llvm.lifetime.end calls between a musttail call and a
-        // return.  The return kills all local allocas.
+        // Don't insert llvm.lifetime.end calls between a musttail or deoptimize
+        // call and a return.  The return kills all local allocas.
         if (InlinedMustTailCalls &&
             RI->getParent()->getTerminatingMustTailCall())
           continue;
+        if (InlinedDeoptimizeCalls &&
+            RI->getParent()->getTerminatingDeoptimizeCall())
+          continue;
         IRBuilder<>(RI).CreateLifetimeEnd(AI, AllocaSize);
       }
     }
index 84e54a0..d9b8898 100644 (file)
@@ -88,3 +88,19 @@ normal:
   store i8 %v, i8* %ptr
   ret i32 42
 }
+
+define i8 @callee_with_alloca() alwaysinline {
+  %t = alloca i8
+  %v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i8* %t) ]
+  ret i8 %v0
+}
+
+define void @caller_with_lifetime() {
+; CHECK-LABLE: @caller_with_lifetime(
+; CHECK:  call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i8* %t.i) ]
+; CHECK-NEXT:  ret void
+
+entry:
+  call i8 @callee_with_alloca();
+  ret void
+}