| ; RUN: opt < %s -inline -S | FileCheck %s |
| ; RUN: opt < %s -passes='cgscc(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 |
| } |
| |
| ; Don't insert lifetime end markers here, the lifetime is trivially over due |
| ; the return. |
| ; CHECK: define void @test_byval_a( |
| ; CHECK: musttail call void @test_byval_c( |
| ; CHECK-NEXT: ret void |
| |
| declare void @test_byval_c(i32* byval %p) |
| define internal void @test_byval_b(i32* byval %p) { |
| musttail call void @test_byval_c(i32* byval %p) |
| ret void |
| } |
| define void @test_byval_a(i32* byval %p) { |
| musttail call void @test_byval_b(i32* byval %p) |
| ret void |
| } |
| |
| ; Don't insert a stack restore, we're about to return. |
| ; CHECK: define void @test_dynalloca_a( |
| ; CHECK: call i8* @llvm.stacksave( |
| ; CHECK: alloca i8, i32 %n |
| ; CHECK: musttail call void @test_dynalloca_c( |
| ; CHECK-NEXT: ret void |
| |
| declare void @escape(i8* %buf) |
| declare void @test_dynalloca_c(i32* byval %p, i32 %n) |
| define internal void @test_dynalloca_b(i32* byval %p, i32 %n) alwaysinline { |
| %buf = alloca i8, i32 %n ; dynamic alloca |
| call void @escape(i8* %buf) ; escape it |
| musttail call void @test_dynalloca_c(i32* byval %p, i32 %n) |
| ret void |
| } |
| define void @test_dynalloca_a(i32* byval %p, i32 %n) { |
| musttail call void @test_dynalloca_b(i32* byval %p, i32 %n) |
| 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 |
| } |
| |
| declare i32 @donttailcall() |
| |
| define i32 @notail() { |
| %rv = notail call i32 @donttailcall() |
| ret i32 %rv |
| } |
| |
| ; CHECK: @test_notail |
| ; CHECK: notail call i32 @donttailcall |
| ; CHECK: ret |
| define i32 @test_notail() { |
| %rv = tail call i32 @notail() |
| ret i32 %rv |
| } |
| |
| ; PR31014: Inlining a musttail call through a notail call site should remove |
| ; any tail marking, otherwise we break verifier invariants. |
| |
| declare void @do_ret(i32) |
| |
| define void @test_notail_inline_musttail(i32 %a) { |
| notail call void @inline_musttail(i32 %a) |
| musttail call void @do_ret(i32 %a) |
| ret void |
| } |
| |
| define internal void @inline_musttail(i32 %a) { |
| musttail call void @do_ret(i32 %a) |
| ret void |
| } |
| |
| ; CHECK-LABEL: define void @test_notail_inline_musttail(i32 %a) |
| ; CHECK: {{^ *}}call void @do_ret(i32 %a) |
| ; CHECK: musttail call void @do_ret(i32 %a) |
| ; CHECK: ret void |