Home | History | Annotate | Download | only in InstSimplify
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
      3 
      4 define i32 @add1(i32 %x) {
      5 ; CHECK-LABEL: @add1(
      6 ; CHECK-NEXT:    ret i32 [[X:%.*]]
      7 ;
      8 ; (X + -1) + 1 -> X
      9   %l = add i32 %x, -1
     10   %r = add i32 %l, 1
     11   ret i32 %r
     12 }
     13 
     14 define i32 @and1(i32 %x, i32 %y) {
     15 ; CHECK-LABEL: @and1(
     16 ; CHECK-NEXT:    [[L:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
     17 ; CHECK-NEXT:    ret i32 [[L]]
     18 ;
     19 ; (X & Y) & X -> X & Y
     20   %l = and i32 %x, %y
     21   %r = and i32 %l, %x
     22   ret i32 %r
     23 }
     24 
     25 define i32 @and2(i32 %x, i32 %y) {
     26 ; CHECK-LABEL: @and2(
     27 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
     28 ; CHECK-NEXT:    ret i32 [[R]]
     29 ;
     30 ; X & (X & Y) -> X & Y
     31   %r = and i32 %x, %y
     32   %l = and i32 %x, %r
     33   ret i32 %l
     34 }
     35 
     36 define i32 @or1(i32 %x, i32 %y) {
     37 ; CHECK-LABEL: @or1(
     38 ; CHECK-NEXT:    [[L:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
     39 ; CHECK-NEXT:    ret i32 [[L]]
     40 ;
     41 ; (X | Y) | X -> X | Y
     42   %l = or i32 %x, %y
     43   %r = or i32 %l, %x
     44   ret i32 %r
     45 }
     46 
     47 define i32 @or2(i32 %x, i32 %y) {
     48 ; CHECK-LABEL: @or2(
     49 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
     50 ; CHECK-NEXT:    ret i32 [[R]]
     51 ;
     52 ; X | (X | Y) -> X | Y
     53   %r = or i32 %x, %y
     54   %l = or i32 %x, %r
     55   ret i32 %l
     56 }
     57 
     58 define i32 @xor1(i32 %x, i32 %y) {
     59 ; CHECK-LABEL: @xor1(
     60 ; CHECK-NEXT:    ret i32 [[Y:%.*]]
     61 ;
     62 ; (X ^ Y) ^ X = Y
     63   %l = xor i32 %x, %y
     64   %r = xor i32 %l, %x
     65   ret i32 %r
     66 }
     67 
     68 define i32 @xor2(i32 %x, i32 %y) {
     69 ; CHECK-LABEL: @xor2(
     70 ; CHECK-NEXT:    ret i32 [[Y:%.*]]
     71 ;
     72 ; X ^ (X ^ Y) = Y
     73   %r = xor i32 %x, %y
     74   %l = xor i32 %x, %r
     75   ret i32 %l
     76 }
     77 
     78 define i32 @sub1(i32 %x, i32 %y) {
     79 ; CHECK-LABEL: @sub1(
     80 ; CHECK-NEXT:    ret i32 [[Y:%.*]]
     81 ;
     82   %d = sub i32 %x, %y
     83   %r = sub i32 %x, %d
     84   ret i32 %r
     85 }
     86 
     87 define i32 @sub2(i32 %x) {
     88 ; CHECK-LABEL: @sub2(
     89 ; CHECK-NEXT:    ret i32 -1
     90 ;
     91 ; X - (X + 1) -> -1
     92   %xp1 = add i32 %x, 1
     93   %r = sub i32 %x, %xp1
     94   ret i32 %r
     95 }
     96 
     97 define i32 @sub3(i32 %x, i32 %y) {
     98 ; CHECK-LABEL: @sub3(
     99 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    100 ;
    101 ; ((X + 1) + Y) - (Y + 1) -> X
    102   %xp1 = add i32 %x, 1
    103   %lhs = add i32 %xp1, %y
    104   %rhs = add i32 %y, 1
    105   %r = sub i32 %lhs, %rhs
    106   ret i32 %r
    107 }
    108 
    109 ; (no overflow X * Y) / Y -> X
    110 
    111 define i32 @mulnsw_sdiv(i32 %x, i32 %y) {
    112 ; CHECK-LABEL: @mulnsw_sdiv(
    113 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    114 ;
    115   %mul = mul nsw i32 %x, %y
    116   %r = sdiv i32 %mul, %y
    117   ret i32 %r
    118 }
    119 
    120 define <2 x i32> @mulnsw_sdiv_commute(<2 x i32> %x, <2 x i32> %y) {
    121 ; CHECK-LABEL: @mulnsw_sdiv_commute(
    122 ; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
    123 ;
    124   %mul = mul nsw <2 x i32> %y, %x
    125   %r = sdiv <2 x i32> %mul, %y
    126   ret <2 x i32> %r
    127 }
    128 
    129 ; (no overflow X * Y) / Y -> X
    130 
    131 define <2 x i8> @mulnuw_udiv(<2 x i8> %x, <2 x i8> %y) {
    132 ; CHECK-LABEL: @mulnuw_udiv(
    133 ; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
    134 ;
    135   %mul = mul nuw <2 x i8> %x, %y
    136   %r = udiv <2 x i8> %mul, %y
    137   ret <2 x i8> %r
    138 }
    139 
    140 define i32 @mulnuw_udiv_commute(i32 %x, i32 %y) {
    141 ; CHECK-LABEL: @mulnuw_udiv_commute(
    142 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    143 ;
    144   %mul = mul nuw i32 %y, %x
    145   %r = udiv i32 %mul, %y
    146   ret i32 %r
    147 }
    148 
    149 ; (((X / Y) * Y) / Y) -> X / Y
    150 
    151 define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) {
    152 ; CHECK-LABEL: @sdiv_mul_sdiv(
    153 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]]
    154 ; CHECK-NEXT:    ret i32 [[DIV]]
    155 ;
    156   %div = sdiv i32 %x, %y
    157   %mul = mul i32 %div, %y
    158   %r = sdiv i32 %mul, %y
    159   ret i32 %r
    160 }
    161 
    162 define i32 @sdiv_mul_sdiv_commute(i32 %x, i32 %y) {
    163 ; CHECK-LABEL: @sdiv_mul_sdiv_commute(
    164 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]]
    165 ; CHECK-NEXT:    ret i32 [[DIV]]
    166 ;
    167   %div = sdiv i32 %x, %y
    168   %mul = mul i32 %y, %div
    169   %r = sdiv i32 %mul, %y
    170   ret i32 %r
    171 }
    172 
    173 ; (((X / Y) * Y) / Y) -> X / Y
    174 
    175 define i32 @udiv_mul_udiv(i32 %x, i32 %y) {
    176 ; CHECK-LABEL: @udiv_mul_udiv(
    177 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
    178 ; CHECK-NEXT:    ret i32 [[DIV]]
    179 ;
    180   %div = udiv i32 %x, %y
    181   %mul = mul i32 %div, %y
    182   %r = udiv i32 %mul, %y
    183   ret i32 %r
    184 }
    185 
    186 define i32 @udiv_mul_udiv_commute(i32 %x, i32 %y) {
    187 ; CHECK-LABEL: @udiv_mul_udiv_commute(
    188 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
    189 ; CHECK-NEXT:    ret i32 [[DIV]]
    190 ;
    191   %div = udiv i32 %x, %y
    192   %mul = mul i32 %y, %div
    193   %r = udiv i32 %mul, %y
    194   ret i32 %r
    195 }
    196 
    197 define i32 @sdiv3(i32 %x, i32 %y) {
    198 ; CHECK-LABEL: @sdiv3(
    199 ; CHECK-NEXT:    ret i32 0
    200 ;
    201 ; (X rem Y) / Y -> 0
    202   %rem = srem i32 %x, %y
    203   %div = sdiv i32 %rem, %y
    204   ret i32 %div
    205 }
    206 
    207 define i32 @sdiv4(i32 %x, i32 %y) {
    208 ; CHECK-LABEL: @sdiv4(
    209 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    210 ;
    211 ; (X / Y) * Y -> X if the division is exact
    212   %div = sdiv exact i32 %x, %y
    213   %mul = mul i32 %div, %y
    214   ret i32 %mul
    215 }
    216 
    217 define i32 @sdiv5(i32 %x, i32 %y) {
    218 ; CHECK-LABEL: @sdiv5(
    219 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    220 ;
    221 ; Y * (X / Y) -> X if the division is exact
    222   %div = sdiv exact i32 %x, %y
    223   %mul = mul i32 %y, %div
    224   ret i32 %mul
    225 }
    226 
    227 define i32 @udiv3(i32 %x, i32 %y) {
    228 ; CHECK-LABEL: @udiv3(
    229 ; CHECK-NEXT:    ret i32 0
    230 ;
    231 ; (X rem Y) / Y -> 0
    232   %rem = urem i32 %x, %y
    233   %div = udiv i32 %rem, %y
    234   ret i32 %div
    235 }
    236 
    237 define i32 @udiv4(i32 %x, i32 %y) {
    238 ; CHECK-LABEL: @udiv4(
    239 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    240 ;
    241 ; (X / Y) * Y -> X if the division is exact
    242   %div = udiv exact i32 %x, %y
    243   %mul = mul i32 %div, %y
    244   ret i32 %mul
    245 }
    246 
    247 define i32 @udiv5(i32 %x, i32 %y) {
    248 ; CHECK-LABEL: @udiv5(
    249 ; CHECK-NEXT:    ret i32 [[X:%.*]]
    250 ;
    251 ; Y * (X / Y) -> X if the division is exact
    252   %div = udiv exact i32 %x, %y
    253   %mul = mul i32 %y, %div
    254   ret i32 %mul
    255 }
    256 
    257 define i16 @trunc1(i32 %x) {
    258 ; CHECK-LABEL: @trunc1(
    259 ; CHECK-NEXT:    ret i16 1
    260 ;
    261   %y = add i32 %x, 1
    262   %tx = trunc i32 %x to i16
    263   %ty = trunc i32 %y to i16
    264   %d = sub i16 %ty, %tx
    265   ret i16 %d
    266 }
    267