Home | History | Annotate | Download | only in GVNHoist
      1 ; RUN: opt -S -gvn-hoist < %s | FileCheck %s
      2 
      3 ; Checking gvn-hoist in case of indirect branches.
      4 
      5 ; Check that the bitcast is not hoisted because it is after an indirect call
      6 ; CHECK-LABEL: @foo
      7 ; CHECK-LABEL: l1.preheader:
      8 ; CHECK-NEXT: bitcast
      9 ; CHECK-LABEL: l1
     10 ; CHECK: bitcast
     11 
     12 %class.bar = type { i8*, %class.base* }
     13 %class.base = type { i32 (...)** }
     14 
     15 @bar = local_unnamed_addr global i32 ()* null, align 8
     16 @bar1 = local_unnamed_addr global i32 ()* null, align 8
     17 
     18 define i32 @foo(i32* nocapture readonly %i) {
     19 entry:
     20   %agg.tmp = alloca %class.bar, align 8
     21   %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
     22   %y = load %class.base*, %class.base** %x, align 8
     23   %0 = load i32, i32* %i, align 4
     24   %.off = add i32 %0, -1
     25   %switch = icmp ult i32 %.off, 2
     26   br i1 %switch, label %l1.preheader, label %sw.default
     27 
     28 l1.preheader:                                     ; preds = %sw.default, %entry
     29   %b1 = bitcast %class.base* %y to void (%class.base*)***
     30   br label %l1
     31 
     32 l1:                                               ; preds = %l1.preheader, %l1
     33   %1 = load i32 ()*, i32 ()** @bar, align 8
     34   %call = tail call i32 %1()
     35   %b2 = bitcast %class.base* %y to void (%class.base*)***
     36   br label %l1
     37 
     38 sw.default:                                       ; preds = %entry
     39   %2 = load i32 ()*, i32 ()** @bar1, align 8
     40   %call2 = tail call i32 %2()
     41   br label %l1.preheader
     42 }
     43 
     44 
     45 ; Any instruction inside an infinite loop will not be hoisted because
     46 ; there is no path to exit of the function.
     47 
     48 ; CHECK-LABEL: @foo1
     49 ; CHECK-LABEL: l1.preheader:
     50 ; CHECK-NEXT: bitcast
     51 ; CHECK-LABEL: l1:
     52 ; CHECK: bitcast
     53 
     54 define i32 @foo1(i32* nocapture readonly %i) {
     55 entry:
     56   %agg.tmp = alloca %class.bar, align 8
     57   %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
     58   %y = load %class.base*, %class.base** %x, align 8
     59   %0 = load i32, i32* %i, align 4
     60   %.off = add i32 %0, -1
     61   %switch = icmp ult i32 %.off, 2
     62   br i1 %switch, label %l1.preheader, label %sw.default
     63 
     64 l1.preheader:                                     ; preds = %sw.default, %entry
     65   %b1 = bitcast %class.base* %y to void (%class.base*)***
     66   %y1 = load %class.base*, %class.base** %x, align 8
     67   br label %l1
     68 
     69 l1:                                               ; preds = %l1.preheader, %l1
     70   %b2 = bitcast %class.base* %y to void (%class.base*)***
     71   %1 = load i32 ()*, i32 ()** @bar, align 8
     72   %y2 = load %class.base*, %class.base** %x, align 8
     73   %call = tail call i32 %1()
     74   br label %l1
     75 
     76 sw.default:                                       ; preds = %entry
     77   %2 = load i32 ()*, i32 ()** @bar1, align 8
     78   %call2 = tail call i32 %2()
     79   br label %l1.preheader
     80 }
     81 
     82 ; Check that bitcast is hoisted even when one of them is partially redundant.
     83 ; CHECK-LABEL: @test13
     84 ; CHECK: bitcast
     85 ; CHECK-NOT: bitcast
     86 
     87 define i32 @test13(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
     88 entry:
     89   %agg.tmp = alloca %class.bar, align 8
     90   %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
     91   %y = load %class.base*, %class.base** %x, align 8
     92   indirectbr i8* %Ptr, [label %BrBlock, label %B2]
     93 
     94 B2:
     95   %b1 = bitcast %class.base* %y to void (%class.base*)***
     96   store i32 4, i32 *%P
     97   br label %BrBlock
     98 
     99 BrBlock:
    100   %b2 = bitcast %class.base* %y to void (%class.base*)***
    101   %L = load i32, i32* %P
    102   %C = icmp eq i32 %L, 42
    103   br i1 %C, label %T, label %F
    104 
    105 T:
    106   ret i32 123
    107 F:
    108   ret i32 1422
    109 }
    110 
    111 ; Check that the bitcast is not hoisted because anticipability
    112 ; cannot be guaranteed here as one of the indirect branch targets
    113 ; do not have the bitcast instruction.
    114 
    115 ; CHECK-LABEL: @test14
    116 ; CHECK-LABEL: B2:
    117 ; CHECK-NEXT: bitcast
    118 ; CHECK-LABEL: BrBlock:
    119 ; CHECK-NEXT: bitcast
    120 
    121 define i32 @test14(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
    122 entry:
    123   %agg.tmp = alloca %class.bar, align 8
    124   %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
    125   %y = load %class.base*, %class.base** %x, align 8
    126   indirectbr i8* %Ptr, [label %BrBlock, label %B2, label %T]
    127 
    128 B2:
    129   %b1 = bitcast %class.base* %y to void (%class.base*)***
    130   store i32 4, i32 *%P
    131   br label %BrBlock
    132 
    133 BrBlock:
    134   %b2 = bitcast %class.base* %y to void (%class.base*)***
    135   %L = load i32, i32* %P
    136   %C = icmp eq i32 %L, 42
    137   br i1 %C, label %T, label %F
    138 
    139 T:
    140   %pi = load i32, i32* %i, align 4
    141   ret i32 %pi
    142 F:
    143   %pl = load i32, i32* %P
    144   ret i32 %pl
    145 }
    146 
    147 
    148 ; Check that the bitcast is not hoisted because of a cycle
    149 ; due to indirect branches
    150 ; CHECK-LABEL: @test16
    151 ; CHECK-LABEL: B2:
    152 ; CHECK-NEXT: bitcast
    153 ; CHECK-LABEL: BrBlock:
    154 ; CHECK-NEXT: bitcast
    155 
    156 define i32 @test16(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
    157 entry:
    158   %agg.tmp = alloca %class.bar, align 8
    159   %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
    160   %y = load %class.base*, %class.base** %x, align 8
    161   indirectbr i8* %Ptr, [label %BrBlock, label %B2]
    162 
    163 B2:
    164   %b1 = bitcast %class.base* %y to void (%class.base*)***
    165   %0 = load i32, i32* %i, align 4
    166   store i32 %0, i32 *%P
    167   br label %BrBlock
    168 
    169 BrBlock:
    170   %b2 = bitcast %class.base* %y to void (%class.base*)***
    171   %L = load i32, i32* %P
    172   %C = icmp eq i32 %L, 42
    173   br i1 %C, label %T, label %F
    174 
    175 T:
    176   indirectbr i32* %P, [label %BrBlock, label %B2]
    177 
    178 F:
    179   indirectbr i8* %Ptr, [label %BrBlock, label %B2]
    180 }
    181 
    182 
    183 @_ZTIi = external constant i8*
    184 
    185 ; Check that an instruction is not hoisted out of landing pad (%lpad4)
    186 ; Also within a landing pad no redundancies are removed by gvn-hoist,
    187 ; however an instruction may be hoisted into a landing pad if
    188 ; landing pad has direct branches (e.g., %lpad to %catch1, %catch)
    189 ; This CFG has a cycle (%lpad -> %catch1 -> %lpad4 -> %lpad)
    190 
    191 ; CHECK-LABEL: @foo2
    192 ; Check that nothing gets hoisted out of %lpad
    193 ; CHECK-LABEL: lpad:
    194 ; CHECK: %bc1 = add i32 %0, 10
    195 ; CHECK: %bc7 = add i32 %0, 10
    196 
    197 ; Check that the add is hoisted
    198 ; CHECK-LABEL: catch1:
    199 ; CHECK-NEXT: invoke
    200 
    201 ; Check that the add is hoisted
    202 ; CHECK-LABEL: catch:
    203 ; CHECK-NEXT: load
    204 
    205 ; Check that other adds are not hoisted
    206 ; CHECK-LABEL: lpad4:
    207 ; CHECK: %bc5 = add i32 %0, 10
    208 ; CHECK-LABEL: unreachable:
    209 ; CHECK: %bc2 = add i32 %0, 10
    210 
    211 ; Function Attrs: noinline uwtable
    212 define i32 @foo2(i32* nocapture readonly %i) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    213 entry:
    214   %0 = load i32, i32* %i, align 4
    215   %cmp = icmp eq i32 %0, 0
    216   br i1 %cmp, label %try.cont, label %if.then
    217 
    218 if.then:
    219   %exception = tail call i8* @__cxa_allocate_exception(i64 4) #2
    220   %1 = bitcast i8* %exception to i32*
    221   store i32 %0, i32* %1, align 16
    222   invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
    223           to label %unreachable unwind label %lpad
    224 
    225 lpad:
    226   %2 = landingpad { i8*, i32 }
    227           catch i8* bitcast (i8** @_ZTIi to i8*)
    228           catch i8* null
    229   %bc1 = add i32 %0, 10
    230   %3 = extractvalue { i8*, i32 } %2, 0
    231   %4 = extractvalue { i8*, i32 } %2, 1
    232   %5 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
    233   %matches = icmp eq i32 %4, %5
    234   %bc7 = add i32 %0, 10
    235   %6 = tail call i8* @__cxa_begin_catch(i8* %3) #2
    236   br i1 %matches, label %catch1, label %catch
    237 
    238 catch1:
    239   %bc3 = add i32 %0, 10
    240   invoke void @__cxa_rethrow() #3
    241           to label %unreachable unwind label %lpad4
    242 
    243 catch:
    244   %bc4 = add i32 %0, 10
    245   %7 = load i32, i32* %i, align 4
    246   %add = add nsw i32 %7, 1
    247   tail call void @__cxa_end_catch()
    248   br label %try.cont
    249 
    250 lpad4:
    251   %8 = landingpad { i8*, i32 }
    252           cleanup
    253   %bc5 = add i32 %0, 10
    254   tail call void @__cxa_end_catch() #2
    255   invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
    256           to label %unreachable unwind label %lpad
    257 
    258 try.cont:
    259   %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ]
    260   %bc6 = add i32 %0, 10
    261   ret i32 %k.0
    262 
    263 unreachable:
    264   %bc2 = add i32 %0, 10
    265   ret i32 %bc2
    266 }
    267 
    268 declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr
    269 
    270 declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
    271 
    272 declare i32 @__gxx_personality_v0(...)
    273 
    274 ; Function Attrs: nounwind readnone
    275 declare i32 @llvm.eh.typeid.for(i8*) #1
    276 
    277 declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr
    278 
    279 declare void @__cxa_end_catch() local_unnamed_addr
    280 
    281 declare void @__cxa_rethrow() local_unnamed_addr
    282 
    283 attributes #1 = { nounwind readnone }
    284 attributes #2 = { nounwind }
    285 attributes #3 = { noreturn }
    286