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 <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) {
      5 ; CHECK-LABEL: @vsel_tvec(
      6 ; CHECK-NEXT:    ret <2 x i8> %x
      7 ;
      8   %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y
      9   ret <2 x i8> %s
     10 }
     11 
     12 define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) {
     13 ; CHECK-LABEL: @vsel_fvec(
     14 ; CHECK-NEXT:    ret <2 x i8> %y
     15 ;
     16   %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y
     17   ret <2 x i8> %s
     18 }
     19 
     20 define <2 x i8> @vsel_mixedvec() {
     21 ; CHECK-LABEL: @vsel_mixedvec(
     22 ; CHECK-NEXT:    ret <2 x i8> <i8 0, i8 3>
     23 ;
     24   %s = select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3>
     25   ret <2 x i8> %s
     26 }
     27 
     28 ; FIXME: Allow for undef elements in a constant vector condition.
     29 
     30 define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
     31 ; CHECK-LABEL: @vsel_undef_true_op(
     32 ; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]
     33 ; CHECK-NEXT:    ret <3 x i8> [[S]]
     34 ;
     35   %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y
     36   ret <3 x i8> %s
     37 }
     38 
     39 define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) {
     40 ; CHECK-LABEL: @vsel_undef_false_op(
     41 ; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]]
     42 ; CHECK-NEXT:    ret <3 x i4> [[S]]
     43 ;
     44   %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y
     45   ret <3 x i4> %s
     46 }
     47 
     48 define i32 @test1(i32 %x) {
     49 ; CHECK-LABEL: @test1(
     50 ; CHECK-NEXT:    ret i32 %x
     51 ;
     52   %and = and i32 %x, 1
     53   %cmp = icmp eq i32 %and, 0
     54   %and1 = and i32 %x, -2
     55   %and1.x = select i1 %cmp, i32 %and1, i32 %x
     56   ret i32 %and1.x
     57 }
     58 
     59 define i32 @test2(i32 %x) {
     60 ; CHECK-LABEL: @test2(
     61 ; CHECK-NEXT:    ret i32 %x
     62 ;
     63   %and = and i32 %x, 1
     64   %cmp = icmp ne i32 %and, 0
     65   %and1 = and i32 %x, -2
     66   %and1.x = select i1 %cmp, i32 %x, i32 %and1
     67   ret i32 %and1.x
     68 }
     69 
     70 define i32 @test3(i32 %x) {
     71 ; CHECK-LABEL: @test3(
     72 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -2
     73 ; CHECK-NEXT:    ret i32 [[AND1]]
     74 ;
     75   %and = and i32 %x, 1
     76   %cmp = icmp ne i32 %and, 0
     77   %and1 = and i32 %x, -2
     78   %and1.x = select i1 %cmp, i32 %and1, i32 %x
     79   ret i32 %and1.x
     80 }
     81 
     82 define i32 @test4(i32 %X) {
     83 ; CHECK-LABEL: @test4(
     84 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %X, -2147483648
     85 ; CHECK-NEXT:    ret i32 [[OR]]
     86 ;
     87   %cmp = icmp slt i32 %X, 0
     88   %or = or i32 %X, -2147483648
     89   %cond = select i1 %cmp, i32 %X, i32 %or
     90   ret i32 %cond
     91 }
     92 
     93 ; Same as above, but the compare isn't canonical
     94 define i32 @test4noncanon(i32 %X) {
     95 ; CHECK-LABEL: @test4noncanon(
     96 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
     97 ; CHECK-NEXT:    ret i32 [[OR]]
     98 ;
     99   %cmp = icmp sle i32 %X, -1
    100   %or = or i32 %X, -2147483648
    101   %cond = select i1 %cmp, i32 %X, i32 %or
    102   ret i32 %cond
    103 }
    104 
    105 define i32 @test5(i32 %X) {
    106 ; CHECK-LABEL: @test5(
    107 ; CHECK-NEXT:    ret i32 %X
    108 ;
    109   %cmp = icmp slt i32 %X, 0
    110   %or = or i32 %X, -2147483648
    111   %cond = select i1 %cmp, i32 %or, i32 %X
    112   ret i32 %cond
    113 }
    114 
    115 define i32 @test6(i32 %X) {
    116 ; CHECK-LABEL: @test6(
    117 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %X, 2147483647
    118 ; CHECK-NEXT:    ret i32 [[AND]]
    119 ;
    120   %cmp = icmp slt i32 %X, 0
    121   %and = and i32 %X, 2147483647
    122   %cond = select i1 %cmp, i32 %and, i32 %X
    123   ret i32 %cond
    124 }
    125 
    126 define i32 @test7(i32 %X) {
    127 ; CHECK-LABEL: @test7(
    128 ; CHECK-NEXT:    ret i32 %X
    129 ;
    130   %cmp = icmp slt i32 %X, 0
    131   %and = and i32 %X, 2147483647
    132   %cond = select i1 %cmp, i32 %X, i32 %and
    133   ret i32 %cond
    134 }
    135 
    136 define i32 @test8(i32 %X) {
    137 ; CHECK-LABEL: @test8(
    138 ; CHECK-NEXT:    ret i32 %X
    139 ;
    140   %cmp = icmp sgt i32 %X, -1
    141   %or = or i32 %X, -2147483648
    142   %cond = select i1 %cmp, i32 %X, i32 %or
    143   ret i32 %cond
    144 }
    145 
    146 define i32 @test9(i32 %X) {
    147 ; CHECK-LABEL: @test9(
    148 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %X, -2147483648
    149 ; CHECK-NEXT:    ret i32 [[OR]]
    150 ;
    151   %cmp = icmp sgt i32 %X, -1
    152   %or = or i32 %X, -2147483648
    153   %cond = select i1 %cmp, i32 %or, i32 %X
    154   ret i32 %cond
    155 }
    156 
    157 ; Same as above, but the compare isn't canonical
    158 define i32 @test9noncanon(i32 %X) {
    159 ; CHECK-LABEL: @test9noncanon(
    160 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
    161 ; CHECK-NEXT:    ret i32 [[OR]]
    162 ;
    163   %cmp = icmp sge i32 %X, 0
    164   %or = or i32 %X, -2147483648
    165   %cond = select i1 %cmp, i32 %or, i32 %X
    166   ret i32 %cond
    167 }
    168 
    169 define i32 @test10(i32 %X) {
    170 ; CHECK-LABEL: @test10(
    171 ; CHECK-NEXT:    ret i32 %X
    172 ;
    173   %cmp = icmp sgt i32 %X, -1
    174   %and = and i32 %X, 2147483647
    175   %cond = select i1 %cmp, i32 %and, i32 %X
    176   ret i32 %cond
    177 }
    178 
    179 define i32 @test11(i32 %X) {
    180 ; CHECK-LABEL: @test11(
    181 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %X, 2147483647
    182 ; CHECK-NEXT:    ret i32 [[AND]]
    183 ;
    184   %cmp = icmp sgt i32 %X, -1
    185   %and = and i32 %X, 2147483647
    186   %cond = select i1 %cmp, i32 %X, i32 %and
    187   ret i32 %cond
    188 }
    189 
    190 define <2 x i8> @test11vec(<2 x i8> %X) {
    191 ; CHECK-LABEL: @test11vec(
    192 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> %X, <i8 127, i8 127>
    193 ; CHECK-NEXT:    ret <2 x i8> [[AND]]
    194 ;
    195   %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1>
    196   %and = and <2 x i8> %X, <i8 127, i8 127>
    197   %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and
    198   ret <2 x i8> %sel
    199 }
    200 
    201 define i32 @test12(i32 %X) {
    202 ; CHECK-LABEL: @test12(
    203 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
    204 ; CHECK-NEXT:    ret i32 [[AND]]
    205 ;
    206   %cmp = icmp ult i32 %X, 4
    207   %and = and i32 %X, 3
    208   %cond = select i1 %cmp, i32 %X, i32 %and
    209   ret i32 %cond
    210 }
    211 
    212 ; Same as above, but the compare isn't canonical
    213 define i32 @test12noncanon(i32 %X) {
    214 ; CHECK-LABEL: @test12noncanon(
    215 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
    216 ; CHECK-NEXT:    ret i32 [[AND]]
    217 ;
    218   %cmp = icmp ule i32 %X, 3
    219   %and = and i32 %X, 3
    220   %cond = select i1 %cmp, i32 %X, i32 %and
    221   ret i32 %cond
    222 }
    223 
    224 define i32 @test13(i32 %X) {
    225 ; CHECK-LABEL: @test13(
    226 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
    227 ; CHECK-NEXT:    ret i32 [[AND]]
    228 ;
    229   %cmp = icmp ugt i32 %X, 3
    230   %and = and i32 %X, 3
    231   %cond = select i1 %cmp, i32 %and, i32 %X
    232   ret i32 %cond
    233 }
    234 
    235 ; Same as above, but the compare isn't canonical
    236 define i32 @test13noncanon(i32 %X) {
    237 ; CHECK-LABEL: @test13noncanon(
    238 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
    239 ; CHECK-NEXT:    ret i32 [[AND]]
    240 ;
    241   %cmp = icmp uge i32 %X, 4
    242   %and = and i32 %X, 3
    243   %cond = select i1 %cmp, i32 %and, i32 %X
    244   ret i32 %cond
    245 }
    246 
    247 define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
    248 ; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
    249 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 8
    250 ; CHECK-NEXT:    ret i32 [[OR]]
    251 ;
    252   %and = and i32 %x, 8
    253   %cmp = icmp eq i32 %and, 0
    254   %or = or i32 %x, 8
    255   %sel = select i1 %cmp, i32 %or, i32 %x
    256   ret i32 %sel
    257 }
    258 
    259 define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) {
    260 ; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt(
    261 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 8
    262 ; CHECK-NEXT:    ret i32 [[OR]]
    263 ;
    264   %and = and i32 %x, 8
    265   %cmp = icmp ne i32 %and, 0
    266   %or = or i32 %x, 8
    267   %sel = select i1 %cmp, i32 %x, i32 %or
    268   ret i32 %sel
    269 }
    270 
    271 define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) {
    272 ; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8(
    273 ; CHECK-NEXT:    ret i32 %x
    274 ;
    275   %and = and i32 %x, 8
    276   %cmp = icmp ne i32 %and, 0
    277   %or = or i32 %x, 8
    278   %sel = select i1 %cmp, i32 %or, i32 %x
    279   ret i32 %sel
    280 }
    281 
    282 define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) {
    283 ; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt(
    284 ; CHECK-NEXT:    ret i32 %x
    285 ;
    286   %and = and i32 %x, 8
    287   %cmp = icmp eq i32 %and, 0
    288   %or = or i32 %x, 8
    289   %sel = select i1 %cmp, i32 %x, i32 %or
    290   ret i32 %sel
    291 }
    292 
    293 define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
    294 ; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
    295 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -9
    296 ; CHECK-NEXT:    ret i32 [[AND1]]
    297 ;
    298   %and = and i32 %x, 8
    299   %cmp = icmp eq i32 %and, 0
    300   %and1 = and i32 %x, -9
    301   %sel = select i1 %cmp, i32 %x, i32 %and1
    302   ret i32 %sel
    303 }
    304 
    305 define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) {
    306 ; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt(
    307 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -9
    308 ; CHECK-NEXT:    ret i32 [[AND1]]
    309 ;
    310   %and = and i32 %x, 8
    311   %cmp = icmp ne i32 %and, 0
    312   %and1 = and i32 %x, -9
    313   %sel = select i1 %cmp, i32 %and1, i32 %x
    314   ret i32 %sel
    315 }
    316 
    317 define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
    318 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
    319 ; CHECK-NEXT:    ret i32 %x
    320 ;
    321   %and = and i32 %x, 8
    322   %cmp = icmp ne i32 %and, 0
    323   %and1 = and i32 %x, -9
    324   %sel = select i1 %cmp, i32 %x, i32 %and1
    325   ret i32 %sel
    326 }
    327 
    328 define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) {
    329 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt(
    330 ; CHECK-NEXT:    ret i32 %x
    331 ;
    332   %and = and i32 %x, 8
    333   %cmp = icmp eq i32 %and, 0
    334   %and1 = and i32 %x, -9
    335   %sel = select i1 %cmp, i32 %and1, i32 %x
    336   ret i32 %sel
    337 }
    338 
    339 ; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466
    340 ; Each of the previous 8 patterns has a variant that replaces the
    341 ; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt.
    342 
    343 define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) {
    344 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128(
    345 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 128
    346 ; CHECK-NEXT:    ret i32 [[OR]]
    347 ;
    348   %trunc = trunc i32 %x to i8
    349   %cmp = icmp sgt i8 %trunc, -1
    350   %or = or i32 %x, 128
    351   %sel = select i1 %cmp, i32 %or, i32 %x
    352   ret i32 %sel
    353 }
    354 
    355 define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) {
    356 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt(
    357 ; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 128
    358 ; CHECK-NEXT:    ret i32 [[OR]]
    359 ;
    360   %trunc = trunc i32 %x to i8
    361   %cmp = icmp slt i8 %trunc, 0
    362   %or = or i32 %x, 128
    363   %sel = select i1 %cmp, i32 %x, i32 %or
    364   ret i32 %sel
    365 }
    366 
    367 define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) {
    368 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128(
    369 ; CHECK-NEXT:    ret i32 %x
    370 ;
    371   %trunc = trunc i32 %x to i8
    372   %cmp = icmp slt i8 %trunc, 0
    373   %or = or i32 %x, 128
    374   %sel = select i1 %cmp, i32 %or, i32 %x
    375   ret i32 %sel
    376 }
    377 
    378 define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) {
    379 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt(
    380 ; CHECK-NEXT:    ret i32 %x
    381 ;
    382   %trunc = trunc i32 %x to i8
    383   %cmp = icmp sgt i8 %trunc, -1
    384   %or = or i32 %x, 128
    385   %sel = select i1 %cmp, i32 %x, i32 %or
    386   ret i32 %sel
    387 }
    388 
    389 define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) {
    390 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8(
    391 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, -9
    392 ; CHECK-NEXT:    ret i32 [[AND]]
    393 ;
    394   %trunc = trunc i32 %x to i4
    395   %cmp = icmp sgt i4 %trunc, -1
    396   %and = and i32 %x, -9
    397   %sel = select i1 %cmp, i32 %x, i32 %and
    398   ret i32 %sel
    399 }
    400 
    401 define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) {
    402 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt(
    403 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, -9
    404 ; CHECK-NEXT:    ret i32 [[AND]]
    405 ;
    406   %trunc = trunc i32 %x to i4
    407   %cmp = icmp slt i4 %trunc, 0
    408   %and = and i32 %x, -9
    409   %sel = select i1 %cmp, i32 %and, i32 %x
    410   ret i32 %sel
    411 }
    412 
    413 define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) {
    414 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8(
    415 ; CHECK-NEXT:    ret i32 %x
    416 ;
    417   %trunc = trunc i32 %x to i4
    418   %cmp = icmp slt i4 %trunc, 0
    419   %and = and i32 %x, -9
    420   %sel = select i1 %cmp, i32 %x, i32 %and
    421   ret i32 %sel
    422 }
    423 
    424 define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) {
    425 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt(
    426 ; CHECK-NEXT:    ret i32 %x
    427 ;
    428   %trunc = trunc i32 %x to i4
    429   %cmp = icmp sgt i4 %trunc, -1
    430   %and = and i32 %x, -9
    431   %sel = select i1 %cmp, i32 %and, i32 %x
    432   ret i32 %sel
    433 }
    434 
    435 ; Make sure that at least a few of the same patterns are repeated with vector types.
    436 
    437 define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) {
    438 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec(
    439 ; CHECK-NEXT:    ret <2 x i32> %x
    440 ;
    441   %and = and <2 x i32> %x, <i32 8, i32 8>
    442   %cmp = icmp ne <2 x i32> %and, zeroinitializer
    443   %and1 = and <2 x i32> %x, <i32 -9, i32 -9>
    444   %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1
    445   ret <2 x i32> %sel
    446 }
    447 
    448 define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) {
    449 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(
    450 ; CHECK-NEXT:    ret <2 x i32> %x
    451 ;
    452   %trunc = trunc <2 x i32> %x to <2 x i4>
    453   %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1>
    454   %and = and <2 x i32> %x, <i32 -9, i32 -9>
    455   %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x
    456   ret <2 x i32> %sel
    457 }
    458 
    459 ; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify?
    460 
    461 define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) {
    462 ; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
    463 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
    464 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
    465 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 %y, -9
    466 ; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i32 %y, i32 [[AND1]]
    467 ; CHECK-NEXT:    ret i32 [[Y_AND1]]
    468 ;
    469   %and = and i32 %x, 8
    470   %cmp = icmp eq i32 %and, 0
    471   %and1 = and i32 %y, -9
    472   %y.and1 = select i1 %cmp, i32 %y, i32 %and1
    473   ret i32 %y.and1
    474 }
    475 
    476 define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) {
    477 ; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8(
    478 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
    479 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
    480 ; CHECK-NEXT:    [[AND1:%.*]] = and i64 %y, -9
    481 ; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i64 %y, i64 [[AND1]]
    482 ; CHECK-NEXT:    ret i64 [[Y_AND1]]
    483 ;
    484   %and = and i32 %x, 8
    485   %cmp = icmp eq i32 %and, 0
    486   %and1 = and i64 %y, -9
    487   %y.and1 = select i1 %cmp, i64 %y, i64 %and1
    488   ret i64 %y.and1
    489 }
    490 
    491 define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) {
    492 ; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8(
    493 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
    494 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
    495 ; CHECK-NEXT:    [[AND1:%.*]] = and i64 %y, -9
    496 ; CHECK-NEXT:    [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 %y
    497 ; CHECK-NEXT:    ret i64 [[AND1_Y]]
    498 ;
    499   %and = and i32 %x, 8
    500   %cmp = icmp eq i32 %and, 0
    501   %and1 = and i64 %y, -9
    502   %and1.y = select i1 %cmp, i64 %and1, i64 %y
    503   ret i64 %and1.y
    504 }
    505 
    506 ; Don't crash on a pointer or aggregate type.
    507 
    508 define i32* @select_icmp_pointers(i32* %x, i32* %y) {
    509 ; CHECK-LABEL: @select_icmp_pointers(
    510 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32* %x, null
    511 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32* %x, i32* %y
    512 ; CHECK-NEXT:    ret i32* [[SEL]]
    513 ;
    514   %cmp = icmp slt i32* %x, null
    515   %sel = select i1 %cmp, i32* %x, i32* %y
    516   ret i32* %sel
    517 }
    518 
    519 ; If the condition is known, we don't need to select, but we're not
    520 ; doing this fold here to avoid compile-time cost.
    521 
    522 declare void @llvm.assume(i1)
    523 
    524 define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
    525 ; CHECK-LABEL: @assume_sel_cond(
    526 ; CHECK-NEXT:    call void @llvm.assume(i1 %cond)
    527 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
    528 ; CHECK-NEXT:    ret i8 [[SEL]]
    529 ;
    530   call void @llvm.assume(i1 %cond)
    531   %sel = select i1 %cond, i8 %x, i8 %y
    532   ret i8 %sel
    533 }
    534 
    535 define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
    536 ; CHECK-LABEL: @do_not_assume_sel_cond(
    537 ; CHECK-NEXT:    [[NOTCOND:%.*]] = icmp eq i1 %cond, false
    538 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTCOND]])
    539 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
    540 ; CHECK-NEXT:    ret i8 [[SEL]]
    541 ;
    542   %notcond = icmp eq i1 %cond, false
    543   call void @llvm.assume(i1 %notcond)
    544   %sel = select i1 %cond, i8 %x, i8 %y
    545   ret i8 %sel
    546 }
    547 
    548 define i32* @select_icmp_eq_0_gep_operand(i32* %base, i64 %n) {
    549 ; CHECK-LABEL: @select_icmp_eq_0_gep_operand(
    550 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr
    551 ; CHECK-NEXT: ret i32* [[GEP]]
    552   %cond = icmp eq i64 %n, 0
    553   %gep = getelementptr i32, i32* %base, i64 %n
    554   %r = select i1 %cond, i32* %base, i32* %gep
    555   ret i32* %r
    556 }
    557 
    558 define i32* @select_icmp_ne_0_gep_operand(i32* %base, i64 %n) {
    559 ; CHECK-LABEL: @select_icmp_ne_0_gep_operand(
    560 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr
    561 ; CHECK-NEXT: ret i32* [[GEP]]
    562   %cond = icmp ne i64 %n, 0
    563   %gep = getelementptr i32, i32* %base, i64 %n
    564   %r = select i1 %cond, i32* %gep, i32* %base
    565   ret i32* %r
    566 }
    567