Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -S -instcombine < %s | FileCheck %s
      2 
      3 declare void @use(i32)
      4 
      5 ; These 18 exercise all combinations of signed comparison
      6 ; for each of the three values produced by your typical 
      7 ; 3way compare function (-1, 0, 1)
      8 
      9 define void @test_low_sgt(i64 %a, i64 %b) {
     10 ; CHECK-LABEL: @test_low_sgt
     11 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
     12 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
     13   %eq = icmp eq i64 %a, %b
     14   %slt = icmp slt i64 %a, %b
     15   %. = select i1 %slt, i32 -1, i32 1
     16   %result = select i1 %eq, i32 0, i32 %.
     17   %cmp = icmp sgt i32 %result, -1
     18   br i1 %cmp, label %unreached, label %normal
     19 normal:
     20   ret void
     21 unreached:
     22   call void @use(i32 %result)
     23   ret void
     24 }
     25 
     26 define void @test_low_slt(i64 %a, i64 %b) {
     27 ; CHECK-LABEL: @test_low_slt
     28 ; CHECK: br i1 false, label %unreached, label %normal
     29   %eq = icmp eq i64 %a, %b
     30   %slt = icmp slt i64 %a, %b
     31   %. = select i1 %slt, i32 -1, i32 1
     32   %result = select i1 %eq, i32 0, i32 %.
     33   %cmp = icmp slt i32 %result, -1
     34   br i1 %cmp, label %unreached, label %normal
     35 normal:
     36   ret void
     37 unreached:
     38   call void @use(i32 %result)
     39   ret void
     40 }
     41 
     42 define void @test_low_sge(i64 %a, i64 %b) {
     43 ; CHECK-LABEL: @test_low_sge
     44 ; CHECK: br i1 true, label %unreached, label %normal
     45   %eq = icmp eq i64 %a, %b
     46   %slt = icmp slt i64 %a, %b
     47   %. = select i1 %slt, i32 -1, i32 1
     48   %result = select i1 %eq, i32 0, i32 %.
     49   %cmp = icmp sge i32 %result, -1
     50   br i1 %cmp, label %unreached, label %normal
     51 normal:
     52   ret void
     53 unreached:
     54   call void @use(i32 %result)
     55   ret void
     56 }
     57 
     58 define void @test_low_sle(i64 %a, i64 %b) {
     59 ; CHECK-LABEL: @test_low_sle
     60 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
     61 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
     62   %eq = icmp eq i64 %a, %b
     63   %slt = icmp slt i64 %a, %b
     64   %. = select i1 %slt, i32 -1, i32 1
     65   %result = select i1 %eq, i32 0, i32 %.
     66   %cmp = icmp sle i32 %result, -1
     67   br i1 %cmp, label %unreached, label %normal
     68 normal:
     69   ret void
     70 unreached:
     71   call void @use(i32 %result)
     72   ret void
     73 }
     74 
     75 define void @test_low_ne(i64 %a, i64 %b) {
     76 ; CHECK-LABEL: @test_low_ne
     77 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
     78 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
     79   %eq = icmp eq i64 %a, %b
     80   %slt = icmp slt i64 %a, %b
     81   %. = select i1 %slt, i32 -1, i32 1
     82   %result = select i1 %eq, i32 0, i32 %.
     83   %cmp = icmp ne i32 %result, -1
     84   br i1 %cmp, label %unreached, label %normal
     85 normal:
     86   ret void
     87 unreached:
     88   call void @use(i32 %result)
     89   ret void
     90 }
     91 
     92 define void @test_low_eq(i64 %a, i64 %b) {
     93 ; CHECK-LABEL: @test_low_eq
     94 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
     95 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
     96   %eq = icmp eq i64 %a, %b
     97   %slt = icmp slt i64 %a, %b
     98   %. = select i1 %slt, i32 -1, i32 1
     99   %result = select i1 %eq, i32 0, i32 %.
    100   %cmp = icmp eq i32 %result, -1
    101   br i1 %cmp, label %unreached, label %normal
    102 normal:
    103   ret void
    104 unreached:
    105   call void @use(i32 %result)
    106   ret void
    107 }
    108 
    109 define void @test_mid_sgt(i64 %a, i64 %b) {
    110 ; CHECK-LABEL: @test_mid_sgt
    111 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    112 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    113   %eq = icmp eq i64 %a, %b
    114   %slt = icmp slt i64 %a, %b
    115   %. = select i1 %slt, i32 -1, i32 1
    116   %result = select i1 %eq, i32 0, i32 %.
    117   %cmp = icmp sgt i32 %result, 0
    118   br i1 %cmp, label %unreached, label %normal
    119 normal:
    120   ret void
    121 unreached:
    122   call void @use(i32 %result)
    123   ret void
    124 }
    125 
    126 define void @test_mid_slt(i64 %a, i64 %b) {
    127 ; CHECK-LABEL: @test_mid_slt
    128 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
    129 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    130   %eq = icmp eq i64 %a, %b
    131   %slt = icmp slt i64 %a, %b
    132   %. = select i1 %slt, i32 -1, i32 1
    133   %result = select i1 %eq, i32 0, i32 %.
    134   %cmp = icmp slt i32 %result, 0
    135   br i1 %cmp, label %unreached, label %normal
    136 normal:
    137   ret void
    138 unreached:
    139   call void @use(i32 %result)
    140   ret void
    141 }
    142 
    143 define void @test_mid_sge(i64 %a, i64 %b) {
    144 ; CHECK-LABEL: @test_mid_sge
    145 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
    146 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
    147   %eq = icmp eq i64 %a, %b
    148   %slt = icmp slt i64 %a, %b
    149   %. = select i1 %slt, i32 -1, i32 1
    150   %result = select i1 %eq, i32 0, i32 %.
    151   %cmp = icmp sge i32 %result, 0
    152   br i1 %cmp, label %unreached, label %normal
    153 normal:
    154   ret void
    155 unreached:
    156   call void @use(i32 %result)
    157   ret void
    158 }
    159 
    160 define void @test_mid_sle(i64 %a, i64 %b) {
    161 ; CHECK-LABEL: @test_mid_sle
    162 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    163 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
    164   %eq = icmp eq i64 %a, %b
    165   %slt = icmp slt i64 %a, %b
    166   %. = select i1 %slt, i32 -1, i32 1
    167   %result = select i1 %eq, i32 0, i32 %.
    168   %cmp = icmp sle i32 %result, 0
    169   br i1 %cmp, label %unreached, label %normal
    170 normal:
    171   ret void
    172 unreached:
    173   call void @use(i32 %result)
    174   ret void
    175 }
    176 
    177 define void @test_mid_ne(i64 %a, i64 %b) {
    178 ; CHECK-LABEL: @test_mid_ne
    179 ; CHECK: [[TMP1:%.*]] = icmp eq i64 %a, %b
    180 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
    181   %eq = icmp eq i64 %a, %b
    182   %slt = icmp slt i64 %a, %b
    183   %. = select i1 %slt, i32 -1, i32 1
    184   %result = select i1 %eq, i32 0, i32 %.
    185   %cmp = icmp ne i32 %result, 0
    186   br i1 %cmp, label %unreached, label %normal
    187 normal:
    188   ret void
    189 unreached:
    190   call void @use(i32 %result)
    191   ret void
    192 }
    193 
    194 define void @test_mid_eq(i64 %a, i64 %b) {
    195 ; CHECK-LABEL: @test_mid_eq
    196 ; CHECK: icmp eq i64 %a, %b
    197 ; CHECK: br i1 %eq, label %unreached, label %normal
    198   %eq = icmp eq i64 %a, %b
    199   %slt = icmp slt i64 %a, %b
    200   %. = select i1 %slt, i32 -1, i32 1
    201   %result = select i1 %eq, i32 0, i32 %.
    202   %cmp = icmp eq i32 %result, 0
    203   br i1 %cmp, label %unreached, label %normal
    204 normal:
    205   ret void
    206 unreached:
    207   call void @use(i32 %result)
    208   ret void
    209 }
    210 
    211 define void @test_high_sgt(i64 %a, i64 %b) {
    212 ; CHECK-LABEL: @test_high_sgt
    213 ; CHECK: br i1 false, label %unreached, label %normal
    214   %eq = icmp eq i64 %a, %b
    215   %slt = icmp slt i64 %a, %b
    216   %. = select i1 %slt, i32 -1, i32 1
    217   %result = select i1 %eq, i32 0, i32 %.
    218   %cmp = icmp sgt i32 %result, 1
    219   br i1 %cmp, label %unreached, label %normal
    220 normal:
    221   ret void
    222 unreached:
    223   call void @use(i32 %result)
    224   ret void
    225 }
    226 
    227 define void @test_high_slt(i64 %a, i64 %b) {
    228 ; CHECK-LABEL: @test_high_slt
    229 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    230 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
    231   %eq = icmp eq i64 %a, %b
    232   %slt = icmp slt i64 %a, %b
    233   %. = select i1 %slt, i32 -1, i32 1
    234   %result = select i1 %eq, i32 0, i32 %.
    235   %cmp = icmp slt i32 %result, 1
    236   br i1 %cmp, label %unreached, label %normal
    237 normal:
    238   ret void
    239 unreached:
    240   call void @use(i32 %result)
    241   ret void
    242 }
    243 
    244 define void @test_high_sge(i64 %a, i64 %b) {
    245 ; CHECK-LABEL: @test_high_sge
    246 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    247 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    248   %eq = icmp eq i64 %a, %b
    249   %slt = icmp slt i64 %a, %b
    250   %. = select i1 %slt, i32 -1, i32 1
    251   %result = select i1 %eq, i32 0, i32 %.
    252   %cmp = icmp sge i32 %result, 1
    253   br i1 %cmp, label %unreached, label %normal
    254 normal:
    255   ret void
    256 unreached:
    257   call void @use(i32 %result)
    258   ret void
    259 }
    260 
    261 define void @test_high_sle(i64 %a, i64 %b) {
    262 ; CHECK-LABEL: @test_high_sle
    263 ; CHECK: br i1 true, label %unreached, label %normal
    264   %eq = icmp eq i64 %a, %b
    265   %slt = icmp slt i64 %a, %b
    266   %. = select i1 %slt, i32 -1, i32 1
    267   %result = select i1 %eq, i32 0, i32 %.
    268   %cmp = icmp sle i32 %result, 1
    269   br i1 %cmp, label %unreached, label %normal
    270 normal:
    271   ret void
    272 unreached:
    273   call void @use(i32 %result)
    274   ret void
    275 }
    276 
    277 define void @test_high_ne(i64 %a, i64 %b) {
    278 ; CHECK-LABEL: @test_high_ne
    279 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    280 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached
    281   %eq = icmp eq i64 %a, %b
    282   %slt = icmp slt i64 %a, %b
    283   %. = select i1 %slt, i32 -1, i32 1
    284   %result = select i1 %eq, i32 0, i32 %.
    285   %cmp = icmp ne i32 %result, 1
    286   br i1 %cmp, label %unreached, label %normal
    287 normal:
    288   ret void
    289 unreached:
    290   call void @use(i32 %result)
    291   ret void
    292 }
    293 
    294 define void @test_high_eq(i64 %a, i64 %b) {
    295 ; CHECK-LABEL: @test_high_eq
    296 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    297 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    298   %eq = icmp eq i64 %a, %b
    299   %slt = icmp slt i64 %a, %b
    300   %. = select i1 %slt, i32 -1, i32 1
    301   %result = select i1 %eq, i32 0, i32 %.
    302   %cmp = icmp eq i32 %result, 1
    303   br i1 %cmp, label %unreached, label %normal
    304 normal:
    305   ret void
    306 unreached:
    307   call void @use(i32 %result)
    308   ret void
    309 }
    310 
    311 ; These five make sure we didn't accidentally hard code one of the
    312 ; produced values
    313 
    314 define void @non_standard_low(i64 %a, i64 %b) {
    315 ; CHECK-LABEL: @non_standard_low
    316 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
    317 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    318   %eq = icmp eq i64 %a, %b
    319   %slt = icmp slt i64 %a, %b
    320   %. = select i1 %slt, i32 -3, i32 -1
    321   %result = select i1 %eq, i32 -2, i32 %.
    322   %cmp = icmp eq i32 %result, -3
    323   br i1 %cmp, label %unreached, label %normal
    324 normal:
    325   ret void
    326 unreached:
    327   call void @use(i32 %result)
    328   ret void
    329 }
    330 
    331 define void @non_standard_mid(i64 %a, i64 %b) {
    332 ; CHECK-LABEL: @non_standard_mid
    333 ; CHECK: icmp eq i64 %a, %b
    334 ; CHECK: br i1 %eq, label %unreached, label %normal
    335   %eq = icmp eq i64 %a, %b
    336   %slt = icmp slt i64 %a, %b
    337   %. = select i1 %slt, i32 -3, i32 -1
    338   %result = select i1 %eq, i32 -2, i32 %.
    339   %cmp = icmp eq i32 %result, -2
    340   br i1 %cmp, label %unreached, label %normal
    341 normal:
    342   ret void
    343 unreached:
    344   call void @use(i32 %result)
    345   ret void
    346 }
    347 
    348 define void @non_standard_high(i64 %a, i64 %b) {
    349 ; CHECK-LABEL: @non_standard_high
    350 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
    351 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal
    352   %eq = icmp eq i64 %a, %b
    353   %slt = icmp slt i64 %a, %b
    354   %. = select i1 %slt, i32 -3, i32 -1
    355   %result = select i1 %eq, i32 -2, i32 %.
    356   %cmp = icmp eq i32 %result, -1
    357   br i1 %cmp, label %unreached, label %normal
    358 normal:
    359   ret void
    360 unreached:
    361   call void @use(i32 %result)
    362   ret void
    363 }
    364 
    365 define void @non_standard_bound1(i64 %a, i64 %b) {
    366 ; CHECK-LABEL: @non_standard_bound1
    367 ; CHECK: br i1 false, label %unreached, label %normal
    368   %eq = icmp eq i64 %a, %b
    369   %slt = icmp slt i64 %a, %b
    370   %. = select i1 %slt, i32 -3, i32 -1
    371   %result = select i1 %eq, i32 -2, i32 %.
    372   %cmp = icmp eq i32 %result, -20
    373   br i1 %cmp, label %unreached, label %normal
    374 normal:
    375   ret void
    376 unreached:
    377   call void @use(i32 %result)
    378   ret void
    379 }
    380 
    381 define void @non_standard_bound2(i64 %a, i64 %b) {
    382 ; CHECK-LABEL: @non_standard_bound2
    383 ; CHECK: br i1 false, label %unreached, label %normal
    384   %eq = icmp eq i64 %a, %b
    385   %slt = icmp slt i64 %a, %b
    386   %. = select i1 %slt, i32 -3, i32 -1
    387   %result = select i1 %eq, i32 -2, i32 %.
    388   %cmp = icmp eq i32 %result, 0
    389   br i1 %cmp, label %unreached, label %normal
    390 normal:
    391   ret void
    392 unreached:
    393   call void @use(i32 %result)
    394   ret void
    395 }
    396