Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -S | FileCheck %s
      2 ; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
      3 
      4 ; We have to apply the less restrictive TailCallKind of the call site being
      5 ; inlined and any call sites cloned into the caller.
      6 
      7 ; No tail marker after inlining, since test_capture_c captures an alloca.
      8 ; CHECK: define void @test_capture_a(
      9 ; CHECK-NOT: tail
     10 ; CHECK: call void @test_capture_c(
     11 
     12 declare void @test_capture_c(i32*)
     13 define internal void @test_capture_b(i32* %P) {
     14   tail call void @test_capture_c(i32* %P)
     15   ret void
     16 }
     17 define void @test_capture_a() {
     18   %A = alloca i32  		; captured by test_capture_b
     19   call void @test_capture_b(i32* %A)
     20   ret void
     21 }
     22 
     23 ; No musttail marker after inlining, since the prototypes don't match.
     24 ; CHECK: define void @test_proto_mismatch_a(
     25 ; CHECK-NOT: musttail
     26 ; CHECK: call void @test_proto_mismatch_c(
     27 
     28 declare void @test_proto_mismatch_c(i32*)
     29 define internal void @test_proto_mismatch_b(i32* %p) {
     30   musttail call void @test_proto_mismatch_c(i32* %p)
     31   ret void
     32 }
     33 define void @test_proto_mismatch_a() {
     34   call void @test_proto_mismatch_b(i32* null)
     35   ret void
     36 }
     37 
     38 ; After inlining through a musttail call site, we need to keep musttail markers
     39 ; to prevent unbounded stack growth.
     40 ; CHECK: define void @test_musttail_basic_a(
     41 ; CHECK: musttail call void @test_musttail_basic_c(
     42 
     43 declare void @test_musttail_basic_c(i32* %p)
     44 define internal void @test_musttail_basic_b(i32* %p) {
     45   musttail call void @test_musttail_basic_c(i32* %p)
     46   ret void
     47 }
     48 define void @test_musttail_basic_a(i32* %p) {
     49   musttail call void @test_musttail_basic_b(i32* %p)
     50   ret void
     51 }
     52 
     53 ; Don't insert lifetime end markers here, the lifetime is trivially over due
     54 ; the return.
     55 ; CHECK: define void @test_byval_a(
     56 ; CHECK: musttail call void @test_byval_c(
     57 ; CHECK-NEXT: ret void
     58 
     59 declare void @test_byval_c(i32* byval %p)
     60 define internal void @test_byval_b(i32* byval %p) {
     61   musttail call void @test_byval_c(i32* byval %p)
     62   ret void
     63 }
     64 define void @test_byval_a(i32* byval %p) {
     65   musttail call void @test_byval_b(i32* byval %p)
     66   ret void
     67 }
     68 
     69 ; Don't insert a stack restore, we're about to return.
     70 ; CHECK: define void @test_dynalloca_a(
     71 ; CHECK: call i8* @llvm.stacksave(
     72 ; CHECK: alloca i8, i32 %n
     73 ; CHECK: musttail call void @test_dynalloca_c(
     74 ; CHECK-NEXT: ret void
     75 
     76 declare void @escape(i8* %buf)
     77 declare void @test_dynalloca_c(i32* byval %p, i32 %n)
     78 define internal void @test_dynalloca_b(i32* byval %p, i32 %n) alwaysinline {
     79   %buf = alloca i8, i32 %n              ; dynamic alloca
     80   call void @escape(i8* %buf)           ; escape it
     81   musttail call void @test_dynalloca_c(i32* byval %p, i32 %n)
     82   ret void
     83 }
     84 define void @test_dynalloca_a(i32* byval %p, i32 %n) {
     85   musttail call void @test_dynalloca_b(i32* byval %p, i32 %n)
     86   ret void
     87 }
     88 
     89 ; We can't merge the returns.
     90 ; CHECK: define void @test_multiret_a(
     91 ; CHECK: musttail call void @test_multiret_c(
     92 ; CHECK-NEXT: ret void
     93 ; CHECK: musttail call void @test_multiret_d(
     94 ; CHECK-NEXT: ret void
     95 
     96 declare void @test_multiret_c(i1 zeroext %b)
     97 declare void @test_multiret_d(i1 zeroext %b)
     98 define internal void @test_multiret_b(i1 zeroext %b) {
     99   br i1 %b, label %c, label %d
    100 c:
    101   musttail call void @test_multiret_c(i1 zeroext %b)
    102   ret void
    103 d:
    104   musttail call void @test_multiret_d(i1 zeroext %b)
    105   ret void
    106 }
    107 define void @test_multiret_a(i1 zeroext %b) {
    108   musttail call void @test_multiret_b(i1 zeroext %b)
    109   ret void
    110 }
    111 
    112 ; We have to avoid bitcast chains.
    113 ; CHECK: define i32* @test_retptr_a(
    114 ; CHECK: musttail call i8* @test_retptr_c(
    115 ; CHECK-NEXT: bitcast i8* {{.*}} to i32*
    116 ; CHECK-NEXT: ret i32*
    117 
    118 declare i8* @test_retptr_c()
    119 define internal i16* @test_retptr_b() {
    120   %rv = musttail call i8* @test_retptr_c()
    121   %v = bitcast i8* %rv to i16*
    122   ret i16* %v
    123 }
    124 define i32* @test_retptr_a() {
    125   %rv = musttail call i16* @test_retptr_b()
    126   %v = bitcast i16* %rv to i32*
    127   ret i32* %v
    128 }
    129 
    130 ; Combine the last two cases: multiple returns with pointer bitcasts.
    131 ; CHECK: define i32* @test_multiptrret_a(
    132 ; CHECK: musttail call i8* @test_multiptrret_c(
    133 ; CHECK-NEXT: bitcast i8* {{.*}} to i32*
    134 ; CHECK-NEXT: ret i32*
    135 ; CHECK: musttail call i8* @test_multiptrret_d(
    136 ; CHECK-NEXT: bitcast i8* {{.*}} to i32*
    137 ; CHECK-NEXT: ret i32*
    138 
    139 declare i8* @test_multiptrret_c(i1 zeroext %b)
    140 declare i8* @test_multiptrret_d(i1 zeroext %b)
    141 define internal i16* @test_multiptrret_b(i1 zeroext %b) {
    142   br i1 %b, label %c, label %d
    143 c:
    144   %c_rv = musttail call i8* @test_multiptrret_c(i1 zeroext %b)
    145   %c_v = bitcast i8* %c_rv to i16*
    146   ret i16* %c_v
    147 d:
    148   %d_rv = musttail call i8* @test_multiptrret_d(i1 zeroext %b)
    149   %d_v = bitcast i8* %d_rv to i16*
    150   ret i16* %d_v
    151 }
    152 define i32* @test_multiptrret_a(i1 zeroext %b) {
    153   %rv = musttail call i16* @test_multiptrret_b(i1 zeroext %b)
    154   %v = bitcast i16* %rv to i32*
    155   ret i32* %v
    156 }
    157 
    158 ; Inline a musttail call site which contains a normal return and a musttail call.
    159 ; CHECK: define i32 @test_mixedret_a(
    160 ; CHECK: br i1 %b
    161 ; CHECK: musttail call i32 @test_mixedret_c(
    162 ; CHECK-NEXT: ret i32
    163 ; CHECK: call i32 @test_mixedret_d(i1 zeroext %b)
    164 ; CHECK: add i32 1,
    165 ; CHECK-NOT: br
    166 ; CHECK: ret i32
    167 
    168 declare i32 @test_mixedret_c(i1 zeroext %b)
    169 declare i32 @test_mixedret_d(i1 zeroext %b)
    170 define internal i32 @test_mixedret_b(i1 zeroext %b) {
    171   br i1 %b, label %c, label %d
    172 c:
    173   %c_rv = musttail call i32 @test_mixedret_c(i1 zeroext %b)
    174   ret i32 %c_rv
    175 d:
    176   %d_rv = call i32 @test_mixedret_d(i1 zeroext %b)
    177   %d_rv1 = add i32 1, %d_rv
    178   ret i32 %d_rv1
    179 }
    180 define i32 @test_mixedret_a(i1 zeroext %b) {
    181   %rv = musttail call i32 @test_mixedret_b(i1 zeroext %b)
    182   ret i32 %rv
    183 }
    184 
    185 declare i32 @donttailcall()
    186 
    187 define i32 @notail() {
    188   %rv = notail call i32 @donttailcall()
    189   ret i32 %rv
    190 }
    191 
    192 ; CHECK: @test_notail
    193 ; CHECK: notail call i32 @donttailcall
    194 ; CHECK: ret
    195 define i32 @test_notail() {
    196   %rv = tail call i32 @notail()
    197   ret i32 %rv
    198 }
    199 
    200 ; PR31014: Inlining a musttail call through a notail call site should remove
    201 ; any tail marking, otherwise we break verifier invariants.
    202 
    203 declare void @do_ret(i32)
    204 
    205 define void @test_notail_inline_musttail(i32 %a) {
    206   notail call void @inline_musttail(i32 %a)
    207   musttail call void @do_ret(i32 %a)
    208   ret void
    209 }
    210 
    211 define internal void @inline_musttail(i32 %a) {
    212   musttail call void @do_ret(i32 %a)
    213   ret void
    214 }
    215 
    216 ; CHECK-LABEL: define void @test_notail_inline_musttail(i32 %a)
    217 ; CHECK:   {{^ *}}call void @do_ret(i32 %a)
    218 ; CHECK:   musttail call void @do_ret(i32 %a)
    219 ; CHECK:   ret void
    220