Home | History | Annotate | Download | only in SimplifyCFG
      1 ; RUN: opt -simplifycfg -instcombine < %s -simplifycfg-merge-cond-stores=true -simplifycfg-merge-cond-stores-aggressively=false -phi-node-folding-threshold=2 -S | FileCheck %s
      2 
      3 ; CHECK-LABEL: @test_simple
      4 ; This test should succeed and end up if-converted.
      5 ; CHECK: icmp eq i32 %b, 0
      6 ; CHECK-NEXT: icmp ne i32 %a, 0
      7 ; CHECK-NEXT: xor i1 %x2, true
      8 ; CHECK-NEXT: %[[x:.*]] = or i1 %{{.*}}, %{{.*}}
      9 ; CHECK-NEXT: br i1 %[[x]]
     10 ; CHECK: store
     11 ; CHECK-NOT: store
     12 ; CHECK: ret
     13 define void @test_simple(i32* %p, i32 %a, i32 %b) {
     14 entry:
     15   %x1 = icmp eq i32 %a, 0
     16   br i1 %x1, label %fallthrough, label %yes1
     17 
     18 yes1:
     19   store i32 0, i32* %p
     20   br label %fallthrough
     21 
     22 fallthrough:
     23   %x2 = icmp eq i32 %b, 0
     24   br i1 %x2, label %end, label %yes2
     25 
     26 yes2:
     27   store i32 1, i32* %p
     28   br label %end
     29 
     30 end:
     31   ret void
     32 }
     33 
     34 ; CHECK-LABEL: @test_recursive
     35 ; This test should entirely fold away, leaving one large basic block.
     36 ; CHECK: store
     37 ; CHECK-NOT: store
     38 ; CHECK: ret
     39 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
     40 entry:
     41   %x1 = icmp eq i32 %a, 0
     42   br i1 %x1, label %fallthrough, label %yes1
     43 
     44 yes1:
     45   store i32 0, i32* %p
     46   br label %fallthrough
     47 
     48 fallthrough:
     49   %x2 = icmp eq i32 %b, 0
     50   br i1 %x2, label %next, label %yes2
     51 
     52 yes2:
     53   store i32 1, i32* %p
     54   br label %next
     55 
     56 next:
     57   %x3 = icmp eq i32 %c, 0
     58   br i1 %x3, label %fallthrough2, label %yes3
     59 
     60 yes3:
     61   store i32 2, i32* %p
     62   br label %fallthrough2
     63 
     64 fallthrough2:
     65   %x4 = icmp eq i32 %d, 0
     66   br i1 %x4, label %end, label %yes4
     67 
     68 yes4:
     69   store i32 3, i32* %p
     70   br label %end
     71 
     72 
     73 end:
     74   ret void
     75 }
     76 
     77 ; CHECK-LABEL: @test_not_ifconverted
     78 ; The code in each diamond is too large - it won't be if-converted so our
     79 ; heuristics should say no.
     80 ; CHECK: store
     81 ; CHECK: store
     82 ; CHECK: ret
     83 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
     84 entry:
     85   %x1 = icmp eq i32 %a, 0
     86   br i1 %x1, label %fallthrough, label %yes1
     87 
     88 yes1:
     89   %y1 = or i32 %b, 55
     90   %y2 = add i32 %y1, 24
     91   %y3 = and i32 %y2, 67
     92   store i32 %y3, i32* %p
     93   br label %fallthrough
     94 
     95 fallthrough:
     96   %x2 = icmp eq i32 %b, 0
     97   br i1 %x2, label %end, label %yes2
     98 
     99 yes2:
    100   %z1 = or i32 %a, 55
    101   %z2 = add i32 %z1, 24
    102   %z3 = and i32 %z2, 67
    103   store i32 %z3, i32* %p
    104   br label %end
    105 
    106 end:
    107   ret void
    108 }
    109 
    110 ; CHECK-LABEL: @test_aliasing1
    111 ; The store to %p clobbers the previous store, so if-converting this would
    112 ; be illegal.
    113 ; CHECK: store
    114 ; CHECK: store
    115 ; CHECK: ret
    116 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
    117 entry:
    118   %x1 = icmp eq i32 %a, 0
    119   br i1 %x1, label %fallthrough, label %yes1
    120 
    121 yes1:
    122   store i32 0, i32* %p
    123   br label %fallthrough
    124 
    125 fallthrough:
    126   %y1 = load i32, i32* %p
    127   %x2 = icmp eq i32 %y1, 0
    128   br i1 %x2, label %end, label %yes2
    129 
    130 yes2:
    131   store i32 1, i32* %p
    132   br label %end
    133 
    134 end:
    135   ret void
    136 }
    137 
    138 ; CHECK-LABEL: @test_aliasing2
    139 ; The load from %q aliases with %p, so if-converting this would be illegal.
    140 ; CHECK: store
    141 ; CHECK: store
    142 ; CHECK: ret
    143 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
    144 entry:
    145   %x1 = icmp eq i32 %a, 0
    146   br i1 %x1, label %fallthrough, label %yes1
    147 
    148 yes1:
    149   store i32 0, i32* %p
    150   br label %fallthrough
    151 
    152 fallthrough:
    153   %y1 = load i32, i32* %q
    154   %x2 = icmp eq i32 %y1, 0
    155   br i1 %x2, label %end, label %yes2
    156 
    157 yes2:
    158   store i32 1, i32* %p
    159   br label %end
    160 
    161 end:
    162   ret void
    163 }
    164 
    165 declare void @f()
    166 
    167 ; CHECK-LABEL: @test_diamond_simple
    168 ; This should get if-converted.
    169 ; CHECK: store
    170 ; CHECK-NOT: store
    171 ; CHECK: ret
    172 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
    173 entry:
    174   %x1 = icmp eq i32 %a, 0
    175   br i1 %x1, label %no1, label %yes1
    176 
    177 yes1:
    178   store i32 0, i32* %p
    179   br label %fallthrough
    180 
    181 no1:
    182   %z1 = add i32 %a, %b
    183   br label %fallthrough
    184 
    185 fallthrough:
    186   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
    187   %x2 = icmp eq i32 %b, 0
    188   br i1 %x2, label %no2, label %yes2
    189 
    190 yes2:
    191   store i32 1, i32* %p
    192   br label %end
    193 
    194 no2:
    195   %z3 = sub i32 %z2, %b
    196   br label %end
    197 
    198 end:
    199   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
    200   ret i32 %z4
    201 }
    202 
    203 ; CHECK-LABEL: @test_diamond_alias3
    204 ; Now there is a call to f() in the bottom branch. The store in the first
    205 ; branch would now be reordered with respect to the call if we if-converted,
    206 ; so we must not.
    207 ; CHECK: store
    208 ; CHECK: store
    209 ; CHECK: ret
    210 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
    211 entry:
    212   %x1 = icmp eq i32 %a, 0
    213   br i1 %x1, label %no1, label %yes1
    214 
    215 yes1:
    216   store i32 0, i32* %p
    217   br label %fallthrough
    218 
    219 no1:
    220   call void @f()
    221   %z1 = add i32 %a, %b
    222   br label %fallthrough
    223 
    224 fallthrough:
    225   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
    226   %x2 = icmp eq i32 %b, 0
    227   br i1 %x2, label %no2, label %yes2
    228 
    229 yes2:
    230   store i32 1, i32* %p
    231   br label %end
    232 
    233 no2:
    234   call void @f()
    235   %z3 = sub i32 %z2, %b
    236   br label %end
    237 
    238 end:
    239   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
    240   ret i32 %z4
    241 }
    242