Home | History | Annotate | Download | only in InstSimplify
      1 ; RUN: opt < %s -instsimplify -S | FileCheck %s
      2 
      3 define i32 @sdiv_sext_big_divisor(i8 %x) {
      4 ; CHECK-LABEL: @sdiv_sext_big_divisor(
      5 ; CHECK-NEXT:    ret i32 0
      6 ;
      7   %conv = sext i8 %x to i32
      8   %div = sdiv i32 %conv, 129
      9   ret i32 %div
     10 }
     11 
     12 define i32 @not_sdiv_sext_big_divisor(i8 %x) {
     13 ; CHECK-LABEL: @not_sdiv_sext_big_divisor(
     14 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
     15 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 128
     16 ; CHECK-NEXT:    ret i32 [[DIV]]
     17 ;
     18   %conv = sext i8 %x to i32
     19   %div = sdiv i32 %conv, 128
     20   ret i32 %div
     21 }
     22 
     23 define i32 @sdiv_sext_small_divisor(i8 %x) {
     24 ; CHECK-LABEL: @sdiv_sext_small_divisor(
     25 ; CHECK-NEXT:    ret i32 0
     26 ;
     27   %conv = sext i8 %x to i32
     28   %div = sdiv i32 %conv, -129
     29   ret i32 %div
     30 }
     31 
     32 define i32 @not_sdiv_sext_small_divisor(i8 %x) {
     33 ; CHECK-LABEL: @not_sdiv_sext_small_divisor(
     34 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
     35 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -128
     36 ; CHECK-NEXT:    ret i32 [[DIV]]
     37 ;
     38   %conv = sext i8 %x to i32
     39   %div = sdiv i32 %conv, -128
     40   ret i32 %div
     41 }
     42 
     43 define i32 @sdiv_zext_big_divisor(i8 %x) {
     44 ; CHECK-LABEL: @sdiv_zext_big_divisor(
     45 ; CHECK-NEXT:    ret i32 0
     46 ;
     47   %conv = zext i8 %x to i32
     48   %div = sdiv i32 %conv, 256
     49   ret i32 %div
     50 }
     51 
     52 define i32 @not_sdiv_zext_big_divisor(i8 %x) {
     53 ; CHECK-LABEL: @not_sdiv_zext_big_divisor(
     54 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
     55 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 255
     56 ; CHECK-NEXT:    ret i32 [[DIV]]
     57 ;
     58   %conv = zext i8 %x to i32
     59   %div = sdiv i32 %conv, 255
     60   ret i32 %div
     61 }
     62 
     63 define i32 @sdiv_zext_small_divisor(i8 %x) {
     64 ; CHECK-LABEL: @sdiv_zext_small_divisor(
     65 ; CHECK-NEXT:    ret i32 0
     66 ;
     67   %conv = zext i8 %x to i32
     68   %div = sdiv i32 %conv, -256
     69   ret i32 %div
     70 }
     71 
     72 define i32 @not_sdiv_zext_small_divisor(i8 %x) {
     73 ; CHECK-LABEL: @not_sdiv_zext_small_divisor(
     74 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
     75 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -255
     76 ; CHECK-NEXT:    ret i32 [[DIV]]
     77 ;
     78   %conv = zext i8 %x to i32
     79   %div = sdiv i32 %conv, -255
     80   ret i32 %div
     81 }
     82 
     83 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
     84 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(
     85 ; CHECK-NEXT:    ret i32 0
     86 ;
     87   %and = and i32 %x, 253
     88   %div = sdiv i32 %and, 254
     89   ret i32 %div
     90 }
     91 
     92 define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
     93 ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(
     94 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
     95 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], 253
     96 ; CHECK-NEXT:    ret i32 [[DIV]]
     97 ;
     98   %and = and i32 %x, 253
     99   %div = sdiv i32 %and, 253
    100   ret i32 %div
    101 }
    102 
    103 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
    104 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(
    105 ; CHECK-NEXT:    ret i32 0
    106 ;
    107   %and = and i32 %x, 253
    108   %div = sdiv i32 %and, -254
    109   ret i32 %div
    110 }
    111 
    112 define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
    113 ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(
    114 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
    115 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], -253
    116 ; CHECK-NEXT:    ret i32 [[DIV]]
    117 ;
    118   %and = and i32 %x, 253
    119   %div = sdiv i32 %and, -253
    120   ret i32 %div
    121 }
    122 
    123 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
    124 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(
    125 ; CHECK-NEXT:    ret i32 0
    126 ;
    127   %or = or i32 %x, -253
    128   %div = sdiv i32 %or, 254
    129   ret i32 %div
    130 }
    131 
    132 define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
    133 ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(
    134 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    135 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], 253
    136 ; CHECK-NEXT:    ret i32 [[DIV]]
    137 ;
    138   %or = or i32 %x, -253
    139   %div = sdiv i32 %or, 253
    140   ret i32 %div
    141 }
    142 
    143 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
    144 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(
    145 ; CHECK-NEXT:    ret i32 0
    146 ;
    147   %or = or i32 %x, -253
    148   %div = sdiv i32 %or, -254
    149   ret i32 %div
    150 }
    151 
    152 define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
    153 ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(
    154 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    155 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], -253
    156 ; CHECK-NEXT:    ret i32 [[DIV]]
    157 ;
    158   %or = or i32 %x, -253
    159   %div = sdiv i32 %or, -253
    160   ret i32 %div
    161 }
    162 
    163 define i32 @srem_sext_big_divisor(i8 %x) {
    164 ; CHECK-LABEL: @srem_sext_big_divisor(
    165 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
    166 ; CHECK-NEXT:    ret i32 [[CONV]]
    167 ;
    168   %conv = sext i8 %x to i32
    169   %rem = srem i32 %conv, 129
    170   ret i32 %rem
    171 }
    172 
    173 define i32 @not_srem_sext_big_divisor(i8 %x) {
    174 ; CHECK-LABEL: @not_srem_sext_big_divisor(
    175 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
    176 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 128
    177 ; CHECK-NEXT:    ret i32 [[REM]]
    178 ;
    179   %conv = sext i8 %x to i32
    180   %rem = srem i32 %conv, 128
    181   ret i32 %rem
    182 }
    183 
    184 define i32 @srem_sext_small_divisor(i8 %x) {
    185 ; CHECK-LABEL: @srem_sext_small_divisor(
    186 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
    187 ; CHECK-NEXT:    ret i32 [[CONV]]
    188 ;
    189   %conv = sext i8 %x to i32
    190   %rem = srem i32 %conv, -129
    191   ret i32 %rem
    192 }
    193 
    194 define i32 @not_srem_sext_small_divisor(i8 %x) {
    195 ; CHECK-LABEL: @not_srem_sext_small_divisor(
    196 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
    197 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -128
    198 ; CHECK-NEXT:    ret i32 [[REM]]
    199 ;
    200   %conv = sext i8 %x to i32
    201   %rem = srem i32 %conv, -128
    202   ret i32 %rem
    203 }
    204 
    205 define i32 @srem_zext_big_divisor(i8 %x) {
    206 ; CHECK-LABEL: @srem_zext_big_divisor(
    207 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
    208 ; CHECK-NEXT:    ret i32 [[CONV]]
    209 ;
    210   %conv = zext i8 %x to i32
    211   %rem = srem i32 %conv, 256
    212   ret i32 %rem
    213 }
    214 
    215 define i32 @not_srem_zext_big_divisor(i8 %x) {
    216 ; CHECK-LABEL: @not_srem_zext_big_divisor(
    217 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
    218 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 255
    219 ; CHECK-NEXT:    ret i32 [[REM]]
    220 ;
    221   %conv = zext i8 %x to i32
    222   %rem = srem i32 %conv, 255
    223   ret i32 %rem
    224 }
    225 
    226 define i32 @srem_zext_small_divisor(i8 %x) {
    227 ; CHECK-LABEL: @srem_zext_small_divisor(
    228 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
    229 ; CHECK-NEXT:    ret i32 [[CONV]]
    230 ;
    231   %conv = zext i8 %x to i32
    232   %rem = srem i32 %conv, -256
    233   ret i32 %rem
    234 }
    235 
    236 define i32 @not_srem_zext_small_divisor(i8 %x) {
    237 ; CHECK-LABEL: @not_srem_zext_small_divisor(
    238 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
    239 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -255
    240 ; CHECK-NEXT:    ret i32 [[REM]]
    241 ;
    242   %conv = zext i8 %x to i32
    243   %rem = srem i32 %conv, -255
    244   ret i32 %rem
    245 }
    246 
    247 define i32 @srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
    248 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_clear_bits(
    249 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
    250 ; CHECK-NEXT:    ret i32 [[AND]]
    251 ;
    252   %and = and i32 %x, 253
    253   %rem = srem i32 %and, 254
    254   ret i32 %rem
    255 }
    256 
    257 define i32 @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
    258 ; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits(
    259 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
    260 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], 253
    261 ; CHECK-NEXT:    ret i32 [[REM]]
    262 ;
    263   %and = and i32 %x, 253
    264   %rem = srem i32 %and, 253
    265   ret i32 %rem
    266 }
    267 
    268 define i32 @srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
    269 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_clear_bits(
    270 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
    271 ; CHECK-NEXT:    ret i32 [[AND]]
    272 ;
    273   %and = and i32 %x, 253
    274   %rem = srem i32 %and, -254
    275   ret i32 %rem
    276 }
    277 
    278 define i32 @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
    279 ; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits(
    280 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
    281 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], -253
    282 ; CHECK-NEXT:    ret i32 [[REM]]
    283 ;
    284   %and = and i32 %x, 253
    285   %rem = srem i32 %and, -253
    286   ret i32 %rem
    287 }
    288 
    289 define i32 @srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
    290 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_set_bits(
    291 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    292 ; CHECK-NEXT:    ret i32 [[OR]]
    293 ;
    294   %or = or i32 %x, -253
    295   %rem = srem i32 %or, 254
    296   ret i32 %rem
    297 }
    298 
    299 define i32 @not_srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
    300 ; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_set_bits(
    301 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    302 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], 253
    303 ; CHECK-NEXT:    ret i32 [[REM]]
    304 ;
    305   %or = or i32 %x, -253
    306   %rem = srem i32 %or, 253
    307   ret i32 %rem
    308 }
    309 
    310 define i32 @srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
    311 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_set_bits(
    312 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    313 ; CHECK-NEXT:    ret i32 [[OR]]
    314 ;
    315   %or = or i32 %x, -253
    316   %rem = srem i32 %or, -254
    317   ret i32 %rem
    318 }
    319 
    320 define i32 @not_srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
    321 ; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_set_bits(
    322 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
    323 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], -253
    324 ; CHECK-NEXT:    ret i32 [[REM]]
    325 ;
    326   %or = or i32 %x, -253
    327   %rem = srem i32 %or, -253
    328   ret i32 %rem
    329 }
    330 
    331 ; Make sure that we're handling the minimum signed constant correctly - can't fold this.
    332 
    333 define i16 @sdiv_min_dividend(i8 %x) {
    334 ; CHECK-LABEL: @sdiv_min_dividend(
    335 ; CHECK-NEXT:    [[Z:%.*]] = zext i8 %x to i16
    336 ; CHECK-NEXT:    [[D:%.*]] = sdiv i16 -32768, [[Z]]
    337 ; CHECK-NEXT:    ret i16 [[D]]
    338 ;
    339   %z = zext i8 %x to i16
    340   %d = sdiv i16 -32768, %z
    341   ret i16 %d
    342 }
    343 
    344 ; If the quotient is known to not be -32768, then this can fold.
    345 
    346 define i16 @sdiv_min_divisor(i8 %x) {
    347 ; CHECK-LABEL: @sdiv_min_divisor(
    348 ; CHECK-NEXT:    ret i16 0
    349 ;
    350   %z = zext i8 %x to i16
    351   %d = sdiv i16 %z, -32768
    352   ret i16 %d
    353 }
    354 
    355