Home | History | Annotate | Download | only in InstSimplify
      1 ; NOTE: Assertions have been autogenerated by update_test_checks.py
      2 ; RUN: opt -S %s -instsimplify | FileCheck %s
      3 
      4 ; A ==> A -> true
      5 define i1 @test(i32 %length.i, i32 %i) {
      6 ; CHECK-LABEL: @test(
      7 ; CHECK:         ret i1 true
      8 ;
      9   %var29 = icmp slt i32 %i, %length.i
     10   %res = icmp uge i1 %var29, %var29
     11   ret i1 %res
     12 }
     13 
     14 ; i +_{nsw} C_{>0} <s L ==> i <s L -> true
     15 define i1 @test2(i32 %length.i, i32 %i) {
     16 ; CHECK-LABEL: @test2(
     17 ; CHECK:         ret i1 true
     18 ;
     19   %iplus1 = add nsw i32 %i, 1
     20   %var29 = icmp slt i32 %i, %length.i
     21   %var30 = icmp slt i32 %iplus1, %length.i
     22   %res = icmp ule i1 %var30, %var29
     23   ret i1 %res
     24 }
     25 
     26 ; i + C_{>0} <s L ==> i <s L -> unknown without the nsw
     27 define i1 @test2_neg(i32 %length.i, i32 %i) {
     28 ; CHECK-LABEL: @test2_neg(
     29 ; CHECK:         [[IPLUS1:%.*]] = add i32 %i, 1
     30 ; CHECK-NEXT:    [[VAR29:%.*]] = icmp slt i32 %i, %length.i
     31 ; CHECK-NEXT:    [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i
     32 ; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[VAR30]], [[VAR29]]
     33 ; CHECK-NEXT:    ret i1 [[RES]]
     34 ;
     35   %iplus1 = add i32 %i, 1
     36   %var29 = icmp slt i32 %i, %length.i
     37   %var30 = icmp slt i32 %iplus1, %length.i
     38   %res = icmp ule i1 %var30, %var29
     39   ret i1 %res
     40 }
     41 
     42 ; sle is not implication
     43 define i1 @test2_neg2(i32 %length.i, i32 %i) {
     44 ; CHECK-LABEL: @test2_neg2(
     45 ; CHECK:         [[IPLUS1:%.*]] = add i32 %i, 1
     46 ; CHECK-NEXT:    [[VAR29:%.*]] = icmp slt i32 %i, %length.i
     47 ; CHECK-NEXT:    [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i
     48 ; CHECK-NEXT:    [[RES:%.*]] = icmp sle i1 [[VAR30]], [[VAR29]]
     49 ; CHECK-NEXT:    ret i1 [[RES]]
     50 ;
     51   %iplus1 = add i32 %i, 1
     52   %var29 = icmp slt i32 %i, %length.i
     53   %var30 = icmp slt i32 %iplus1, %length.i
     54   %res = icmp sle i1 %var30, %var29
     55   ret i1 %res
     56 }
     57 
     58 ; The binary operator has to be an add
     59 define i1 @test2_neg3(i32 %length.i, i32 %i) {
     60 ; CHECK-LABEL: @test2_neg3(
     61 ; CHECK:         [[IPLUS1:%.*]] = sub nsw i32 %i, 1
     62 ; CHECK-NEXT:    [[VAR29:%.*]] = icmp slt i32 %i, %length.i
     63 ; CHECK-NEXT:    [[VAR30:%.*]] = icmp slt i32 [[IPLUS1]], %length.i
     64 ; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[VAR30]], [[VAR29]]
     65 ; CHECK-NEXT:    ret i1 [[RES]]
     66 ;
     67   %iplus1 = sub nsw i32 %i, 1
     68   %var29 = icmp slt i32 %i, %length.i
     69   %var30 = icmp slt i32 %iplus1, %length.i
     70   %res = icmp ule i1 %var30, %var29
     71   ret i1 %res
     72 }
     73 
     74 ; i +_{nsw} C_{>0} <s L ==> i <s L -> true
     75 ; With an inverted conditional (ule B A rather than canonical ugt A B
     76 define i1 @test3(i32 %length.i, i32 %i) {
     77 ; CHECK-LABEL: @test3(
     78 ; CHECK:         ret i1 true
     79 ;
     80   %iplus1 = add nsw i32 %i, 1
     81   %var29 = icmp slt i32 %i, %length.i
     82   %var30 = icmp slt i32 %iplus1, %length.i
     83   %res = icmp uge i1 %var29, %var30
     84   ret i1 %res
     85 }
     86 
     87 ; i +_{nuw} C <u L ==> i <u L
     88 define i1 @test4(i32 %length.i, i32 %i) {
     89 ; CHECK-LABEL: @test4(
     90 ; CHECK:         ret i1 true
     91 ;
     92   %iplus1 = add nuw i32 %i, 1
     93   %var29 = icmp ult i32 %i, %length.i
     94   %var30 = icmp ult i32 %iplus1, %length.i
     95   %res = icmp ule i1 %var30, %var29
     96   ret i1 %res
     97 }
     98 
     99 ; A ==> A for vectors
    100 define <4 x i1> @test5(<4 x i1> %vec) {
    101 ; CHECK-LABEL: @test5(
    102 ; CHECK:         ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
    103 ;
    104   %res = icmp ule <4 x i1> %vec, %vec
    105   ret <4 x i1> %res
    106 }
    107 
    108 ; Don't crash on vector inputs - pr25040
    109 define <4 x i1> @test6(<4 x i1> %a, <4 x i1> %b) {
    110 ; CHECK-LABEL: @test6(
    111 ; CHECK:         [[RES:%.*]] = icmp ule <4 x i1> %a, %b
    112 ; CHECK-NEXT:    ret <4 x i1> [[RES]]
    113 ;
    114   %res = icmp ule <4 x i1> %a, %b
    115   ret <4 x i1> %res
    116 }
    117 
    118 ; i +_{nsw} 1 <s L  ==> i < L +_{nsw} 1
    119 define i1 @test7(i32 %length.i, i32 %i) {
    120 ; CHECK-LABEL: @test7(
    121 ; CHECK:         ret i1 true
    122 ;
    123   %iplus1 = add nsw i32 %i, 1
    124   %len.plus.one = add nsw i32 %length.i, 1
    125   %var29 = icmp slt i32 %i, %len.plus.one
    126   %var30 = icmp slt i32 %iplus1, %length.i
    127   %res = icmp ule i1 %var30, %var29
    128   ret i1 %res
    129 }
    130 
    131 ; i +_{nuw} 1 <u L  ==> i < L +_{nuw} 1
    132 define i1 @test8(i32 %length.i, i32 %i) {
    133 ; CHECK-LABEL: @test8(
    134 ; CHECK:         ret i1 true
    135 ;
    136   %iplus1 = add nuw i32 %i, 1
    137   %len.plus.one = add nuw i32 %length.i, 1
    138   %var29 = icmp ult i32 %i, %len.plus.one
    139   %var30 = icmp ult i32 %iplus1, %length.i
    140   %res = icmp ule i1 %var30, %var29
    141   ret i1 %res
    142 }
    143 
    144 ; i +_{nuw} C <u L ==> i < L, even if C is negative
    145 define i1 @test9(i32 %length.i, i32 %i) {
    146 ; CHECK-LABEL: @test9(
    147 ; CHECK:         ret i1 true
    148 ;
    149   %iplus1 = add nuw i32 %i, -100
    150   %var29 = icmp ult i32 %i, %length.i
    151   %var30 = icmp ult i32 %iplus1, %length.i
    152   %res = icmp ule i1 %var30, %var29
    153   ret i1 %res
    154 }
    155 
    156 define i1 @test10(i32 %length.i, i32 %x.full) {
    157 ; CHECK-LABEL: @test10(
    158 ; CHECK:         ret i1 true
    159 ;
    160   %x = and i32 %x.full, 4294901760  ;; 4294901760 == 0xffff0000
    161   %large = or i32 %x, 100
    162   %small = or i32 %x, 90
    163   %known = icmp ult i32 %large, %length.i
    164   %to.prove = icmp ult i32 %small, %length.i
    165   %res = icmp ule i1 %known, %to.prove
    166   ret i1 %res
    167 }
    168 
    169 define i1 @test11(i32 %length.i, i32 %x) {
    170 ; CHECK-LABEL: @test11(
    171 ; CHECK:         [[LARGE:%.*]] = or i32 %x, 100
    172 ; CHECK-NEXT:    [[SMALL:%.*]] = or i32 %x, 90
    173 ; CHECK-NEXT:    [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i
    174 ; CHECK-NEXT:    [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i
    175 ; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]]
    176 ; CHECK-NEXT:    ret i1 [[RES]]
    177 ;
    178   %large = or i32 %x, 100
    179   %small = or i32 %x, 90
    180   %known = icmp ult i32 %large, %length.i
    181   %to.prove = icmp ult i32 %small, %length.i
    182   %res = icmp ule i1 %known, %to.prove
    183   ret i1 %res
    184 }
    185 
    186 define i1 @test12(i32 %length.i, i32 %x.full) {
    187 ; CHECK-LABEL: @test12(
    188 ; CHECK:         [[X:%.*]] = and i32 [[X:%.*]].full, -65536
    189 ; CHECK-NEXT:    [[LARGE:%.*]] = or i32 [[X]], 65536
    190 ; CHECK-NEXT:    [[SMALL:%.*]] = or i32 [[X]], 90
    191 ; CHECK-NEXT:    [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i
    192 ; CHECK-NEXT:    [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i
    193 ; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]]
    194 ; CHECK-NEXT:    ret i1 [[RES]]
    195 ;
    196   %x = and i32 %x.full, 4294901760  ;; 4294901760 == 0xffff0000
    197   %large = or i32 %x, 65536 ;; 65536 == 0x00010000
    198   %small = or i32 %x, 90
    199   %known = icmp ult i32 %large, %length.i
    200   %to.prove = icmp ult i32 %small, %length.i
    201   %res = icmp ule i1 %known, %to.prove
    202   ret i1 %res
    203 }
    204 
    205 define i1 @test13(i32 %length.i, i32 %x) {
    206 ; CHECK-LABEL: @test13(
    207 ; CHECK:         ret i1 true
    208 ;
    209   %large = add nuw i32 %x, 100
    210   %small = add nuw i32 %x, 90
    211   %known = icmp ult i32 %large, %length.i
    212   %to.prove = icmp ult i32 %small, %length.i
    213   %res = icmp ule i1 %known, %to.prove
    214   ret i1 %res
    215 }
    216 
    217 define i1 @test14(i32 %length.i, i32 %x.full) {
    218 ; CHECK-LABEL: @test14(
    219 ; CHECK:         ret i1 true
    220 ;
    221   %x = and i32 %x.full, 4294905615  ;; 4294905615 == 0xffff0f0f
    222   %large = or i32 %x, 8224 ;; == 0x2020
    223   %small = or i32 %x, 4112 ;; == 0x1010
    224   %known = icmp ult i32 %large, %length.i
    225   %to.prove = icmp ult i32 %small, %length.i
    226   %res = icmp ule i1 %known, %to.prove
    227   ret i1 %res
    228 }
    229 
    230 define i1 @test15(i32 %length.i, i32 %x) {
    231 ; CHECK-LABEL: @test15(
    232 ; CHECK:         [[LARGE:%.*]] = add nuw i32 %x, 100
    233 ; CHECK-NEXT:    [[SMALL:%.*]] = add nuw i32 %x, 110
    234 ; CHECK-NEXT:    [[KNOWN:%.*]] = icmp ult i32 [[LARGE]], %length.i
    235 ; CHECK-NEXT:    [[TO_PROVE:%.*]] = icmp ult i32 [[SMALL]], %length.i
    236 ; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[KNOWN]], [[TO_PROVE]]
    237 ; CHECK-NEXT:    ret i1 [[RES]]
    238 ;
    239   %large = add nuw i32 %x, 100
    240   %small = add nuw i32 %x, 110
    241   %known = icmp ult i32 %large, %length.i
    242   %to.prove = icmp ult i32 %small, %length.i
    243   %res = icmp ule i1 %known, %to.prove
    244   ret i1 %res
    245 }
    246 
    247 ; X >=(s) Y == X ==> Y (i1 1 becomes -1 for reasoning)
    248 define i1 @test_sge(i32 %length.i, i32 %i) {
    249 ; CHECK-LABEL: @test_sge(
    250 ; CHECK:         ret i1 true
    251 ;
    252   %iplus1 = add nsw nuw i32 %i, 1
    253   %var29 = icmp ult i32 %i, %length.i
    254   %var30 = icmp ult i32 %iplus1, %length.i
    255   %res = icmp sge i1 %var30, %var29
    256   ret i1 %res
    257 }
    258