Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -instcombine -S | FileCheck %s
      3 
      4 ; https://bugs.llvm.org/show_bug.cgi?id=36950
      5 
      6 ; These all should be just and+icmp, there should be no select.
      7 
      8 define i32 @and_lshr_and(i32 %arg) {
      9 ; CHECK-LABEL: @and_lshr_and(
     10 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3
     11 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
     12 ; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
     13 ; CHECK-NEXT:    ret i32 [[TMP4]]
     14 ;
     15   %tmp = and i32 %arg, 1
     16   %tmp1 = icmp eq i32 %tmp, 0
     17   %tmp2 = lshr i32 %arg, 1
     18   %tmp3 = and i32 %tmp2, 1
     19   %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1
     20   ret i32 %tmp4
     21 }
     22 
     23 define <2 x i32> @and_lshr_and_splatvec(<2 x i32> %arg) {
     24 ; CHECK-LABEL: @and_lshr_and_splatvec(
     25 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3>
     26 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
     27 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
     28 ; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
     29 ;
     30   %tmp = and <2 x i32> %arg, <i32 1, i32 1>
     31   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
     32   %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1>
     33   %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1>
     34   %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1>
     35   ret <2 x i32> %tmp4
     36 }
     37 
     38 define <2 x i32> @and_lshr_and_vec_v0(<2 x i32> %arg) {
     39 ; CHECK-LABEL: @and_lshr_and_vec_v0(
     40 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 6>
     41 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
     42 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
     43 ; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
     44 ;
     45   %tmp = and <2 x i32> %arg, <i32 1, i32 4> ; mask is not splat
     46   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
     47   %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1>
     48   %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1>
     49   %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1>
     50   ret <2 x i32> %tmp4
     51 }
     52 
     53 define <2 x i32> @and_lshr_and_vec_v1(<2 x i32> %arg) {
     54 ; CHECK-LABEL: @and_lshr_and_vec_v1(
     55 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 5>
     56 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
     57 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
     58 ; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
     59 ;
     60   %tmp = and <2 x i32> %arg, <i32 1, i32 1>
     61   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
     62   %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat
     63   %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1>
     64   %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1>
     65   ret <2 x i32> %tmp4
     66 }
     67 
     68 define <2 x i32> @and_lshr_and_vec_v2(<2 x i32> %arg) {
     69 ; CHECK-LABEL: @and_lshr_and_vec_v2(
     70 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 12, i32 3>
     71 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
     72 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
     73 ; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
     74 ;
     75   %tmp = and <2 x i32> %arg, <i32 8, i32 1> ; mask is not splat
     76   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
     77   %tmp2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat
     78   %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1>
     79   %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1>
     80   ret <2 x i32> %tmp4
     81 }
     82 
     83 define <3 x i32> @and_lshr_and_vec_undef(<3 x i32> %arg) {
     84 ; CHECK-LABEL: @and_lshr_and_vec_undef(
     85 ; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 undef, i32 3>
     86 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer
     87 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>
     88 ; CHECK-NEXT:    ret <3 x i32> [[TMP4]]
     89 ;
     90   %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1>
     91   %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
     92   %tmp2 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1>
     93   %tmp3 = and <3 x i32> %tmp2, <i32 1, i32 undef, i32 1>
     94   %tmp4 = select <3 x i1> %tmp1, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1>
     95   ret <3 x i32> %tmp4
     96 }
     97 
     98 define i32 @and_and(i32 %arg) {
     99 ; CHECK-LABEL: @and_and(
    100 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3
    101 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
    102 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
    103 ; CHECK-NEXT:    ret i32 [[TMP3]]
    104 ;
    105   %tmp = and i32 %arg, 2
    106   %tmp1 = icmp eq i32 %tmp, 0
    107   %tmp2 = and i32 %arg, 1
    108   %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1
    109   ret i32 %tmp3
    110 }
    111 
    112 define <2 x i32> @and_and_splatvec(<2 x i32> %arg) {
    113 ; CHECK-LABEL: @and_and_splatvec(
    114 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3>
    115 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
    116 ; CHECK-NEXT:    [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
    117 ; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
    118 ;
    119   %tmp = and <2 x i32> %arg, <i32 2, i32 2>
    120   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
    121   %tmp2 = and <2 x i32> %arg, <i32 1, i32 1>
    122   %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1>
    123   ret <2 x i32> %tmp3
    124 }
    125 
    126 define <2 x i32> @and_and_vec(<2 x i32> %arg) {
    127 ; CHECK-LABEL: @and_and_vec(
    128 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 7, i32 3>
    129 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
    130 ; CHECK-NEXT:    [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
    131 ; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
    132 ;
    133   %tmp = and <2 x i32> %arg, <i32 6, i32 2> ; mask is not splat
    134   %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer
    135   %tmp2 = and <2 x i32> %arg, <i32 1, i32 1>
    136   %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1>
    137   ret <2 x i32> %tmp3
    138 }
    139 
    140 define <3 x i32> @and_and_vec_undef(<3 x i32> %arg) {
    141 ; CHECK-LABEL: @and_and_vec_undef(
    142 ; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 -1, i32 3>
    143 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer
    144 ; CHECK-NEXT:    [[TMP3:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>
    145 ; CHECK-NEXT:    ret <3 x i32> [[TMP3]]
    146 ;
    147   %tmp = and <3 x i32> %arg, <i32 2, i32 undef, i32 2>
    148   %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
    149   %tmp2 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1>
    150   %tmp3 = select <3 x i1> %tmp1, <3 x i32> %tmp2, <3 x i32> <i32 1, i32 undef, i32 1>
    151   ret <3 x i32> %tmp3
    152 }
    153 
    154 ; ============================================================================ ;
    155 ; Mask can be a variable, too.
    156 ; ============================================================================ ;
    157 
    158 define i32 @f_var0(i32 %arg, i32 %arg1) {
    159 ; CHECK-LABEL: @f_var0(
    160 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2
    161 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]]
    162 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
    163 ; CHECK-NEXT:    [[TMP5:%.*]] = zext i1 [[TMP3]] to i32
    164 ; CHECK-NEXT:    ret i32 [[TMP5]]
    165 ;
    166   %tmp = and i32 %arg, %arg1
    167   %tmp2 = icmp eq i32 %tmp, 0
    168   %tmp3 = lshr i32 %arg, 1
    169   %tmp4 = and i32 %tmp3, 1
    170   %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1
    171   ret i32 %tmp5
    172 }
    173 
    174 ; Should be exactly as the previous one
    175 define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) {
    176 ; CHECK-LABEL: @f_var0_commutative_and(
    177 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2
    178 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]]
    179 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
    180 ; CHECK-NEXT:    [[TMP5:%.*]] = zext i1 [[TMP3]] to i32
    181 ; CHECK-NEXT:    ret i32 [[TMP5]]
    182 ;
    183   %tmp = and i32 %arg1, %arg ; in different order
    184   %tmp2 = icmp eq i32 %tmp, 0
    185   %tmp3 = lshr i32 %arg, 1
    186   %tmp4 = and i32 %tmp3, 1
    187   %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1
    188   ret i32 %tmp5
    189 }
    190 
    191 define <2 x i32> @f_var0_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {
    192 ; CHECK-LABEL: @f_var0_splatvec(
    193 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 2>
    194 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]]
    195 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
    196 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
    197 ; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
    198 ;
    199   %tmp = and <2 x i32> %arg, %arg1
    200   %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer
    201   %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 1>
    202   %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1>
    203   %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1>
    204   ret <2 x i32> %tmp5
    205 }
    206 
    207 define <2 x i32> @f_var0_vec(<2 x i32> %arg, <2 x i32> %arg1) {
    208 ; CHECK-LABEL: @f_var0_vec(
    209 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 4>
    210 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]]
    211 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
    212 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
    213 ; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
    214 ;
    215   %tmp = and <2 x i32> %arg, %arg1
    216   %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer
    217   %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat
    218   %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1>
    219   %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1>
    220   ret <2 x i32> %tmp5
    221 }
    222 
    223 define <3 x i32> @f_var0_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) {
    224 ; CHECK-LABEL: @f_var0_vec_undef(
    225 ; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 2, i32 undef, i32 2>
    226 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]]
    227 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
    228 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>
    229 ; CHECK-NEXT:    ret <3 x i32> [[TMP5]]
    230 ;
    231   %tmp = and <3 x i32> %arg, %arg1
    232   %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
    233   %tmp3 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1>
    234   %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1>
    235   %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1>
    236   ret <3 x i32> %tmp5
    237 }
    238 
    239 define i32 @f_var1(i32 %arg, i32 %arg1) {
    240 ; CHECK-LABEL: @f_var1(
    241 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1
    242 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]]
    243 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
    244 ; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
    245 ; CHECK-NEXT:    ret i32 [[TMP4]]
    246 ;
    247   %tmp = and i32 %arg, %arg1
    248   %tmp2 = icmp eq i32 %tmp, 0
    249   %tmp3 = and i32 %arg, 1
    250   %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1
    251   ret i32 %tmp4
    252 }
    253 
    254 ; Should be exactly as the previous one
    255 define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) {
    256 ; CHECK-LABEL: @f_var1_commutative_and(
    257 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1
    258 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]]
    259 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
    260 ; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
    261 ; CHECK-NEXT:    ret i32 [[TMP4]]
    262 ;
    263   %tmp = and i32 %arg1, %arg ; in different order
    264   %tmp2 = icmp eq i32 %tmp, 0
    265   %tmp3 = and i32 %arg, 1
    266   %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1
    267   ret i32 %tmp4
    268 }
    269 
    270 define <2 x i32> @f_var1_vec(<2 x i32> %arg, <2 x i32> %arg1) {
    271 ; CHECK-LABEL: @f_var1_vec(
    272 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 1, i32 1>
    273 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]]
    274 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
    275 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
    276 ; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
    277 ;
    278   %tmp = and <2 x i32> %arg, %arg1
    279   %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer
    280   %tmp3 = and <2 x i32> %arg, <i32 1, i32 1>
    281   %tmp4 = select <2 x i1> %tmp2, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1>
    282   ret <2 x i32> %tmp4
    283 }
    284 
    285 define <3 x i32> @f_var1_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) {
    286 ; CHECK-LABEL: @f_var1_vec_undef(
    287 ; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 1, i32 1, i32 1>
    288 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]]
    289 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
    290 ; CHECK-NEXT:    [[TMP4:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>
    291 ; CHECK-NEXT:    ret <3 x i32> [[TMP4]]
    292 ;
    293   %tmp = and <3 x i32> %arg, %arg1
    294   %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
    295   %tmp3 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1>
    296   %tmp4 = select <3 x i1> %tmp2, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1>
    297   ret <3 x i32> %tmp4
    298 }
    299 
    300 ; ============================================================================ ;
    301 ; Shift can be a variable, too.
    302 ; ============================================================================ ;
    303 
    304 define i32 @f_var2(i32 %arg, i32 %arg1) {
    305 ; CHECK-LABEL: @f_var2(
    306 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 1, [[ARG1:%.*]]
    307 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], 1
    308 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]]
    309 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
    310 ; CHECK-NEXT:    [[TMP5:%.*]] = zext i1 [[TMP4]] to i32
    311 ; CHECK-NEXT:    ret i32 [[TMP5]]
    312 ;
    313   %tmp = and i32 %arg, 1
    314   %tmp2 = icmp eq i32 %tmp, 0
    315   %tmp3 = lshr i32 %arg, %arg1
    316   %tmp4 = and i32 %tmp3, 1
    317   %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1
    318   ret i32 %tmp5
    319 }
    320 
    321 define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {
    322 ; CHECK-LABEL: @f_var2_splatvec(
    323 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]]
    324 ; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 1, i32 1>
    325 ; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]]
    326 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer
    327 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32>
    328 ; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
    329 ;
    330   %tmp = and <2 x i32> %arg, <i32 1, i32 1>
    331   %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer
    332   %tmp3 = lshr <2 x i32> %arg, %arg1
    333   %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1>
    334   %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1>
    335   ret <2 x i32> %tmp5
    336 }
    337 
    338 define <2 x i32> @f_var2_vec(<2 x i32> %arg, <2 x i32> %arg1) {
    339 ; CHECK-LABEL: @f_var2_vec(
    340 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]]
    341 ; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 2, i32 1>
    342 ; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]]
    343 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer
    344 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32>
    345 ; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
    346 ;
    347   %tmp = and <2 x i32> %arg, <i32 2, i32 1>; mask is not splat
    348   %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer
    349   %tmp3 = lshr <2 x i32> %arg, %arg1
    350   %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1>
    351   %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1>
    352   ret <2 x i32> %tmp5
    353 }
    354 
    355 define <3 x i32> @f_var2_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) {
    356 ; CHECK-LABEL: @f_var2_vec_undef(
    357 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG1:%.*]]
    358 ; CHECK-NEXT:    [[TMP2:%.*]] = or <3 x i32> [[TMP1]], <i32 1, i32 undef, i32 1>
    359 ; CHECK-NEXT:    [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]]
    360 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer
    361 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32>
    362 ; CHECK-NEXT:    ret <3 x i32> [[TMP5]]
    363 ;
    364   %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1>
    365   %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
    366   %tmp3 = lshr <3 x i32> %arg, %arg1
    367   %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1>
    368   %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1>
    369   ret <3 x i32> %tmp5
    370 }
    371 
    372 ; ============================================================================ ;
    373 ; The worst case: both Mask and Shift are variables
    374 ; ============================================================================ ;
    375 
    376 define i32 @f_var3(i32 %arg, i32 %arg1, i32 %arg2) {
    377 ; CHECK-LABEL: @f_var3(
    378 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]]
    379 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]]
    380 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]]
    381 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
    382 ; CHECK-NEXT:    [[TMP6:%.*]] = zext i1 [[TMP4]] to i32
    383 ; CHECK-NEXT:    ret i32 [[TMP6]]
    384 ;
    385   %tmp = and i32 %arg, %arg1
    386   %tmp3 = icmp eq i32 %tmp, 0
    387   %tmp4 = lshr i32 %arg, %arg2
    388   %tmp5 = and i32 %tmp4, 1
    389   %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1
    390   ret i32 %tmp6
    391 }
    392 
    393 ; Should be exactly as the previous one
    394 define i32 @f_var3_commutative_and(i32 %arg, i32 %arg1, i32 %arg2) {
    395 ; CHECK-LABEL: @f_var3_commutative_and(
    396 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]]
    397 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]]
    398 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]]
    399 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
    400 ; CHECK-NEXT:    [[TMP6:%.*]] = zext i1 [[TMP4]] to i32
    401 ; CHECK-NEXT:    ret i32 [[TMP6]]
    402 ;
    403   %tmp = and i32 %arg1, %arg ; in different order
    404   %tmp3 = icmp eq i32 %tmp, 0
    405   %tmp4 = lshr i32 %arg, %arg2
    406   %tmp5 = and i32 %tmp4, 1
    407   %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1
    408   ret i32 %tmp6
    409 }
    410 
    411 define <2 x i32> @f_var3_splatvec(<2 x i32> %arg, <2 x i32> %arg1, <2 x i32> %arg2) {
    412 ; CHECK-LABEL: @f_var3_splatvec(
    413 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG2:%.*]]
    414 ; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[TMP1]], [[ARG1:%.*]]
    415 ; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]]
    416 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer
    417 ; CHECK-NEXT:    [[TMP6:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32>
    418 ; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
    419 ;
    420   %tmp = and <2 x i32> %arg, %arg1
    421   %tmp3 = icmp eq <2 x i32> %tmp, zeroinitializer
    422   %tmp4 = lshr <2 x i32> %arg, %arg2
    423   %tmp5 = and <2 x i32> %tmp4, <i32 1, i32 1>
    424   %tmp6 = select <2 x i1> %tmp3, <2 x i32> %tmp5, <2 x i32> <i32 1, i32 1>
    425   ret <2 x i32> %tmp6
    426 }
    427 
    428 define <3 x i32> @f_var3_vec_undef(<3 x i32> %arg, <3 x i32> %arg1, <3 x i32> %arg2) {
    429 ; CHECK-LABEL: @f_var3_vec_undef(
    430 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG2:%.*]]
    431 ; CHECK-NEXT:    [[TMP2:%.*]] = or <3 x i32> [[TMP1]], [[ARG1:%.*]]
    432 ; CHECK-NEXT:    [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]]
    433 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer
    434 ; CHECK-NEXT:    [[TMP6:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32>
    435 ; CHECK-NEXT:    ret <3 x i32> [[TMP6]]
    436 ;
    437   %tmp = and <3 x i32> %arg, %arg1
    438   %tmp3 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0>
    439   %tmp4 = lshr <3 x i32> %arg, %arg2
    440   %tmp5 = and <3 x i32> %tmp4, <i32 1, i32 undef, i32 1>
    441   %tmp6 = select <3 x i1> %tmp3, <3 x i32> %tmp5, <3 x i32> <i32 1, i32 undef, i32 1>
    442   ret <3 x i32> %tmp6
    443 }
    444 
    445 ; ============================================================================ ;
    446 ; Negative tests. Should not be folded.
    447 ; ============================================================================ ;
    448 
    449 ; One use only.
    450 
    451 declare void @use32(i32)
    452 
    453 declare void @use1(i1)
    454 
    455 define i32 @n_var0_oneuse(i32 %arg, i32 %arg1, i32 %arg2) {
    456 ; CHECK-LABEL: @n_var0_oneuse(
    457 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]
    458 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP]], 0
    459 ; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]
    460 ; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
    461 ; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 1
    462 ; CHECK-NEXT:    call void @use32(i32 [[TMP]])
    463 ; CHECK-NEXT:    call void @use1(i1 [[TMP3]])
    464 ; CHECK-NEXT:    call void @use32(i32 [[TMP4]])
    465 ; CHECK-NEXT:    call void @use32(i32 [[TMP5]])
    466 ; CHECK-NEXT:    ret i32 [[TMP6]]
    467 ;
    468   %tmp = and i32 %arg, %arg1
    469   %tmp3 = icmp eq i32 %tmp, 0
    470   %tmp4 = lshr i32 %arg, %arg2
    471   %tmp5 = and i32 %tmp4, 1
    472   %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1
    473   call void @use32(i32 %tmp)
    474   call void @use1(i1 %tmp3)
    475   call void @use32(i32 %tmp4)
    476   call void @use32(i32 %tmp5)
    477   ret i32 %tmp6
    478 }
    479 
    480 define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) {
    481 ; CHECK-LABEL: @n_var1_oneuse(
    482 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]
    483 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0
    484 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[ARG]], 1
    485 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1
    486 ; CHECK-NEXT:    call void @use32(i32 [[TMP]])
    487 ; CHECK-NEXT:    call void @use1(i1 [[TMP2]])
    488 ; CHECK-NEXT:    call void @use32(i32 [[TMP3]])
    489 ; CHECK-NEXT:    ret i32 [[TMP4]]
    490 ;
    491   %tmp = and i32 %arg, %arg1
    492   %tmp2 = icmp eq i32 %tmp, 0
    493   %tmp3 = and i32 %arg, 1
    494   %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1
    495   call void @use32(i32 %tmp)
    496   call void @use1(i1 %tmp2)
    497   call void @use32(i32 %tmp3)
    498   ret i32 %tmp4
    499 }
    500 
    501 ; Different variables are used
    502 
    503 define i32 @n0(i32 %arg, i32 %arg1) {
    504 ; CHECK-LABEL: @n0(
    505 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 1
    506 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0
    507 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[ARG1:%.*]], 1
    508 ; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP3]], 1
    509 ; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i32 [[TMP4]], i32 1
    510 ; CHECK-NEXT:    ret i32 [[TMP5]]
    511 ;
    512   %tmp = and i32 %arg, 1
    513   %tmp2 = icmp eq i32 %tmp, 0
    514   %tmp3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg
    515   %tmp4 = and i32 %tmp3, 1
    516   %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1
    517   ret i32 %tmp5
    518 }
    519 
    520 define i32 @n1(i32 %arg, i32 %arg1) {
    521 ; CHECK-LABEL: @n1(
    522 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 2
    523 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0
    524 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[ARG1:%.*]], 1
    525 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1
    526 ; CHECK-NEXT:    ret i32 [[TMP4]]
    527 ;
    528   %tmp = and i32 %arg, 2
    529   %tmp2 = icmp eq i32 %tmp, 0
    530   %tmp3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg
    531   %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1
    532   ret i32 %tmp4
    533 }
    534 
    535 ; False-value is not 1
    536 
    537 define i32 @n2(i32 %arg) {
    538 ; CHECK-LABEL: @n2(
    539 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 1
    540 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    541 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[ARG]], 2
    542 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 1
    543 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 0
    544 ; CHECK-NEXT:    ret i32 [[TMP4]]
    545 ;
    546   %tmp = and i32 %arg, 1
    547   %tmp1 = icmp eq i32 %tmp, 0
    548   %tmp2 = lshr i32 %arg, 2
    549   %tmp3 = and i32 %tmp2, 1
    550   %tmp4 = select i1 %tmp1, i32 %tmp3, i32 0 ; 0 instead of 1
    551   ret i32 %tmp4
    552 }
    553 
    554 define i32 @n3(i32 %arg) {
    555 ; CHECK-LABEL: @n3(
    556 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 2
    557 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    558 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG]], 1
    559 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 0
    560 ; CHECK-NEXT:    ret i32 [[TMP3]]
    561 ;
    562   %tmp = and i32 %arg, 2
    563   %tmp1 = icmp eq i32 %tmp, 0
    564   %tmp2 = and i32 %arg, 1
    565   %tmp3 = select i1 %tmp1, i32 %tmp2, i32 0 ; 0 instead of 1
    566   ret i32 %tmp3
    567 }
    568 
    569 ; Mask of second and is not one
    570 
    571 define i32 @n4(i32 %arg) {
    572 ; CHECK-LABEL: @n4(
    573 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 1
    574 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    575 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[ARG]], 2
    576 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 2
    577 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 1
    578 ; CHECK-NEXT:    ret i32 [[TMP4]]
    579 ;
    580   %tmp = and i32 %arg, 1
    581   %tmp1 = icmp eq i32 %tmp, 0
    582   %tmp2 = lshr i32 %arg, 2
    583   %tmp3 = and i32 %tmp2, 2 ; 2 instead of 1
    584   %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1
    585   ret i32 %tmp4
    586 }
    587 
    588 define i32 @n5(i32 %arg) {
    589 ; CHECK-LABEL: @n5(
    590 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 2
    591 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    592 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG]], 2
    593 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 1
    594 ; CHECK-NEXT:    ret i32 [[TMP3]]
    595 ;
    596   %tmp = and i32 %arg, 2
    597   %tmp1 = icmp eq i32 %tmp, 0
    598   %tmp2 = and i32 %arg, 2 ; 2 instead of 1
    599   %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1
    600   ret i32 %tmp3
    601 }
    602 
    603 ; Wrong icmp pred
    604 
    605 define i32 @n6(i32 %arg) {
    606 ; CHECK-LABEL: @n6(
    607 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 1
    608 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    609 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[ARG]], 2
    610 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 1
    611 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]]
    612 ; CHECK-NEXT:    ret i32 [[TMP4]]
    613 ;
    614   %tmp = and i32 %arg, 1
    615   %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq
    616   %tmp2 = lshr i32 %arg, 2
    617   %tmp3 = and i32 %tmp2, 1
    618   %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1
    619   ret i32 %tmp4
    620 }
    621 
    622 define i32 @n7(i32 %arg) {
    623 ; CHECK-LABEL: @n7(
    624 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 2
    625 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    626 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG]], 1
    627 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP2]]
    628 ; CHECK-NEXT:    ret i32 [[TMP3]]
    629 ;
    630   %tmp = and i32 %arg, 2
    631   %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq
    632   %tmp2 = and i32 %arg, 1
    633   %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1
    634   ret i32 %tmp3
    635 }
    636 
    637 ; icmp second operand is not zero
    638 
    639 define i32 @n8(i32 %arg) {
    640 ; CHECK-LABEL: @n8(
    641 ; CHECK-NEXT:    [[TMP:%.*]] = and i32 [[ARG:%.*]], 1
    642 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
    643 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[ARG]], 2
    644 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 1
    645 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]]
    646 ; CHECK-NEXT:    ret i32 [[TMP4]]
    647 ;
    648   %tmp = and i32 %arg, 1
    649   %tmp1 = icmp eq i32 %tmp, 1
    650   %tmp2 = lshr i32 %arg, 2
    651   %tmp3 = and i32 %tmp2, 1
    652   %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1
    653   ret i32 %tmp4
    654 }
    655