Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -S | FileCheck %s
      2 
      3 ; Test that the inliner correctly handles inlining into invoke sites
      4 ; by appending selectors and forwarding _Unwind_Resume directly to the
      5 ; enclosing landing pad.
      6 
      7 ;; Test 0 - basic functionality.
      8 
      9 %struct.A = type { i8 }
     10 
     11 @_ZTIi = external constant i8*
     12 
     13 declare void @_ZN1AC1Ev(%struct.A*)
     14 
     15 declare void @_ZN1AD1Ev(%struct.A*)
     16 
     17 declare void @use(i32) nounwind
     18 
     19 declare void @opaque()
     20 
     21 declare i8* @llvm.eh.exception() nounwind readonly
     22 
     23 declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
     24 
     25 declare i32 @llvm.eh.typeid.for(i8*) nounwind
     26 
     27 declare void @llvm.eh.resume(i8*, i32)
     28 
     29 declare i32 @__gxx_personality_v0(...)
     30 
     31 declare i8* @__cxa_begin_catch(i8*)
     32 
     33 declare void @__cxa_end_catch()
     34 
     35 declare void @_ZSt9terminatev()
     36 
     37 define internal void @test0_in() alwaysinline uwtable ssp {
     38 entry:
     39   %a = alloca %struct.A, align 1
     40   %b = alloca %struct.A, align 1
     41   call void @_ZN1AC1Ev(%struct.A* %a)
     42   invoke void @_ZN1AC1Ev(%struct.A* %b)
     43           to label %invoke.cont unwind label %lpad
     44 
     45 invoke.cont:
     46   invoke void @_ZN1AD1Ev(%struct.A* %b)
     47           to label %invoke.cont1 unwind label %lpad
     48 
     49 invoke.cont1:
     50   call void @_ZN1AD1Ev(%struct.A* %a)
     51   ret void
     52 
     53 lpad:
     54   %exn = call i8* @llvm.eh.exception() nounwind
     55   %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0) nounwind
     56   invoke void @_ZN1AD1Ev(%struct.A* %a)
     57           to label %invoke.cont2 unwind label %terminate.lpad
     58 
     59 invoke.cont2:
     60   call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
     61   unreachable
     62 
     63 terminate.lpad:
     64   %exn3 = call i8* @llvm.eh.exception() nounwind
     65   %eh.selector4 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn3, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) nounwind
     66   call void @_ZSt9terminatev() noreturn nounwind
     67   unreachable
     68 }
     69 
     70 define void @test0_out() uwtable ssp {
     71 entry:
     72   invoke void @test0_in()
     73           to label %ret unwind label %lpad
     74 
     75 ret:
     76   ret void
     77 
     78 lpad:                                             ; preds = %entry
     79   %exn = call i8* @llvm.eh.exception() nounwind
     80   %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
     81   %0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
     82   %1 = icmp eq i32 %eh.selector, %0
     83   br i1 %1, label %catch, label %eh.resume
     84 
     85 catch:
     86   %ignored = call i8* @__cxa_begin_catch(i8* %exn) nounwind
     87   call void @__cxa_end_catch() nounwind
     88   br label %ret
     89 
     90 eh.resume:
     91   call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
     92   unreachable
     93 }
     94 
     95 ; CHECK:    define void @test0_out()
     96 ; CHECK:      [[A:%.*]] = alloca %struct.A,
     97 ; CHECK:      [[B:%.*]] = alloca %struct.A,
     98 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[A]])
     99 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[B]])
    100 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[B]])
    101 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[A]])
    102 ; CHECK:      call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
    103 ; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
    104 ; CHECK-NEXT:   to label %[[LBL:[^\s]+]] unwind
    105 ; CHECK: [[LBL]]:
    106 ; CHECK-NEXT: br label %[[LPAD:[^\s]+]]
    107 ; CHECK:      ret void
    108 ; CHECK:      call i8* @llvm.eh.exception()
    109 ; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
    110 ; CHECK-NEXT: br label %[[LPAD]]
    111 ; CHECK: [[LPAD]]:
    112 ; CHECK-NEXT: phi i8* [
    113 ; CHECK-NEXT: phi i32 [
    114 ; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
    115 
    116 
    117 ;; Test 1 - Correctly handle phis in outer landing pads.
    118 
    119 define void @test1_out() uwtable ssp {
    120 entry:
    121   invoke void @test0_in()
    122           to label %cont unwind label %lpad
    123 
    124 cont:
    125   invoke void @test0_in()
    126           to label %ret unwind label %lpad
    127 
    128 ret:
    129   ret void
    130 
    131 lpad:
    132   %x = phi i32 [ 0, %entry ], [ 1, %cont ]
    133   %y = phi i32 [ 1, %entry ], [ 4, %cont ]
    134   %exn = call i8* @llvm.eh.exception() nounwind
    135   %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
    136   %0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
    137   %1 = icmp eq i32 %eh.selector, %0
    138   br i1 %1, label %catch, label %eh.resume
    139 
    140 catch:
    141   %ignored = call i8* @__cxa_begin_catch(i8* %exn) nounwind
    142   call void @use(i32 %x)
    143   call void @use(i32 %y)
    144   call void @__cxa_end_catch() nounwind
    145   br label %ret
    146 
    147 eh.resume:
    148   call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
    149   unreachable
    150 }
    151 
    152 ; CHECK:    define void @test1_out()
    153 ; CHECK:      [[A2:%.*]] = alloca %struct.A,
    154 ; CHECK:      [[B2:%.*]] = alloca %struct.A,
    155 ; CHECK:      [[A1:%.*]] = alloca %struct.A,
    156 ; CHECK:      [[B1:%.*]] = alloca %struct.A,
    157 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[A1]])
    158 ; CHECK-NEXT:   unwind label %[[LPAD:[^\s]+]]
    159 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[B1]])
    160 ; CHECK-NEXT:   unwind label %[[LPAD1:[^\s]+]]
    161 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[B1]])
    162 ; CHECK-NEXT:   unwind label %[[LPAD1]]
    163 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
    164 ; CHECK-NEXT:   unwind label %[[LPAD]]
    165 
    166 ; Inner landing pad from first inlining.
    167 ; CHECK:    [[LPAD1]]:
    168 ; CHECK-NEXT: [[EXN1:%.*]] = call i8* @llvm.eh.exception()
    169 ; CHECK-NEXT: [[SEL1:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN1]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
    170 ; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
    171 ; CHECK-NEXT:   to label %[[RESUME1:[^\s]+]] unwind
    172 ; CHECK: [[RESUME1]]:
    173 ; CHECK-NEXT: br label %[[LPAD_JOIN1:[^\s]+]]
    174 
    175 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[A2]])
    176 ; CHECK-NEXT:   unwind label %[[LPAD]]
    177 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[B2]])
    178 ; CHECK-NEXT:   unwind label %[[LPAD2:[^\s]+]]
    179 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[B2]])
    180 ; CHECK-NEXT:   unwind label %[[LPAD2]]
    181 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
    182 ; CHECK-NEXT:   unwind label %[[LPAD]]
    183 
    184 ; Inner landing pad from second inlining.
    185 ; CHECK:    [[LPAD2]]:
    186 ; CHECK-NEXT: [[EXN2:%.*]] = call i8* @llvm.eh.exception()
    187 ; CHECK-NEXT: [[SEL2:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN2]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
    188 ; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
    189 ; CHECK-NEXT:   to label %[[RESUME2:[^\s]+]] unwind
    190 ; CHECK: [[RESUME2]]:
    191 ; CHECK-NEXT: br label %[[LPAD_JOIN2:[^\s]+]]
    192 
    193 ; CHECK:      ret void
    194 
    195 ; CHECK:    [[LPAD]]:
    196 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, %entry ], [ 0, {{%.*}} ], [ 1, %cont ], [ 1, {{%.*}} ]
    197 ; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 1, %entry ], [ 1, {{%.*}} ], [ 4, %cont ], [ 4, {{%.*}} ]
    198 ; CHECK-NEXT: [[EXN:%.*]] = call i8* @llvm.eh.exception()
    199 ; CHECK-NEXT: [[SEL:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
    200 ; CHECK-NEXT: br label %[[LPAD_JOIN2]]
    201 
    202 ; CHECK: [[LPAD_JOIN2]]:
    203 ; CHECK-NEXT: [[XJ2:%.*]] = phi i32 [ [[X]], %[[LPAD]] ], [ 1, %[[RESUME2]] ]
    204 ; CHECK-NEXT: [[YJ2:%.*]] = phi i32 [ [[Y]], %[[LPAD]] ], [ 4, %[[RESUME2]] ]
    205 ; CHECK-NEXT: [[EXNJ2:%.*]] = phi i8* [ [[EXN]], %[[LPAD]] ], [ [[EXN2]], %[[RESUME2]] ]
    206 ; CHECK-NEXT: [[SELJ2:%.*]] = phi i32 [ [[SEL]], %[[LPAD]] ], [ [[SEL2]], %[[RESUME2]] ]
    207 ; CHECK-NEXT: br label %[[LPAD_JOIN1]]
    208 
    209 ; CHECK: [[LPAD_JOIN1]]:
    210 ; CHECK-NEXT: [[XJ1:%.*]] = phi i32 [ [[XJ2]], %[[LPAD_JOIN2]] ], [ 0, %[[RESUME1]] ]
    211 ; CHECK-NEXT: [[YJ1:%.*]] = phi i32 [ [[YJ2]], %[[LPAD_JOIN2]] ], [ 1, %[[RESUME1]] ]
    212 ; CHECK-NEXT: [[EXNJ1:%.*]] = phi i8* [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[EXN1]], %[[RESUME1]] ]
    213 ; CHECK-NEXT: [[SELJ1:%.*]] = phi i32 [ [[SELJ2]], %[[LPAD_JOIN2]] ], [ [[SEL1]], %[[RESUME1]] ]
    214 ; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for(
    215 ; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]
    216 
    217 ; CHECK:      call void @use(i32 [[XJ1]])
    218 ; CHECK:      call void @use(i32 [[YJ1]])
    219 
    220 ; CHECK:      call void @llvm.eh.resume(i8* [[EXNJ1]], i32 [[SELJ1]])
    221 
    222 
    223 ;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
    224 define void @test2_out() uwtable ssp {
    225 entry:
    226   invoke void @test0_in()
    227           to label %ret unwind label %lpad
    228 
    229 ret:
    230   ret void
    231 
    232 lpad:
    233   call void @_ZSt9terminatev()
    234   unreachable
    235 }
    236 
    237 ; CHECK: define void @test2_out()
    238 ; CHECK:      [[A:%.*]] = alloca %struct.A,
    239 ; CHECK:      [[B:%.*]] = alloca %struct.A,
    240 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[A]])
    241 ; CHECK-NEXT:   unwind label %[[LPAD:[^\s]+]]
    242 ; CHECK:      invoke void @_ZN1AC1Ev(%struct.A* [[B]])
    243 ; CHECK-NEXT:   unwind label %[[LPAD2:[^\s]+]]
    244 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[B]])
    245 ; CHECK-NEXT:   unwind label %[[LPAD2]]
    246 ; CHECK:      invoke void @_ZN1AD1Ev(%struct.A* [[A]])
    247 ; CHECK-NEXT:   unwind label %[[LPAD]]
    248 
    249 
    250 ;; Test 3 - Deal correctly with split unwind edges.
    251 define void @test3_out() uwtable ssp {
    252 entry:
    253   invoke void @test0_in()
    254           to label %ret unwind label %lpad
    255 
    256 ret:
    257   ret void
    258 
    259 lpad:
    260   br label %lpad.cont
    261 
    262 lpad.cont:
    263   %exn = call i8* @llvm.eh.exception() nounwind
    264   %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
    265   call void @_ZSt9terminatev()
    266   unreachable
    267 }
    268 
    269 ; CHECK: define void @test3_out()
    270 ; CHECK:      call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
    271 ; CHECK-NEXT: invoke void @_ZN1AD1Ev(
    272 ; CHECK-NEXT:   to label %[[L:[^\s]+]] unwind
    273 ; CHECK:    [[L]]:
    274 ; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
    275 ; CHECK:    [[JOIN]]:
    276 ; CHECK-NEXT: phi
    277 ; CHECK-NEXT: phi
    278 ; CHECK-NEXT: br label %lpad.cont
    279 ; CHECK:    lpad.cont:
    280 ; CHECK-NEXT: call void @_ZSt9terminatev()
    281 
    282 
    283 ;; Test 4 - Split unwind edges with a dominance problem
    284 define void @test4_out() uwtable ssp {
    285 entry:
    286   invoke void @test0_in()
    287           to label %cont unwind label %lpad.crit
    288 
    289 cont:
    290   invoke void @opaque()
    291           to label %ret unwind label %lpad
    292 
    293 ret:
    294   ret void
    295 
    296 lpad.crit:
    297   call void @opaque() nounwind
    298   br label %lpad
    299 
    300 lpad:
    301   %phi = phi i32 [ 0, %lpad.crit ], [ 1, %cont ]
    302   %exn = call i8* @llvm.eh.exception() nounwind
    303   %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
    304   call void @use(i32 %phi)
    305   call void @_ZSt9terminatev()
    306   unreachable
    307 }
    308 
    309 ; CHECK: define void @test4_out()
    310 ; CHECK:      call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
    311 ; CHECK-NEXT: invoke void @_ZN1AD1Ev(
    312 ; CHECK-NEXT:   to label %[[L:[^\s]+]] unwind
    313 ; CHECK:    [[L]]:
    314 ; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
    315 ; CHECK:      invoke void @opaque()
    316 ; CHECK-NEXT:                  unwind label %lpad
    317 ; CHECK:    lpad.crit:
    318 ; CHECK-NEXT: call i8* @llvm.eh.exception()
    319 ; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %4, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
    320 ; CHECK-NEXT: br label %[[JOIN]]
    321 ; CHECK:    [[JOIN]]:
    322 ; CHECK-NEXT: phi i8*
    323 ; CHECK-NEXT: phi i32
    324 ; CHECK-NEXT: call void @opaque() nounwind
    325 ; CHECK-NEXT: br label %[[FIX:[^\s]+]]
    326 ; CHECK:    lpad:
    327 ; CHECK-NEXT: [[T0:%.*]] = phi i32 [ 1, %cont ]
    328 ; CHECK-NEXT: call i8* @llvm.eh.exception() nounwind
    329 ; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
    330 ; CHECK-NEXT: br label %[[FIX]]
    331 ; CHECK:    [[FIX]]:
    332 ; CHECK-NEXT: [[T1:%.*]] = phi i32 [ [[T0]], %lpad ], [ 0, %[[JOIN]] ]
    333 ; CHECK-NEXT: phi i8*
    334 ; CHECK-NEXT: phi i32
    335 ; CHECK-NEXT: call void @use(i32 [[T1]])
    336 ; CHECK-NEXT: call void @_ZSt9terminatev()
    337