[CodeGen] skip lifetime end marker in isInTailCallPosition
authorRobert Lougher <rob.lougher@gmail.com>
Wed, 24 Oct 2018 17:03:19 +0000 (17:03 +0000)
committerRobert Lougher <rob.lougher@gmail.com>
Wed, 24 Oct 2018 17:03:19 +0000 (17:03 +0000)
A lifetime end intrinsic between a tail call and the return should not
prevent the call from being tail call optimized.

Differential Revision: https://reviews.llvm.org/D53519

llvm-svn: 345163

llvm/lib/CodeGen/Analysis.cpp
llvm/test/CodeGen/X86/tailcall-lifetime-end.ll [new file with mode: 0644]

index aae04a5..27dce7f 100644 (file)
@@ -496,6 +496,10 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS, const TargetMachine &TM) {
       // Debug info intrinsics do not get in the way of tail call optimization.
       if (isa<DbgInfoIntrinsic>(BBI))
         continue;
+      // A lifetime end intrinsic should not stop tail call optimization.
+      if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI))
+        if (II->getIntrinsicID() == Intrinsic::lifetime_end)
+          continue;
       if (BBI->mayHaveSideEffects() || BBI->mayReadFromMemory() ||
           !isSafeToSpeculativelyExecute(&*BBI))
         return false;
diff --git a/llvm/test/CodeGen/X86/tailcall-lifetime-end.ll b/llvm/test/CodeGen/X86/tailcall-lifetime-end.ll
new file mode 100644 (file)
index 0000000..3aedd00
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s
+
+; A lifetime end intrinsic should not prevent a call from being tail call
+; optimized.
+
+define void @foobar() {
+; CHECK-LABEL: foobar
+; CHECK: pushq %rax
+; CHECK: leaq  4(%rsp), %rdi
+; CHECK: callq foo
+; CHECK: popq  %rax
+; CHECK: jmp   bar
+entry:
+  %i = alloca i32
+  %0 = bitcast i32* %i to i8*
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0)
+  call void @foo(i32* nonnull %i)
+  tail call void @bar()
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0)
+  ret void
+}
+
+declare void @foo(i32* nocapture %p)
+declare void @bar()
+
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)