Consider the following program:
------------- test.c --------------- extern void bar(void); __attribute__((__noinline__)) void foo(int *p) { *p = 10; } void foobar() { int i; foo(&i); bar(); } ------------------------------------
TailCallElim will correctly identify the call to bar as a tail call (as foo is nocapture). However, it will not be tail call optimized as it fails isInTailCallPosition() due to the lifetime end marker for the variable i:
define void @foobar() { entry: %i = alloca i32, align 4 %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 }
On x86_64 this generates:
foobar: pushq %rax leaq 4(%rsp), %rdi callq foo callq bar popq %rax retq
After this patch we get:
foobar: pushq %rax leaq 4(%rsp), %rdi callq foo popq %rax jmp bar # TAILCALL