Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 
      3 @T1 = external constant i32
      4 @T2 = external constant i32
      5 @T3 = external constant i32
      6 
      7 declare i32 @generic_personality(i32, i64, i8*, i8*)
      8 declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
      9 declare i32 @__objc_personality_v0(i32, i64, i8*, i8*)
     10 declare i32 @__C_specific_handler(...)
     11 
     12 declare void @bar()
     13 
     14 define void @foo_generic() personality i32 (i32, i64, i8*, i8*)* @generic_personality {
     15 ; CHECK-LABEL: @foo_generic(
     16   invoke void @bar()
     17     to label %cont.a unwind label %lpad.a
     18 cont.a:
     19   invoke void @bar()
     20     to label %cont.b unwind label %lpad.b
     21 cont.b:
     22   invoke void @bar()
     23     to label %cont.c unwind label %lpad.c
     24 cont.c:
     25   invoke void @bar()
     26     to label %cont.d unwind label %lpad.d
     27 cont.d:
     28   invoke void @bar()
     29     to label %cont.e unwind label %lpad.e
     30 cont.e:
     31   invoke void @bar()
     32     to label %cont.f unwind label %lpad.f
     33 cont.f:
     34   invoke void @bar()
     35     to label %cont.g unwind label %lpad.g
     36 cont.g:
     37   invoke void @bar()
     38     to label %cont.h unwind label %lpad.h
     39 cont.h:
     40   invoke void @bar()
     41     to label %cont.i unwind label %lpad.i
     42 cont.i:
     43   ret void
     44 
     45 lpad.a:
     46   %a = landingpad { i8*, i32 }
     47           catch i32* @T1
     48           catch i32* @T2
     49           catch i32* @T1
     50           catch i32* @T2
     51   unreachable
     52 ; CHECK: %a = landingpad
     53 ; CHECK-NEXT: @T1
     54 ; CHECK-NEXT: @T2
     55 ; CHECK-NEXT: unreachable
     56 
     57 lpad.b:
     58   %b = landingpad { i8*, i32 }
     59           filter [0 x i32*] zeroinitializer
     60           catch i32* @T1
     61   unreachable
     62 ; CHECK: %b = landingpad
     63 ; CHECK-NEXT: filter
     64 ; CHECK-NEXT: unreachable
     65 
     66 lpad.c:
     67   %c = landingpad { i8*, i32 }
     68           catch i32* @T1
     69           filter [1 x i32*] [i32* @T1]
     70           catch i32* @T2
     71   unreachable
     72 ; Caught types should not be removed from filters
     73 ; CHECK: %c = landingpad
     74 ; CHECK-NEXT: catch i32* @T1
     75 ; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
     76 ; CHECK-NEXT: catch i32* @T2 
     77 ; CHECK-NEXT: unreachable
     78 
     79 lpad.d:
     80   %d = landingpad { i8*, i32 }
     81           filter [3 x i32*] zeroinitializer
     82   unreachable
     83 ; CHECK: %d = landingpad
     84 ; CHECK-NEXT: filter [1 x i32*] zeroinitializer
     85 ; CHECK-NEXT: unreachable
     86 
     87 lpad.e:
     88   %e = landingpad { i8*, i32 }
     89           catch i32* @T1
     90           filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2]
     91   unreachable
     92 ; Caught types should not be removed from filters
     93 ; CHECK: %e = landingpad
     94 ; CHECK-NEXT: catch i32* @T1
     95 ; CHECK-NEXT: filter [2 x i32*] [i32* @T1, i32* @T2]
     96 ; CHECK-NEXT: unreachable
     97 
     98 lpad.f:
     99   %f = landingpad { i8*, i32 }
    100           filter [2 x i32*] [i32* @T2, i32* @T1]
    101           filter [1 x i32*] [i32* @T1]
    102   unreachable
    103 ; CHECK: %f = landingpad
    104 ; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
    105 ; CHECK-NEXT: unreachable
    106 
    107 lpad.g:
    108   %g = landingpad { i8*, i32 }
    109           filter [1 x i32*] [i32* @T1]
    110           catch i32* @T3
    111           filter [2 x i32*] [i32* @T2, i32* @T1]
    112   unreachable
    113 ; CHECK: %g = landingpad
    114 ; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
    115 ; CHECK-NEXT: catch i32* @T3
    116 ; CHECK-NEXT: unreachable
    117 
    118 lpad.h:
    119   %h = landingpad { i8*, i32 }
    120           filter [2 x i32*] [i32* @T1, i32* null]
    121           filter [1 x i32*] zeroinitializer
    122   unreachable
    123 ; CHECK: %h = landingpad
    124 ; CHECK-NEXT: filter [1 x i32*] zeroinitializer
    125 ; CHECK-NEXT: unreachable
    126 
    127 lpad.i:
    128   %i = landingpad { i8*, i32 }
    129           cleanup
    130           filter [0 x i32*] zeroinitializer
    131   unreachable
    132 ; CHECK: %i = landingpad
    133 ; CHECK-NEXT: filter
    134 ; CHECK-NEXT: unreachable
    135 }
    136 
    137 define void @foo_cxx() personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 {
    138 ; CHECK-LABEL: @foo_cxx(
    139   invoke void @bar()
    140     to label %cont.a unwind label %lpad.a
    141 cont.a:
    142   invoke void @bar()
    143     to label %cont.b unwind label %lpad.b
    144 cont.b:
    145   invoke void @bar()
    146     to label %cont.c unwind label %lpad.c
    147 cont.c:
    148   invoke void @bar()
    149     to label %cont.d unwind label %lpad.d
    150 cont.d:
    151   ret void
    152 
    153 lpad.a:
    154   %a = landingpad { i8*, i32 }
    155           catch i32* null
    156           catch i32* @T1
    157   unreachable
    158 ; CHECK: %a = landingpad
    159 ; CHECK-NEXT: null
    160 ; CHECK-NEXT: unreachable
    161 
    162 lpad.b:
    163   %b = landingpad { i8*, i32 }
    164           filter [1 x i32*] zeroinitializer
    165   unreachable
    166 ; CHECK: %b = landingpad
    167 ; CHECK-NEXT: cleanup
    168 ; CHECK-NEXT: unreachable
    169 
    170 lpad.c:
    171   %c = landingpad { i8*, i32 }
    172           filter [2 x i32*] [i32* @T1, i32* null]
    173   unreachable
    174 ; CHECK: %c = landingpad
    175 ; CHECK-NEXT: cleanup
    176 ; CHECK-NEXT: unreachable
    177 
    178 lpad.d:
    179   %d = landingpad { i8*, i32 }
    180           cleanup
    181           catch i32* null
    182   unreachable
    183 ; CHECK: %d = landingpad
    184 ; CHECK-NEXT: null
    185 ; CHECK-NEXT: unreachable
    186 }
    187 
    188 define void @foo_objc() personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0 {
    189 ; CHECK-LABEL: @foo_objc(
    190   invoke void @bar()
    191     to label %cont.a unwind label %lpad.a
    192 cont.a:
    193   invoke void @bar()
    194     to label %cont.b unwind label %lpad.b
    195 cont.b:
    196   invoke void @bar()
    197     to label %cont.c unwind label %lpad.c
    198 cont.c:
    199   invoke void @bar()
    200     to label %cont.d unwind label %lpad.d
    201 cont.d:
    202   ret void
    203 
    204 lpad.a:
    205   %a = landingpad { i8*, i32 }
    206           catch i32* null
    207           catch i32* @T1
    208   unreachable
    209 ; CHECK: %a = landingpad
    210 ; CHECK-NEXT: null
    211 ; CHECK-NEXT: unreachable
    212 
    213 lpad.b:
    214   %b = landingpad { i8*, i32 }
    215           filter [1 x i32*] zeroinitializer
    216   unreachable
    217 ; CHECK: %b = landingpad
    218 ; CHECK-NEXT: cleanup
    219 ; CHECK-NEXT: unreachable
    220 
    221 lpad.c:
    222   %c = landingpad { i8*, i32 }
    223           filter [2 x i32*] [i32* @T1, i32* null]
    224   unreachable
    225 ; CHECK: %c = landingpad
    226 ; CHECK-NEXT: cleanup
    227 ; CHECK-NEXT: unreachable
    228 
    229 lpad.d:
    230   %d = landingpad { i8*, i32 }
    231           cleanup
    232           catch i32* null
    233   unreachable
    234 ; CHECK: %d = landingpad
    235 ; CHECK-NEXT: null
    236 ; CHECK-NEXT: unreachable
    237 }
    238 
    239 define void @foo_seh() personality i32 (...)* @__C_specific_handler {
    240 ; CHECK-LABEL: @foo_seh(
    241   invoke void @bar()
    242     to label %cont.a unwind label %lpad.a
    243 cont.a:
    244   invoke void @bar()
    245     to label %cont.b unwind label %lpad.b
    246 cont.b:
    247   invoke void @bar()
    248     to label %cont.c unwind label %lpad.c
    249 cont.c:
    250   invoke void @bar()
    251     to label %cont.d unwind label %lpad.d
    252 cont.d:
    253   ret void
    254 
    255 lpad.a:
    256   %a = landingpad { i8*, i32 }
    257           catch i32* null
    258           catch i32* @T1
    259   unreachable
    260 ; CHECK: %a = landingpad
    261 ; CHECK-NEXT: null
    262 ; CHECK-NEXT: unreachable
    263 
    264 lpad.b:
    265   %b = landingpad { i8*, i32 }
    266           filter [1 x i32*] zeroinitializer
    267   unreachable
    268 ; CHECK: %b = landingpad
    269 ; CHECK-NEXT: cleanup
    270 ; CHECK-NEXT: unreachable
    271 
    272 lpad.c:
    273   %c = landingpad { i8*, i32 }
    274           filter [2 x i32*] [i32* @T1, i32* null]
    275   unreachable
    276 ; CHECK: %c = landingpad
    277 ; CHECK-NEXT: cleanup
    278 ; CHECK-NEXT: unreachable
    279 
    280 lpad.d:
    281   %d = landingpad { i8*, i32 }
    282           cleanup
    283           catch i32* null
    284   unreachable
    285 ; CHECK: %d = landingpad
    286 ; CHECK-NEXT: null
    287 ; CHECK-NEXT: unreachable
    288 }
    289