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 
      5 define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
      6 ; CHECK-LABEL: @foo(
      7 ; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 %a, %b
      8 ; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d
      9 ; CHECK-NEXT:    ret i32 [[J]]
     10 ;
     11   %e = icmp slt i32 %a, %b
     12   %f = sext i1 %e to i32
     13   %g = and i32 %c, %f
     14   %h = xor i32 %f, -1
     15   %i = and i32 %d, %h
     16   %j = or i32 %g, %i
     17   ret i32 %j
     18 }
     19 
     20 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
     21 ; CHECK-LABEL: @bar(
     22 ; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 %a, %b
     23 ; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d
     24 ; CHECK-NEXT:    ret i32 [[J]]
     25 ;
     26   %e = icmp slt i32 %a, %b
     27   %f = sext i1 %e to i32
     28   %g = and i32 %c, %f
     29   %h = xor i32 %f, -1
     30   %i = and i32 %d, %h
     31   %j = or i32 %i, %g
     32   ret i32 %j
     33 }
     34 
     35 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {
     36 ; CHECK-LABEL: @goo(
     37 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
     38 ; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
     39 ; CHECK-NEXT:    ret i32 [[T3]]
     40 ;
     41   %t0 = icmp slt i32 %a, %b
     42   %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
     43   %t1 = and i32 %iftmp.0.0, %c
     44   %not = xor i32 %iftmp.0.0, -1
     45   %t2 = and i32 %not, %d
     46   %t3 = or i32 %t1, %t2
     47   ret i32 %t3
     48 }
     49 
     50 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) {
     51 ; CHECK-LABEL: @poo(
     52 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
     53 ; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
     54 ; CHECK-NEXT:    ret i32 [[T3]]
     55 ;
     56   %t0 = icmp slt i32 %a, %b
     57   %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
     58   %t1 = and i32 %iftmp.0.0, %c
     59   %iftmp = select i1 %t0, i32 0, i32 -1
     60   %t2 = and i32 %iftmp, %d
     61   %t3 = or i32 %t1, %t2
     62   ret i32 %t3
     63 }
     64 
     65 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
     66 ; CHECK-LABEL: @par(
     67 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
     68 ; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
     69 ; CHECK-NEXT:    ret i32 [[T3]]
     70 ;
     71   %t0 = icmp slt i32 %a, %b
     72   %iftmp.1.0 = select i1 %t0, i32 -1, i32 0
     73   %t1 = and i32 %iftmp.1.0, %c
     74   %not = xor i32 %iftmp.1.0, -1
     75   %t2 = and i32 %not, %d
     76   %t3 = or i32 %t1, %t2
     77   ret i32 %t3
     78 }
     79 
     80 ; In the following tests (8 commutation variants), verify that a bitcast doesn't get
     81 ; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly
     82 ; other vector code because of canonicalization to i64 elements for vectors.
     83 
     84 ; The fptosi instructions are included to avoid commutation canonicalization based on
     85 ; operator weight. Using another cast operator ensures that both operands of all logic
     86 ; ops are equally weighted, and this ensures that we're testing all commutation
     87 ; possibilities.
     88 
     89 define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
     90 ; CHECK-LABEL: @bitcast_select_swap0(
     91 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
     92 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
     93 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
     94 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
     95 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
     96 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
     97 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
     98 ;
     99   %sia = fptosi <2 x double> %a to <2 x i64>
    100   %sib = fptosi <2 x double> %b to <2 x i64>
    101   %sext = sext <4 x i1> %cmp to <4 x i32>
    102   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    103   %and1 = and <2 x i64> %bc1, %sia
    104   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    105   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    106   %and2 = and <2 x i64> %bc2, %sib
    107   %or = or <2 x i64> %and1, %and2
    108   ret <2 x i64> %or
    109 }
    110 
    111 define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    112 ; CHECK-LABEL: @bitcast_select_swap1(
    113 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    114 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    115 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    116 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    117 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    118 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    119 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    120 ;
    121   %sia = fptosi <2 x double> %a to <2 x i64>
    122   %sib = fptosi <2 x double> %b to <2 x i64>
    123   %sext = sext <4 x i1> %cmp to <4 x i32>
    124   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    125   %and1 = and <2 x i64> %bc1, %sia
    126   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    127   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    128   %and2 = and <2 x i64> %bc2, %sib
    129   %or = or <2 x i64> %and2, %and1
    130   ret <2 x i64> %or
    131 }
    132 
    133 define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    134 ; CHECK-LABEL: @bitcast_select_swap2(
    135 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    136 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    137 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    138 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    139 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    140 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    141 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    142 ;
    143   %sia = fptosi <2 x double> %a to <2 x i64>
    144   %sib = fptosi <2 x double> %b to <2 x i64>
    145   %sext = sext <4 x i1> %cmp to <4 x i32>
    146   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    147   %and1 = and <2 x i64> %bc1, %sia
    148   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    149   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    150   %and2 = and <2 x i64> %sib, %bc2
    151   %or = or <2 x i64> %and1, %and2
    152   ret <2 x i64> %or
    153 }
    154 
    155 define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    156 ; CHECK-LABEL: @bitcast_select_swap3(
    157 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    158 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    159 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    160 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    161 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    162 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    163 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    164 ;
    165   %sia = fptosi <2 x double> %a to <2 x i64>
    166   %sib = fptosi <2 x double> %b to <2 x i64>
    167   %sext = sext <4 x i1> %cmp to <4 x i32>
    168   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    169   %and1 = and <2 x i64> %bc1, %sia
    170   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    171   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    172   %and2 = and <2 x i64> %sib, %bc2
    173   %or = or <2 x i64> %and2, %and1
    174   ret <2 x i64> %or
    175 }
    176 
    177 define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    178 ; CHECK-LABEL: @bitcast_select_swap4(
    179 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    180 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    181 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    182 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    183 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    184 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    185 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    186 ;
    187   %sia = fptosi <2 x double> %a to <2 x i64>
    188   %sib = fptosi <2 x double> %b to <2 x i64>
    189   %sext = sext <4 x i1> %cmp to <4 x i32>
    190   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    191   %and1 = and <2 x i64> %sia, %bc1
    192   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    193   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    194   %and2 = and <2 x i64> %bc2, %sib
    195   %or = or <2 x i64> %and1, %and2
    196   ret <2 x i64> %or
    197 }
    198 
    199 define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    200 ; CHECK-LABEL: @bitcast_select_swap5(
    201 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    202 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    203 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    204 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    205 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    206 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    207 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    208 ;
    209   %sia = fptosi <2 x double> %a to <2 x i64>
    210   %sib = fptosi <2 x double> %b to <2 x i64>
    211   %sext = sext <4 x i1> %cmp to <4 x i32>
    212   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    213   %and1 = and <2 x i64> %sia, %bc1
    214   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    215   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    216   %and2 = and <2 x i64> %bc2, %sib
    217   %or = or <2 x i64> %and2, %and1
    218   ret <2 x i64> %or
    219 }
    220 
    221 define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    222 ; CHECK-LABEL: @bitcast_select_swap6(
    223 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    224 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    225 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    226 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    227 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    228 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    229 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    230 ;
    231   %sia = fptosi <2 x double> %a to <2 x i64>
    232   %sib = fptosi <2 x double> %b to <2 x i64>
    233   %sext = sext <4 x i1> %cmp to <4 x i32>
    234   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    235   %and1 = and <2 x i64> %sia, %bc1
    236   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    237   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    238   %and2 = and <2 x i64> %sib, %bc2
    239   %or = or <2 x i64> %and1, %and2
    240   ret <2 x i64> %or
    241 }
    242 
    243 define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
    244 ; CHECK-LABEL: @bitcast_select_swap7(
    245 ; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
    246 ; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
    247 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
    248 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
    249 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
    250 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
    251 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
    252 ;
    253   %sia = fptosi <2 x double> %a to <2 x i64>
    254   %sib = fptosi <2 x double> %b to <2 x i64>
    255   %sext = sext <4 x i1> %cmp to <4 x i32>
    256   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    257   %and1 = and <2 x i64> %sia, %bc1
    258   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    259   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    260   %and2 = and <2 x i64> %sib, %bc2
    261   %or = or <2 x i64> %and2, %and1
    262   ret <2 x i64> %or
    263 }
    264 
    265 define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) {
    266 ; CHECK-LABEL: @bitcast_select_multi_uses(
    267 ; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> %cmp to <4 x i32>
    268 ; CHECK-NEXT:    [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
    269 ; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[BC1]], %a
    270 ; CHECK-NEXT:    [[NEG:%.*]] = xor <4 x i32> [[SEXT]], <i32 -1, i32 -1, i32 -1, i32 -1>
    271 ; CHECK-NEXT:    [[BC2:%.*]] = bitcast <4 x i32> [[NEG]] to <2 x i64>
    272 ; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[BC2]], %b
    273 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]
    274 ; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]]
    275 ; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]]
    276 ; CHECK-NEXT:    ret <2 x i64> [[SUB]]
    277 ;
    278   %sext = sext <4 x i1> %cmp to <4 x i32>
    279   %bc1 = bitcast <4 x i32> %sext to <2 x i64>
    280   %and1 = and <2 x i64> %a, %bc1
    281   %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
    282   %bc2 = bitcast <4 x i32> %neg to <2 x i64>
    283   %and2 = and <2 x i64> %b, %bc2
    284   %or = or <2 x i64> %and2, %and1
    285   %add = add <2 x i64> %and2, %bc2
    286   %sub = sub <2 x i64> %or, %add
    287   ret <2 x i64> %sub
    288 }
    289 
    290 define i1 @bools(i1 %a, i1 %b, i1 %c) {
    291 ; CHECK-LABEL: @bools(
    292 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a
    293 ; CHECK-NEXT:    ret i1 [[TMP1]]
    294 ;
    295   %not = xor i1 %c, -1
    296   %and1 = and i1 %not, %a
    297   %and2 = and i1 %c, %b
    298   %or = or i1 %and1, %and2
    299   ret i1 %or
    300 }
    301 
    302 ; Form a select if we know we can get replace 2 simple logic ops.
    303 
    304 define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
    305 ; CHECK-LABEL: @bools_multi_uses1(
    306 ; CHECK-NEXT:    [[NOT:%.*]] = xor i1 %c, true
    307 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], %a
    308 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a
    309 ; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[TMP1]], [[AND1]]
    310 ; CHECK-NEXT:    ret i1 [[XOR]]
    311 ;
    312   %not = xor i1 %c, -1
    313   %and1 = and i1 %not, %a
    314   %and2 = and i1 %c, %b
    315   %or = or i1 %and1, %and2
    316   %xor = xor i1 %or, %and1
    317   ret i1 %xor
    318 }
    319 
    320 ; Don't replace a cheap logic op with a potentially expensive select
    321 ; unless we can also eliminate one of the other original ops.
    322 
    323 define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {
    324 ; CHECK-LABEL: @bools_multi_uses2(
    325 ; CHECK-NEXT:    [[NOT:%.*]] = xor i1 %c, true
    326 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], %a
    327 ; CHECK-NEXT:    [[AND2:%.*]] = and i1 %c, %b
    328 ; CHECK-NEXT:    [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]]
    329 ; CHECK-NEXT:    ret i1 [[ADD]]
    330 ;
    331   %not = xor i1 %c, -1
    332   %and1 = and i1 %not, %a
    333   %and2 = and i1 %c, %b
    334   %or = or i1 %and1, %and2
    335   %add = add i1 %and1, %and2
    336   %and3 = and i1 %or, %add
    337   ret i1 %and3
    338 }
    339 
    340 define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {
    341 ; CHECK-LABEL: @vec_of_bools(
    342 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> %c, <4 x i1> %b, <4 x i1> %a
    343 ; CHECK-NEXT:    ret <4 x i1> [[TMP1]]
    344 ;
    345   %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
    346   %and1 = and <4 x i1> %not, %a
    347   %and2 = and <4 x i1> %b, %c
    348   %or = or <4 x i1> %and2, %and1
    349   ret <4 x i1> %or
    350 }
    351 
    352 define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) {
    353 ; CHECK-LABEL: @vec_of_casted_bools(
    354 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i4 %a to <4 x i1>
    355 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i4 %b to <4 x i1>
    356 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %c, <4 x i1> [[TMP2]], <4 x i1> [[TMP1]]
    357 ; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
    358 ; CHECK-NEXT:    ret i4 [[TMP4]]
    359 ;
    360   %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
    361   %bc1 = bitcast <4 x i1> %not to i4
    362   %bc2 = bitcast <4 x i1> %c to i4
    363   %and1 = and i4 %a, %bc1
    364   %and2 = and i4 %bc2, %b
    365   %or = or i4 %and1, %and2
    366   ret i4 %or
    367 }
    368 
    369 ; Inverted 'and' constants mean this is a select.
    370 
    371 define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {
    372 ; CHECK-LABEL: @vec_sel_consts(
    373 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b
    374 ; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
    375 ;
    376   %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1>
    377   %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0>
    378   %or = or <4 x i32> %and1, %and2
    379   ret <4 x i32> %or
    380 }
    381 
    382 ; The select condition constant is always derived from the first operand of the 'or'.
    383 
    384 define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) {
    385 ; CHECK-LABEL: @vec_sel_consts_weird(
    386 ; CHECK-NEXT:    [[TMP1:%.*]] = select <3 x i1> <i1 false, i1 true, i1 false>, <3 x i129> %b, <3 x i129> %a
    387 ; CHECK-NEXT:    ret <3 x i129> [[TMP1]]
    388 ;
    389   %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1>
    390   %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0>
    391   %or = or <3 x i129> %and2, %and1
    392   ret <3 x i129> %or
    393 }
    394 
    395 ; The mask elements must be inverted for this to be a select.
    396 
    397 define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) {
    398 ; CHECK-LABEL: @vec_not_sel_consts(
    399 ; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
    400 ; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>
    401 ; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
    402 ; CHECK-NEXT:    ret <4 x i32> [[OR]]
    403 ;
    404   %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
    405   %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>
    406   %or = or <4 x i32> %and1, %and2
    407   ret <4 x i32> %or
    408 }
    409 
    410 ; The inverted constants may be operands of xor instructions.
    411 
    412 define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
    413 ; CHECK-LABEL: @vec_sel_xor(
    414 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true>
    415 ; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b
    416 ; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
    417 ;
    418   %mask = sext <4 x i1> %c to <4 x i32>
    419   %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
    420   %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
    421   %and1 = and <4 x i32> %not_mask_flip1, %a
    422   %and2 = and <4 x i32> %mask_flip1, %b
    423   %or = or <4 x i32> %and1, %and2
    424   ret <4 x i32> %or
    425 }
    426 
    427 ; Allow the transform even if the mask values have multiple uses because
    428 ; there's still a net reduction of instructions from removing the and/and/or.
    429 
    430 define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
    431 ; CHECK-LABEL: @vec_sel_xor_multi_use(
    432 ; CHECK-NEXT:    [[MASK:%.*]] = sext <4 x i1> %c to <4 x i32>
    433 ; CHECK-NEXT:    [[MASK_FLIP1:%.*]] = xor <4 x i32> [[MASK]], <i32 -1, i32 0, i32 0, i32 0>
    434 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true>
    435 ; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b
    436 ; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[TMP2]], [[MASK_FLIP1]]
    437 ; CHECK-NEXT:    ret <4 x i32> [[ADD]]
    438 ;
    439   %mask = sext <4 x i1> %c to <4 x i32>
    440   %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
    441   %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
    442   %and1 = and <4 x i32> %not_mask_flip1, %a
    443   %and2 = and <4 x i32> %mask_flip1, %b
    444   %or = or <4 x i32> %and1, %and2
    445   %add = add <4 x i32> %or, %mask_flip1
    446   ret <4 x i32> %add
    447 }
    448 
    449