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 i64 @pow2(i32 %x) {
      5 ; CHECK-LABEL: @pow2(
      6 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, %x
      7 ; CHECK-NEXT:    [[X2:%.*]] = and i32 %x, [[NEGX]]
      8 ; CHECK-NEXT:    [[E:%.*]] = zext i32 [[X2]] to i64
      9 ; CHECK-NEXT:    ret i64 [[E]]
     10 ;
     11   %negx = sub i32 0, %x
     12   %x2 = and i32 %x, %negx
     13   %e = zext i32 %x2 to i64
     14   %nege = sub i64 0, %e
     15   %e2 = and i64 %e, %nege
     16   ret i64 %e2
     17 }
     18 
     19 define i64 @pow2b(i32 %x) {
     20 ; CHECK-LABEL: @pow2b(
     21 ; CHECK-NEXT:    [[SH:%.*]] = shl i32 2, %x
     22 ; CHECK-NEXT:    [[E:%.*]] = zext i32 [[SH]] to i64
     23 ; CHECK-NEXT:    ret i64 [[E]]
     24 ;
     25   %sh = shl i32 2, %x
     26   %e = zext i32 %sh to i64
     27   %nege = sub i64 0, %e
     28   %e2 = and i64 %e, %nege
     29   ret i64 %e2
     30 }
     31 
     32 define i32 @sub_neg_nuw(i32 %x, i32 %y) {
     33 ; CHECK-LABEL: @sub_neg_nuw(
     34 ; CHECK-NEXT:    ret i32 %x
     35 ;
     36   %neg = sub nuw i32 0, %y
     37   %sub = sub i32 %x, %neg
     38   ret i32 %sub
     39 }
     40 
     41 define i1 @and_of_icmps0(i32 %b) {
     42 ; CHECK-LABEL: @and_of_icmps0(
     43 ; CHECK-NEXT:    ret i1 false
     44 ;
     45   %1 = add i32 %b, 2
     46   %2 = icmp ult i32 %1, 4
     47   %cmp3 = icmp sgt i32 %b, 2
     48   %cmp = and i1 %2, %cmp3
     49   ret i1 %cmp
     50 }
     51 
     52 define i1 @and_of_icmps1(i32 %b) {
     53 ; CHECK-LABEL: @and_of_icmps1(
     54 ; CHECK-NEXT:    ret i1 false
     55 ;
     56   %1 = add nsw i32 %b, 2
     57   %2 = icmp slt i32 %1, 4
     58   %cmp3 = icmp sgt i32 %b, 2
     59   %cmp = and i1 %2, %cmp3
     60   ret i1 %cmp
     61 }
     62 
     63 define i1 @and_of_icmps2(i32 %b) {
     64 ; CHECK-LABEL: @and_of_icmps2(
     65 ; CHECK-NEXT:    ret i1 false
     66 ;
     67   %1 = add i32 %b, 2
     68   %2 = icmp ule i32 %1, 3
     69   %cmp3 = icmp sgt i32 %b, 2
     70   %cmp = and i1 %2, %cmp3
     71   ret i1 %cmp
     72 }
     73 
     74 define i1 @and_of_icmps3(i32 %b) {
     75 ; CHECK-LABEL: @and_of_icmps3(
     76 ; CHECK-NEXT:    ret i1 false
     77 ;
     78   %1 = add nsw i32 %b, 2
     79   %2 = icmp sle i32 %1, 3
     80   %cmp3 = icmp sgt i32 %b, 2
     81   %cmp = and i1 %2, %cmp3
     82   ret i1 %cmp
     83 }
     84 
     85 define i1 @and_of_icmps4(i32 %b) {
     86 ; CHECK-LABEL: @and_of_icmps4(
     87 ; CHECK-NEXT:    ret i1 false
     88 ;
     89   %1 = add nuw i32 %b, 2
     90   %2 = icmp ult i32 %1, 4
     91   %cmp3 = icmp ugt i32 %b, 2
     92   %cmp = and i1 %2, %cmp3
     93   ret i1 %cmp
     94 }
     95 
     96 define i1 @and_of_icmps5(i32 %b) {
     97 ; CHECK-LABEL: @and_of_icmps5(
     98 ; CHECK-NEXT:    ret i1 false
     99 ;
    100   %1 = add nuw i32 %b, 2
    101   %2 = icmp ule i32 %1, 3
    102   %cmp3 = icmp ugt i32 %b, 2
    103   %cmp = and i1 %2, %cmp3
    104   ret i1 %cmp
    105 }
    106 
    107 define i1 @or_of_icmps0(i32 %b) {
    108 ; CHECK-LABEL: @or_of_icmps0(
    109 ; CHECK-NEXT:    ret i1 true
    110 ;
    111   %1 = add i32 %b, 2
    112   %2 = icmp uge i32 %1, 4
    113   %cmp3 = icmp sle i32 %b, 2
    114   %cmp = or i1 %2, %cmp3
    115   ret i1 %cmp
    116 }
    117 
    118 define i1 @or_of_icmps1(i32 %b) {
    119 ; CHECK-LABEL: @or_of_icmps1(
    120 ; CHECK-NEXT:    ret i1 true
    121 ;
    122   %1 = add nsw i32 %b, 2
    123   %2 = icmp sge i32 %1, 4
    124   %cmp3 = icmp sle i32 %b, 2
    125   %cmp = or i1 %2, %cmp3
    126   ret i1 %cmp
    127 }
    128 
    129 define i1 @or_of_icmps2(i32 %b) {
    130 ; CHECK-LABEL: @or_of_icmps2(
    131 ; CHECK-NEXT:    ret i1 true
    132 ;
    133   %1 = add i32 %b, 2
    134   %2 = icmp ugt i32 %1, 3
    135   %cmp3 = icmp sle i32 %b, 2
    136   %cmp = or i1 %2, %cmp3
    137   ret i1 %cmp
    138 }
    139 
    140 define i1 @or_of_icmps3(i32 %b) {
    141 ; CHECK-LABEL: @or_of_icmps3(
    142 ; CHECK-NEXT:    ret i1 true
    143 ;
    144   %1 = add nsw i32 %b, 2
    145   %2 = icmp sgt i32 %1, 3
    146   %cmp3 = icmp sle i32 %b, 2
    147   %cmp = or i1 %2, %cmp3
    148   ret i1 %cmp
    149 }
    150 
    151 define i1 @or_of_icmps4(i32 %b) {
    152 ; CHECK-LABEL: @or_of_icmps4(
    153 ; CHECK-NEXT:    ret i1 true
    154 ;
    155   %1 = add nuw i32 %b, 2
    156   %2 = icmp uge i32 %1, 4
    157   %cmp3 = icmp ule i32 %b, 2
    158   %cmp = or i1 %2, %cmp3
    159   ret i1 %cmp
    160 }
    161 
    162 define i1 @or_of_icmps5(i32 %b) {
    163 ; CHECK-LABEL: @or_of_icmps5(
    164 ; CHECK-NEXT:    ret i1 true
    165 ;
    166   %1 = add nuw i32 %b, 2
    167   %2 = icmp ugt i32 %1, 3
    168   %cmp3 = icmp ule i32 %b, 2
    169   %cmp = or i1 %2, %cmp3
    170   ret i1 %cmp
    171 }
    172 
    173 define i32 @neg_nuw(i32 %x) {
    174 ; CHECK-LABEL: @neg_nuw(
    175 ; CHECK-NEXT:    ret i32 0
    176 ;
    177   %neg = sub nuw i32 0, %x
    178   ret i32 %neg
    179 }
    180 
    181 define i1 @and_icmp1(i32 %x, i32 %y) {
    182 ; CHECK-LABEL: @and_icmp1(
    183 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %x, %y
    184 ; CHECK-NEXT:    ret i1 [[TMP1]]
    185 ;
    186   %1 = icmp ult i32 %x, %y
    187   %2 = icmp ne i32 %y, 0
    188   %3 = and i1 %1, %2
    189   ret i1 %3
    190 }
    191 
    192 define i1 @and_icmp2(i32 %x, i32 %y) {
    193 ; CHECK-LABEL: @and_icmp2(
    194 ; CHECK-NEXT:    ret i1 false
    195 ;
    196   %1 = icmp ult i32 %x, %y
    197   %2 = icmp eq i32 %y, 0
    198   %3 = and i1 %1, %2
    199   ret i1 %3
    200 }
    201 
    202 define i1 @or_icmp1(i32 %x, i32 %y) {
    203 ; CHECK-LABEL: @or_icmp1(
    204 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 %y, 0
    205 ; CHECK-NEXT:    ret i1 [[TMP1]]
    206 ;
    207   %1 = icmp ult i32 %x, %y
    208   %2 = icmp ne i32 %y, 0
    209   %3 = or i1 %1, %2
    210   ret i1 %3
    211 }
    212 
    213 define i1 @or_icmp2(i32 %x, i32 %y) {
    214 ; CHECK-LABEL: @or_icmp2(
    215 ; CHECK-NEXT:    ret i1 true
    216 ;
    217   %1 = icmp uge i32 %x, %y
    218   %2 = icmp ne i32 %y, 0
    219   %3 = or i1 %1, %2
    220   ret i1 %3
    221 }
    222 
    223 define i1 @or_icmp3(i32 %x, i32 %y) {
    224 ; CHECK-LABEL: @or_icmp3(
    225 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i32 %x, %y
    226 ; CHECK-NEXT:    ret i1 [[TMP1]]
    227 ;
    228   %1 = icmp uge i32 %x, %y
    229   %2 = icmp eq i32 %y, 0
    230   %3 = or i1 %1, %2
    231   ret i1 %3
    232 }
    233 
    234 define i1 @disjoint_cmps(i32 %A) {
    235 ; CHECK-LABEL: @disjoint_cmps(
    236 ; CHECK-NEXT:    ret i1 false
    237 ;
    238   %B = icmp eq i32 %A, 1
    239   %C = icmp sge i32 %A, 3
    240   %D = and i1 %B, %C
    241   ret i1 %D
    242 }
    243 
    244 define i1 @disjoint_cmps2(i32 %X) {
    245 ; CHECK-LABEL: @disjoint_cmps2(
    246 ; CHECK-NEXT:    ret i1 false
    247 ;
    248   %a = icmp ult i32 %X, 31
    249   %b = icmp slt i32 %X, 0
    250   %c = and i1 %a, %b
    251   ret i1 %c
    252 }
    253 
    254 ; PR27869 - Look through casts to eliminate cmps and bitwise logic.
    255 
    256 define i32 @and_of_zexted_icmps(i32 %i) {
    257 ; CHECK-LABEL: @and_of_zexted_icmps(
    258 ; CHECK-NEXT:    ret i32 0
    259 ;
    260   %cmp0 = icmp eq i32 %i, 0
    261   %conv0 = zext i1 %cmp0 to i32
    262   %cmp1 = icmp ugt i32 %i, 4
    263   %conv1 = zext i1 %cmp1 to i32
    264   %and = and i32 %conv0, %conv1
    265   ret i32 %and
    266 }
    267 
    268 ; Make sure vectors work too.
    269 
    270 define <4 x i32> @and_of_zexted_icmps_vec(<4 x i32> %i) {
    271 ; CHECK-LABEL: @and_of_zexted_icmps_vec(
    272 ; CHECK-NEXT:    ret <4 x i32> zeroinitializer
    273 ;
    274   %cmp0 = icmp eq <4 x i32> %i, zeroinitializer
    275   %conv0 = zext <4 x i1> %cmp0 to <4 x i32>
    276   %cmp1 = icmp slt <4 x i32> %i, zeroinitializer
    277   %conv1 = zext <4 x i1> %cmp1 to <4 x i32>
    278   %and = and <4 x i32> %conv0, %conv1
    279   ret <4 x i32> %and
    280 }
    281 
    282 ; Try a different cast and weird types.
    283 
    284 define i5 @and_of_sexted_icmps(i3 %i) {
    285 ; CHECK-LABEL: @and_of_sexted_icmps(
    286 ; CHECK-NEXT:    ret i5 0
    287 ;
    288   %cmp0 = icmp eq i3 %i, 0
    289   %conv0 = sext i1 %cmp0 to i5
    290   %cmp1 = icmp ugt i3 %i, 1
    291   %conv1 = sext i1 %cmp1 to i5
    292   %and = and i5 %conv0, %conv1
    293   ret i5 %and
    294 }
    295 
    296 ; Try a different cast and weird vector types.
    297 
    298 define i3 @and_of_bitcast_icmps_vec(<3 x i65> %i) {
    299 ; CHECK-LABEL: @and_of_bitcast_icmps_vec(
    300 ; CHECK-NEXT:    ret i3 0
    301 ;
    302   %cmp0 = icmp sgt <3 x i65> %i, zeroinitializer
    303   %conv0 = bitcast <3 x i1> %cmp0 to i3
    304   %cmp1 = icmp slt <3 x i65> %i, zeroinitializer
    305   %conv1 = bitcast <3 x i1> %cmp1 to i3
    306   %and = and i3 %conv0, %conv1
    307   ret i3 %and
    308 }
    309 
    310 ; We can't do this if the casts are different.
    311 
    312 define i16 @and_of_different_cast_icmps(i8 %i) {
    313 ; CHECK-LABEL: @and_of_different_cast_icmps(
    314 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i8 %i, 0
    315 ; CHECK-NEXT:    [[CONV0:%.*]] = zext i1 [[CMP0]] to i16
    316 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 %i, 1
    317 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i1 [[CMP1]] to i16
    318 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[CONV0]], [[CONV1]]
    319 ; CHECK-NEXT:    ret i16 [[AND]]
    320 ;
    321   %cmp0 = icmp eq i8 %i, 0
    322   %conv0 = zext i1 %cmp0 to i16
    323   %cmp1 = icmp eq i8 %i, 1
    324   %conv1 = sext i1 %cmp1 to i16
    325   %and = and i16 %conv0, %conv1
    326   ret i16 %and
    327 }
    328 
    329 define <2 x i3> @and_of_different_cast_icmps_vec(<2 x i8> %i, <2 x i16> %j) {
    330 ; CHECK-LABEL: @and_of_different_cast_icmps_vec(
    331 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq <2 x i8> %i, zeroinitializer
    332 ; CHECK-NEXT:    [[CONV0:%.*]] = zext <2 x i1> [[CMP0]] to <2 x i3>
    333 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt <2 x i16> %j, <i16 1, i16 1>
    334 ; CHECK-NEXT:    [[CONV1:%.*]] = zext <2 x i1> [[CMP1]] to <2 x i3>
    335 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i3> [[CONV0]], [[CONV1]]
    336 ; CHECK-NEXT:    ret <2 x i3> [[AND]]
    337 ;
    338   %cmp0 = icmp eq <2 x i8> %i, zeroinitializer
    339   %conv0 = zext <2 x i1> %cmp0 to <2 x i3>
    340   %cmp1 = icmp ugt <2 x i16> %j, <i16 1, i16 1>
    341   %conv1 = zext <2 x i1> %cmp1 to <2 x i3>
    342   %and = and <2 x i3> %conv0, %conv1
    343   ret <2 x i3> %and
    344 }
    345 
    346