llvm-6502/test/Transforms/Inline/inline-tail.ll
Reid Kleckner cf7cfd8208 Revert "Don't insert lifetime.end markers between a musttail call and ret"
This reverts commit r208912.

It was committed accidentally without review.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208914 91177308-0d34-0410-b5e6-96231b3b80d8
2014-05-15 20:41:05 +00:00

147 lines
4.2 KiB
LLVM

; RUN: opt < %s -inline -S | FileCheck %s
; We have to apply the less restrictive TailCallKind of the call site being
; inlined and any call sites cloned into the caller.
; No tail marker after inlining, since test_capture_c captures an alloca.
; CHECK: define void @test_capture_a(
; CHECK-NOT: tail
; CHECK: call void @test_capture_c(
declare void @test_capture_c(i32*)
define internal void @test_capture_b(i32* %P) {
tail call void @test_capture_c(i32* %P)
ret void
}
define void @test_capture_a() {
%A = alloca i32 ; captured by test_capture_b
call void @test_capture_b(i32* %A)
ret void
}
; No musttail marker after inlining, since the prototypes don't match.
; CHECK: define void @test_proto_mismatch_a(
; CHECK-NOT: musttail
; CHECK: call void @test_proto_mismatch_c(
declare void @test_proto_mismatch_c(i32*)
define internal void @test_proto_mismatch_b(i32* %p) {
musttail call void @test_proto_mismatch_c(i32* %p)
ret void
}
define void @test_proto_mismatch_a() {
call void @test_proto_mismatch_b(i32* null)
ret void
}
; After inlining through a musttail call site, we need to keep musttail markers
; to prevent unbounded stack growth.
; CHECK: define void @test_musttail_basic_a(
; CHECK: musttail call void @test_musttail_basic_c(
declare void @test_musttail_basic_c(i32* %p)
define internal void @test_musttail_basic_b(i32* %p) {
musttail call void @test_musttail_basic_c(i32* %p)
ret void
}
define void @test_musttail_basic_a(i32* %p) {
musttail call void @test_musttail_basic_b(i32* %p)
ret void
}
; We can't merge the returns.
; CHECK: define void @test_multiret_a(
; CHECK: musttail call void @test_multiret_c(
; CHECK-NEXT: ret void
; CHECK: musttail call void @test_multiret_d(
; CHECK-NEXT: ret void
declare void @test_multiret_c(i1 zeroext %b)
declare void @test_multiret_d(i1 zeroext %b)
define internal void @test_multiret_b(i1 zeroext %b) {
br i1 %b, label %c, label %d
c:
musttail call void @test_multiret_c(i1 zeroext %b)
ret void
d:
musttail call void @test_multiret_d(i1 zeroext %b)
ret void
}
define void @test_multiret_a(i1 zeroext %b) {
musttail call void @test_multiret_b(i1 zeroext %b)
ret void
}
; We have to avoid bitcast chains.
; CHECK: define i32* @test_retptr_a(
; CHECK: musttail call i8* @test_retptr_c(
; CHECK-NEXT: bitcast i8* {{.*}} to i32*
; CHECK-NEXT: ret i32*
declare i8* @test_retptr_c()
define internal i16* @test_retptr_b() {
%rv = musttail call i8* @test_retptr_c()
%v = bitcast i8* %rv to i16*
ret i16* %v
}
define i32* @test_retptr_a() {
%rv = musttail call i16* @test_retptr_b()
%v = bitcast i16* %rv to i32*
ret i32* %v
}
; Combine the last two cases: multiple returns with pointer bitcasts.
; CHECK: define i32* @test_multiptrret_a(
; CHECK: musttail call i8* @test_multiptrret_c(
; CHECK-NEXT: bitcast i8* {{.*}} to i32*
; CHECK-NEXT: ret i32*
; CHECK: musttail call i8* @test_multiptrret_d(
; CHECK-NEXT: bitcast i8* {{.*}} to i32*
; CHECK-NEXT: ret i32*
declare i8* @test_multiptrret_c(i1 zeroext %b)
declare i8* @test_multiptrret_d(i1 zeroext %b)
define internal i16* @test_multiptrret_b(i1 zeroext %b) {
br i1 %b, label %c, label %d
c:
%c_rv = musttail call i8* @test_multiptrret_c(i1 zeroext %b)
%c_v = bitcast i8* %c_rv to i16*
ret i16* %c_v
d:
%d_rv = musttail call i8* @test_multiptrret_d(i1 zeroext %b)
%d_v = bitcast i8* %d_rv to i16*
ret i16* %d_v
}
define i32* @test_multiptrret_a(i1 zeroext %b) {
%rv = musttail call i16* @test_multiptrret_b(i1 zeroext %b)
%v = bitcast i16* %rv to i32*
ret i32* %v
}
; Inline a musttail call site which contains a normal return and a musttail call.
; CHECK: define i32 @test_mixedret_a(
; CHECK: br i1 %b
; CHECK: musttail call i32 @test_mixedret_c(
; CHECK-NEXT: ret i32
; CHECK: call i32 @test_mixedret_d(i1 zeroext %b)
; CHECK: add i32 1,
; CHECK-NOT: br
; CHECK: ret i32
declare i32 @test_mixedret_c(i1 zeroext %b)
declare i32 @test_mixedret_d(i1 zeroext %b)
define internal i32 @test_mixedret_b(i1 zeroext %b) {
br i1 %b, label %c, label %d
c:
%c_rv = musttail call i32 @test_mixedret_c(i1 zeroext %b)
ret i32 %c_rv
d:
%d_rv = call i32 @test_mixedret_d(i1 zeroext %b)
%d_rv1 = add i32 1, %d_rv
ret i32 %d_rv1
}
define i32 @test_mixedret_a(i1 zeroext %b) {
%rv = musttail call i32 @test_mixedret_b(i1 zeroext %b)
ret i32 %rv
}