[CodeGen] skip lifetime end marker in isInTailCallPosition

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
This commit is contained in:
Robert Lougher 2018-10-24 17:03:19 +00:00
parent e004590e92
commit a374f5927e
2 changed files with 31 additions and 0 deletions

View 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;

View File

@ -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)