Home | History | Annotate | Download | only in SimplifyCFG
      1 ; RUN: opt -simplifycfg -S -o - < %s | FileCheck %s
      2 
      3 declare void @helper(i32)
      4 
      5 define void @test1(i1 %a, i1 %b) {
      6 ; CHECK-LABEL: @test1(
      7 entry:
      8   br i1 %a, label %Y, label %X, !prof !0
      9 ; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !0
     10 
     11 X:
     12   %c = or i1 %b, false
     13   br i1 %c, label %Z, label %Y, !prof !1
     14 
     15 Y:
     16   call void @helper(i32 0)
     17   ret void
     18 
     19 Z:
     20   call void @helper(i32 1)
     21   ret void
     22 }
     23 
     24 define void @test2(i1 %a, i1 %b) {
     25 ; CHECK-LABEL: @test2(
     26 entry:
     27   br i1 %a, label %X, label %Y, !prof !1
     28 ; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !1
     29 ; CHECK-NOT: !prof
     30 
     31 X:
     32   %c = or i1 %b, false
     33   br i1 %c, label %Z, label %Y, !prof !2
     34 
     35 Y:
     36   call void @helper(i32 0)
     37   ret void
     38 
     39 Z:
     40   call void @helper(i32 1)
     41   ret void
     42 }
     43 
     44 define void @test3(i1 %a, i1 %b) {
     45 ; CHECK-LABEL: @test3(
     46 ; CHECK-NOT: !prof
     47 entry:
     48   br i1 %a, label %X, label %Y, !prof !1
     49 
     50 X:
     51   %c = or i1 %b, false
     52   br i1 %c, label %Z, label %Y
     53 
     54 Y:
     55   call void @helper(i32 0)
     56   ret void
     57 
     58 Z:
     59   call void @helper(i32 1)
     60   ret void
     61 }
     62 
     63 define void @test4(i1 %a, i1 %b) {
     64 ; CHECK-LABEL: @test4(
     65 ; CHECK-NOT: !prof
     66 entry:
     67   br i1 %a, label %X, label %Y
     68 
     69 X:
     70   %c = or i1 %b, false
     71   br i1 %c, label %Z, label %Y, !prof !1
     72 
     73 Y:
     74   call void @helper(i32 0)
     75   ret void
     76 
     77 Z:
     78   call void @helper(i32 1)
     79   ret void
     80 }
     81 
     82 ;; test5 - The case where it jumps to the default target will be removed.
     83 define void @test5(i32 %M, i32 %N) nounwind uwtable {
     84 entry:
     85   switch i32 %N, label %sw2 [
     86     i32 1, label %sw2
     87     i32 2, label %sw.bb
     88     i32 3, label %sw.bb1
     89   ], !prof !3
     90 ; CHECK-LABEL: @test5(
     91 ; CHECK: switch i32 %N, label %sw2 [
     92 ; CHECK: i32 3, label %sw.bb1
     93 ; CHECK: i32 2, label %sw.bb
     94 ; CHECK: ], !prof !2
     95 
     96 sw.bb:
     97   call void @helper(i32 0)
     98   br label %sw.epilog
     99 
    100 sw.bb1:
    101   call void @helper(i32 1)
    102   br label %sw.epilog
    103 
    104 sw2:
    105   call void @helper(i32 2)
    106   br label %sw.epilog
    107 
    108 sw.epilog:
    109   ret void
    110 }
    111 
    112 ;; test6 - Some cases of the second switch are pruned during optimization.
    113 ;; Then the second switch will be converted to a branch, finally, the first
    114 ;; switch and the branch will be merged into a single switch.
    115 define void @test6(i32 %M, i32 %N) nounwind uwtable {
    116 entry:
    117   switch i32 %N, label %sw2 [
    118     i32 1, label %sw2
    119     i32 2, label %sw.bb
    120     i32 3, label %sw.bb1
    121   ], !prof !4
    122 ; CHECK-LABEL: @test6(
    123 ; CHECK: switch i32 %N, label %sw.epilog
    124 ; CHECK: i32 3, label %sw.bb1
    125 ; CHECK: i32 2, label %sw.bb
    126 ; CHECK: i32 4, label %sw.bb5
    127 ; CHECK: ], !prof !3
    128 
    129 sw.bb:
    130   call void @helper(i32 0)
    131   br label %sw.epilog
    132 
    133 sw.bb1:
    134   call void @helper(i32 1)
    135   br label %sw.epilog
    136 
    137 sw2:
    138 ;; Here "case 2" is invalidated since the default case of the first switch
    139 ;; does not include "case 2".
    140   switch i32 %N, label %sw.epilog [
    141     i32 2, label %sw.bb4
    142     i32 4, label %sw.bb5
    143   ], !prof !5
    144 
    145 sw.bb4:
    146   call void @helper(i32 2)
    147   br label %sw.epilog
    148 
    149 sw.bb5:
    150   call void @helper(i32 3)
    151   br label %sw.epilog
    152 
    153 sw.epilog:
    154   ret void
    155 }
    156 
    157 ;; This test is based on test1 but swapped the targets of the second branch.
    158 define void @test1_swap(i1 %a, i1 %b) {
    159 ; CHECK-LABEL: @test1_swap(
    160 entry:
    161   br i1 %a, label %Y, label %X, !prof !0
    162 ; CHECK: br i1 %or.cond, label %Y, label %Z, !prof !4
    163 
    164 X:
    165   %c = or i1 %b, false
    166   br i1 %c, label %Y, label %Z, !prof !1
    167 
    168 Y:
    169   call void @helper(i32 0)
    170   ret void
    171 
    172 Z:
    173   call void @helper(i32 1)
    174   ret void
    175 }
    176 
    177 define void @test7(i1 %a, i1 %b) {
    178 ; CHECK-LABEL: @test7(
    179 entry:
    180   %c = or i1 %b, false
    181   br i1 %a, label %Y, label %X, !prof !0
    182 ; CHECK: br i1 %brmerge, label %Y, label %Z, !prof !5
    183 
    184 X:
    185   br i1 %c, label %Y, label %Z, !prof !6
    186 
    187 Y:
    188   call void @helper(i32 0)
    189   ret void
    190 
    191 Z:
    192   call void @helper(i32 1)
    193   ret void
    194 }
    195 
    196 ; Test basic folding to a conditional branch.
    197 define void @test8(i64 %x, i64 %y) nounwind {
    198 ; CHECK-LABEL: @test8(
    199 entry:
    200     %lt = icmp slt i64 %x, %y
    201 ; CHECK: br i1 %lt, label %a, label %b, !prof !6
    202     %qux = select i1 %lt, i32 0, i32 2
    203     switch i32 %qux, label %bees [
    204         i32 0, label %a
    205         i32 1, label %b
    206         i32 2, label %b
    207     ], !prof !7
    208 a:
    209     call void @helper(i32 0) nounwind
    210     ret void
    211 b:
    212     call void @helper(i32 1) nounwind
    213     ret void
    214 bees:
    215     call void @helper(i32 2) nounwind
    216     ret void
    217 }
    218 
    219 ; Test edge splitting when the default target has icmp and unconditinal
    220 ; branch
    221 define i1 @test9(i32 %x, i32 %y) nounwind {
    222 ; CHECK-LABEL: @test9(
    223 entry:
    224     switch i32 %x, label %bees [
    225         i32 0, label %a
    226         i32 1, label %end
    227         i32 2, label %end
    228     ], !prof !7
    229 ; CHECK: switch i32 %x, label %bees [
    230 ; CHECK: i32 0, label %a
    231 ; CHECK: i32 1, label %end
    232 ; CHECK: i32 2, label %end
    233 ; CHECK: i32 92, label %end
    234 ; CHECK: ], !prof !7
    235 
    236 a:
    237     call void @helper(i32 0) nounwind
    238     %reta = icmp slt i32 %x, %y
    239     ret i1 %reta
    240 
    241 bees:
    242     %tmp = icmp eq i32 %x, 92
    243     br label %end
    244 
    245 end:
    246 ; CHECK: end:
    247 ; CHECK: %ret = phi i1 [ true, %entry ], [ false, %bees ], [ true, %entry ], [ true, %entry ]
    248     %ret = phi i1 [ true, %entry ], [%tmp, %bees], [true, %entry]
    249     call void @helper(i32 2) nounwind
    250     ret i1 %ret
    251 }
    252 
    253 define void @test10(i32 %x) nounwind readnone ssp noredzone {
    254 entry:
    255  switch i32 %x, label %lor.rhs [
    256    i32 2, label %lor.end
    257    i32 1, label %lor.end
    258    i32 3, label %lor.end
    259  ], !prof !7
    260 
    261 lor.rhs:
    262  call void @helper(i32 1) nounwind
    263  ret void
    264 
    265 lor.end:
    266  call void @helper(i32 0) nounwind
    267  ret void
    268 
    269 ; CHECK-LABEL: @test10(
    270 ; CHECK: %x.off = add i32 %x, -1
    271 ; CHECK: %switch = icmp ult i32 %x.off, 3
    272 ; CHECK: br i1 %switch, label %lor.end, label %lor.rhs, !prof !8
    273 }
    274 
    275 ; Remove dead cases from the switch.
    276 define void @test11(i32 %x) nounwind {
    277   %i = shl i32 %x, 1
    278   switch i32 %i, label %a [
    279     i32 21, label %b
    280     i32 24, label %c
    281   ], !prof !8
    282 ; CHECK-LABEL: @test11(
    283 ; CHECK: %cond = icmp eq i32 %i, 24
    284 ; CHECK: br i1 %cond, label %c, label %a, !prof !9
    285 
    286 a:
    287  call void @helper(i32 0) nounwind
    288  ret void
    289 b:
    290  call void @helper(i32 1) nounwind
    291  ret void
    292 c:
    293  call void @helper(i32 2) nounwind
    294  ret void
    295 }
    296 
    297 ;; test12 - Don't crash if the whole switch is removed
    298 define void @test12(i32 %M, i32 %N) nounwind uwtable {
    299 entry:
    300   switch i32 %N, label %sw.bb [
    301     i32 1, label %sw.bb
    302   ], !prof !9
    303 ; CHECK-LABEL: @test12(
    304 ; CHECK-NEXT: entry:
    305 ; CHECK-NEXT: call void @helper
    306 ; CHECK-NEXT: ret void
    307 
    308 sw.bb:
    309   call void @helper(i32 0)
    310   br label %sw.epilog
    311 
    312 sw.epilog:
    313   ret void
    314 }
    315 
    316 ;; If every case is dead, make sure they are all removed. This used to
    317 ;; crash trying to merge the metadata.
    318 define void @test13(i32 %x) nounwind {
    319 entry:
    320   %i = shl i32 %x, 1
    321   switch i32 %i, label %a [
    322     i32 21, label %b
    323     i32 25, label %c
    324   ], !prof !8
    325 ; CHECK-LABEL: @test13(
    326 ; CHECK-NEXT: entry:
    327 ; CHECK-NEXT: call void @helper
    328 ; CHECK-NEXT: ret void
    329 
    330 a:
    331  call void @helper(i32 0) nounwind
    332  ret void
    333 b:
    334  call void @helper(i32 1) nounwind
    335  ret void
    336 c:
    337  call void @helper(i32 2) nounwind
    338  ret void
    339 }
    340 
    341 ;; When folding branches to common destination, the updated branch weights
    342 ;; can exceed uint32 by more than factor of 2. We should keep halving the
    343 ;; weights until they can fit into uint32.
    344 @max_regno = common global i32 0, align 4
    345 define void @test14(i32* %old, i32 %final) {
    346 ; CHECK-LABEL: @test14
    347 ; CHECK: br i1 %or.cond, label %for.exit, label %for.inc, !prof !10
    348 for.cond:
    349   br label %for.cond2
    350 for.cond2:
    351   %i.1 = phi i32 [ %inc19, %for.inc ], [ 0, %for.cond ]
    352   %bit.0 = phi i32 [ %shl, %for.inc ], [ 1, %for.cond ]
    353   %tobool = icmp eq i32 %bit.0, 0
    354   br i1 %tobool, label %for.exit, label %for.body3, !prof !10
    355 for.body3:
    356   %v3 = load i32, i32* @max_regno, align 4
    357   %cmp4 = icmp eq i32 %i.1, %v3
    358   br i1 %cmp4, label %for.exit, label %for.inc, !prof !11
    359 for.inc:
    360   %shl = shl i32 %bit.0, 1
    361   %inc19 = add nsw i32 %i.1, 1
    362   br label %for.cond2
    363 for.exit:
    364   ret void
    365 }
    366 
    367 !0 = !{!"branch_weights", i32 3, i32 5}
    368 !1 = !{!"branch_weights", i32 1, i32 1}
    369 !2 = !{!"branch_weights", i32 1, i32 2}
    370 !3 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
    371 !4 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
    372 !5 = !{!"branch_weights", i32 7, i32 6, i32 5}
    373 !6 = !{!"branch_weights", i32 1, i32 3}
    374 !7 = !{!"branch_weights", i32 33, i32 9, i32 8, i32 7}
    375 !8 = !{!"branch_weights", i32 33, i32 9, i32 8}
    376 !9 = !{!"branch_weights", i32 7, i32 6}
    377 !10 = !{!"branch_weights", i32 672646, i32 21604207}
    378 !11 = !{!"branch_weights", i32 6960, i32 21597248}
    379 
    380 ; CHECK: !0 = !{!"branch_weights", i32 5, i32 11}
    381 ; CHECK: !1 = !{!"branch_weights", i32 1, i32 5}
    382 ; CHECK: !2 = !{!"branch_weights", i32 7, i32 1, i32 2}
    383 ; CHECK: !3 = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
    384 ; CHECK: !4 = !{!"branch_weights", i32 11, i32 5}
    385 ; CHECK: !5 = !{!"branch_weights", i32 17, i32 15} 
    386 ; CHECK: !6 = !{!"branch_weights", i32 9, i32 7}
    387 ; CHECK: !7 = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
    388 ; CHECK: !8 = !{!"branch_weights", i32 24, i32 33}
    389 ; CHECK: !9 = !{!"branch_weights", i32 8, i32 33}
    390 ;; The false weight prints out as a negative integer here, but inside llvm, we
    391 ;; treat the weight as an unsigned integer.
    392 ; CHECK: !10 = !{!"branch_weights", i32 112017436, i32 -735157296}
    393