Home | History | Annotate | Download | only in AArch64
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
      3 
      4 ; https://bugs.llvm.org/show_bug.cgi?id=37104
      5 
      6 define i8 @out8(i8 %x, i8 %y, i8 %mask) {
      7 ; CHECK-LABEL: out8:
      8 ; CHECK:       // %bb.0:
      9 ; CHECK-NEXT:    and w8, w0, w2
     10 ; CHECK-NEXT:    bic w9, w1, w2
     11 ; CHECK-NEXT:    orr w0, w8, w9
     12 ; CHECK-NEXT:    ret
     13   %mx = and i8 %x, %mask
     14   %notmask = xor i8 %mask, -1
     15   %my = and i8 %y, %notmask
     16   %r = or i8 %mx, %my
     17   ret i8 %r
     18 }
     19 
     20 define i16 @out16(i16 %x, i16 %y, i16 %mask) {
     21 ; CHECK-LABEL: out16:
     22 ; CHECK:       // %bb.0:
     23 ; CHECK-NEXT:    and w8, w0, w2
     24 ; CHECK-NEXT:    bic w9, w1, w2
     25 ; CHECK-NEXT:    orr w0, w8, w9
     26 ; CHECK-NEXT:    ret
     27   %mx = and i16 %x, %mask
     28   %notmask = xor i16 %mask, -1
     29   %my = and i16 %y, %notmask
     30   %r = or i16 %mx, %my
     31   ret i16 %r
     32 }
     33 
     34 define i32 @out32(i32 %x, i32 %y, i32 %mask) {
     35 ; CHECK-LABEL: out32:
     36 ; CHECK:       // %bb.0:
     37 ; CHECK-NEXT:    and w8, w0, w2
     38 ; CHECK-NEXT:    bic w9, w1, w2
     39 ; CHECK-NEXT:    orr w0, w8, w9
     40 ; CHECK-NEXT:    ret
     41   %mx = and i32 %x, %mask
     42   %notmask = xor i32 %mask, -1
     43   %my = and i32 %y, %notmask
     44   %r = or i32 %mx, %my
     45   ret i32 %r
     46 }
     47 
     48 define i64 @out64(i64 %x, i64 %y, i64 %mask) {
     49 ; CHECK-LABEL: out64:
     50 ; CHECK:       // %bb.0:
     51 ; CHECK-NEXT:    and x8, x0, x2
     52 ; CHECK-NEXT:    bic x9, x1, x2
     53 ; CHECK-NEXT:    orr x0, x8, x9
     54 ; CHECK-NEXT:    ret
     55   %mx = and i64 %x, %mask
     56   %notmask = xor i64 %mask, -1
     57   %my = and i64 %y, %notmask
     58   %r = or i64 %mx, %my
     59   ret i64 %r
     60 }
     61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     62 ; Should be the same as the previous one.
     63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     64 
     65 define i8 @in8(i8 %x, i8 %y, i8 %mask) {
     66 ; CHECK-LABEL: in8:
     67 ; CHECK:       // %bb.0:
     68 ; CHECK-NEXT:    and w8, w0, w2
     69 ; CHECK-NEXT:    bic w9, w1, w2
     70 ; CHECK-NEXT:    orr w0, w8, w9
     71 ; CHECK-NEXT:    ret
     72   %n0 = xor i8 %x, %y
     73   %n1 = and i8 %n0, %mask
     74   %r = xor i8 %n1, %y
     75   ret i8 %r
     76 }
     77 
     78 define i16 @in16(i16 %x, i16 %y, i16 %mask) {
     79 ; CHECK-LABEL: in16:
     80 ; CHECK:       // %bb.0:
     81 ; CHECK-NEXT:    and w8, w0, w2
     82 ; CHECK-NEXT:    bic w9, w1, w2
     83 ; CHECK-NEXT:    orr w0, w8, w9
     84 ; CHECK-NEXT:    ret
     85   %n0 = xor i16 %x, %y
     86   %n1 = and i16 %n0, %mask
     87   %r = xor i16 %n1, %y
     88   ret i16 %r
     89 }
     90 
     91 define i32 @in32(i32 %x, i32 %y, i32 %mask) {
     92 ; CHECK-LABEL: in32:
     93 ; CHECK:       // %bb.0:
     94 ; CHECK-NEXT:    bic w8, w1, w2
     95 ; CHECK-NEXT:    and w9, w0, w2
     96 ; CHECK-NEXT:    orr w0, w9, w8
     97 ; CHECK-NEXT:    ret
     98   %n0 = xor i32 %x, %y
     99   %n1 = and i32 %n0, %mask
    100   %r = xor i32 %n1, %y
    101   ret i32 %r
    102 }
    103 
    104 define i64 @in64(i64 %x, i64 %y, i64 %mask) {
    105 ; CHECK-LABEL: in64:
    106 ; CHECK:       // %bb.0:
    107 ; CHECK-NEXT:    bic x8, x1, x2
    108 ; CHECK-NEXT:    and x9, x0, x2
    109 ; CHECK-NEXT:    orr x0, x9, x8
    110 ; CHECK-NEXT:    ret
    111   %n0 = xor i64 %x, %y
    112   %n1 = and i64 %n0, %mask
    113   %r = xor i64 %n1, %y
    114   ret i64 %r
    115 }
    116 ; ============================================================================ ;
    117 ; Commutativity tests.
    118 ; ============================================================================ ;
    119 define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) {
    120 ; CHECK-LABEL: in_commutativity_0_0_1:
    121 ; CHECK:       // %bb.0:
    122 ; CHECK-NEXT:    bic w8, w1, w2
    123 ; CHECK-NEXT:    and w9, w0, w2
    124 ; CHECK-NEXT:    orr w0, w9, w8
    125 ; CHECK-NEXT:    ret
    126   %n0 = xor i32 %x, %y
    127   %n1 = and i32 %mask, %n0 ; swapped
    128   %r = xor i32 %n1, %y
    129   ret i32 %r
    130 }
    131 define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) {
    132 ; CHECK-LABEL: in_commutativity_0_1_0:
    133 ; CHECK:       // %bb.0:
    134 ; CHECK-NEXT:    bic w8, w1, w2
    135 ; CHECK-NEXT:    and w9, w0, w2
    136 ; CHECK-NEXT:    orr w0, w9, w8
    137 ; CHECK-NEXT:    ret
    138   %n0 = xor i32 %x, %y
    139   %n1 = and i32 %n0, %mask
    140   %r = xor i32 %y, %n1 ; swapped
    141   ret i32 %r
    142 }
    143 define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) {
    144 ; CHECK-LABEL: in_commutativity_0_1_1:
    145 ; CHECK:       // %bb.0:
    146 ; CHECK-NEXT:    bic w8, w1, w2
    147 ; CHECK-NEXT:    and w9, w0, w2
    148 ; CHECK-NEXT:    orr w0, w9, w8
    149 ; CHECK-NEXT:    ret
    150   %n0 = xor i32 %x, %y
    151   %n1 = and i32 %mask, %n0 ; swapped
    152   %r = xor i32 %y, %n1 ; swapped
    153   ret i32 %r
    154 }
    155 define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) {
    156 ; CHECK-LABEL: in_commutativity_1_0_0:
    157 ; CHECK:       // %bb.0:
    158 ; CHECK-NEXT:    bic w8, w0, w2
    159 ; CHECK-NEXT:    and w9, w1, w2
    160 ; CHECK-NEXT:    orr w0, w9, w8
    161 ; CHECK-NEXT:    ret
    162   %n0 = xor i32 %x, %y
    163   %n1 = and i32 %n0, %mask
    164   %r = xor i32 %n1, %x ; %x instead of %y
    165   ret i32 %r
    166 }
    167 define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) {
    168 ; CHECK-LABEL: in_commutativity_1_0_1:
    169 ; CHECK:       // %bb.0:
    170 ; CHECK-NEXT:    bic w8, w0, w2
    171 ; CHECK-NEXT:    and w9, w1, w2
    172 ; CHECK-NEXT:    orr w0, w9, w8
    173 ; CHECK-NEXT:    ret
    174   %n0 = xor i32 %x, %y
    175   %n1 = and i32 %mask, %n0 ; swapped
    176   %r = xor i32 %n1, %x ; %x instead of %y
    177   ret i32 %r
    178 }
    179 define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) {
    180 ; CHECK-LABEL: in_commutativity_1_1_0:
    181 ; CHECK:       // %bb.0:
    182 ; CHECK-NEXT:    bic w8, w0, w2
    183 ; CHECK-NEXT:    and w9, w1, w2
    184 ; CHECK-NEXT:    orr w0, w9, w8
    185 ; CHECK-NEXT:    ret
    186   %n0 = xor i32 %x, %y
    187   %n1 = and i32 %n0, %mask
    188   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
    189   ret i32 %r
    190 }
    191 define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) {
    192 ; CHECK-LABEL: in_commutativity_1_1_1:
    193 ; CHECK:       // %bb.0:
    194 ; CHECK-NEXT:    bic w8, w0, w2
    195 ; CHECK-NEXT:    and w9, w1, w2
    196 ; CHECK-NEXT:    orr w0, w9, w8
    197 ; CHECK-NEXT:    ret
    198   %n0 = xor i32 %x, %y
    199   %n1 = and i32 %mask, %n0 ; swapped
    200   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
    201   ret i32 %r
    202 }
    203 ; ============================================================================ ;
    204 ; Y is an 'and' too.
    205 ; ============================================================================ ;
    206 define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
    207 ; CHECK-LABEL: in_complex_y0:
    208 ; CHECK:       // %bb.0:
    209 ; CHECK-NEXT:    and w8, w1, w2
    210 ; CHECK-NEXT:    and w9, w0, w3
    211 ; CHECK-NEXT:    bic w8, w8, w3
    212 ; CHECK-NEXT:    orr w0, w9, w8
    213 ; CHECK-NEXT:    ret
    214   %y = and i32 %y_hi, %y_low
    215   %n0 = xor i32 %x, %y
    216   %n1 = and i32 %n0, %mask
    217   %r = xor i32 %n1, %y
    218   ret i32 %r
    219 }
    220 define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
    221 ; CHECK-LABEL: in_complex_y1:
    222 ; CHECK:       // %bb.0:
    223 ; CHECK-NEXT:    and w8, w1, w2
    224 ; CHECK-NEXT:    and w9, w0, w3
    225 ; CHECK-NEXT:    bic w8, w8, w3
    226 ; CHECK-NEXT:    orr w0, w9, w8
    227 ; CHECK-NEXT:    ret
    228   %y = and i32 %y_hi, %y_low
    229   %n0 = xor i32 %x, %y
    230   %n1 = and i32 %n0, %mask
    231   %r = xor i32 %y, %n1
    232   ret i32 %r
    233 }
    234 ; ============================================================================ ;
    235 ; M is an 'xor' too.
    236 ; ============================================================================ ;
    237 define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
    238 ; CHECK-LABEL: in_complex_m0:
    239 ; CHECK:       // %bb.0:
    240 ; CHECK-NEXT:    eor w8, w2, w3
    241 ; CHECK-NEXT:    bic w9, w1, w8
    242 ; CHECK-NEXT:    and w8, w0, w8
    243 ; CHECK-NEXT:    orr w0, w8, w9
    244 ; CHECK-NEXT:    ret
    245   %mask = xor i32 %m_a, %m_b
    246   %n0 = xor i32 %x, %y
    247   %n1 = and i32 %n0, %mask
    248   %r = xor i32 %n1, %y
    249   ret i32 %r
    250 }
    251 define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
    252 ; CHECK-LABEL: in_complex_m1:
    253 ; CHECK:       // %bb.0:
    254 ; CHECK-NEXT:    eor w8, w2, w3
    255 ; CHECK-NEXT:    bic w9, w1, w8
    256 ; CHECK-NEXT:    and w8, w0, w8
    257 ; CHECK-NEXT:    orr w0, w8, w9
    258 ; CHECK-NEXT:    ret
    259   %mask = xor i32 %m_a, %m_b
    260   %n0 = xor i32 %x, %y
    261   %n1 = and i32 %mask, %n0
    262   %r = xor i32 %n1, %y
    263   ret i32 %r
    264 }
    265 ; ============================================================================ ;
    266 ; Both Y and M are complex.
    267 ; ============================================================================ ;
    268 define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    269 ; CHECK-LABEL: in_complex_y0_m0:
    270 ; CHECK:       // %bb.0:
    271 ; CHECK-NEXT:    and w8, w1, w2
    272 ; CHECK-NEXT:    eor w9, w3, w4
    273 ; CHECK-NEXT:    bic w8, w8, w9
    274 ; CHECK-NEXT:    and w9, w0, w9
    275 ; CHECK-NEXT:    orr w0, w9, w8
    276 ; CHECK-NEXT:    ret
    277   %y = and i32 %y_hi, %y_low
    278   %mask = xor i32 %m_a, %m_b
    279   %n0 = xor i32 %x, %y
    280   %n1 = and i32 %n0, %mask
    281   %r = xor i32 %n1, %y
    282   ret i32 %r
    283 }
    284 define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    285 ; CHECK-LABEL: in_complex_y1_m0:
    286 ; CHECK:       // %bb.0:
    287 ; CHECK-NEXT:    and w8, w1, w2
    288 ; CHECK-NEXT:    eor w9, w3, w4
    289 ; CHECK-NEXT:    bic w8, w8, w9
    290 ; CHECK-NEXT:    and w9, w0, w9
    291 ; CHECK-NEXT:    orr w0, w9, w8
    292 ; CHECK-NEXT:    ret
    293   %y = and i32 %y_hi, %y_low
    294   %mask = xor i32 %m_a, %m_b
    295   %n0 = xor i32 %x, %y
    296   %n1 = and i32 %n0, %mask
    297   %r = xor i32 %y, %n1
    298   ret i32 %r
    299 }
    300 define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    301 ; CHECK-LABEL: in_complex_y0_m1:
    302 ; CHECK:       // %bb.0:
    303 ; CHECK-NEXT:    and w8, w1, w2
    304 ; CHECK-NEXT:    eor w9, w3, w4
    305 ; CHECK-NEXT:    bic w8, w8, w9
    306 ; CHECK-NEXT:    and w9, w0, w9
    307 ; CHECK-NEXT:    orr w0, w9, w8
    308 ; CHECK-NEXT:    ret
    309   %y = and i32 %y_hi, %y_low
    310   %mask = xor i32 %m_a, %m_b
    311   %n0 = xor i32 %x, %y
    312   %n1 = and i32 %mask, %n0
    313   %r = xor i32 %n1, %y
    314   ret i32 %r
    315 }
    316 define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    317 ; CHECK-LABEL: in_complex_y1_m1:
    318 ; CHECK:       // %bb.0:
    319 ; CHECK-NEXT:    and w8, w1, w2
    320 ; CHECK-NEXT:    eor w9, w3, w4
    321 ; CHECK-NEXT:    bic w8, w8, w9
    322 ; CHECK-NEXT:    and w9, w0, w9
    323 ; CHECK-NEXT:    orr w0, w9, w8
    324 ; CHECK-NEXT:    ret
    325   %y = and i32 %y_hi, %y_low
    326   %mask = xor i32 %m_a, %m_b
    327   %n0 = xor i32 %x, %y
    328   %n1 = and i32 %mask, %n0
    329   %r = xor i32 %y, %n1
    330   ret i32 %r
    331 }
    332 ; ============================================================================ ;
    333 ; Various cases with %x and/or %y being a constant
    334 ; ============================================================================ ;
    335 define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
    336 ; CHECK-LABEL: out_constant_varx_mone:
    337 ; CHECK:       // %bb.0:
    338 ; CHECK-NEXT:    and w8, w2, w0
    339 ; CHECK-NEXT:    orn w0, w8, w2
    340 ; CHECK-NEXT:    ret
    341   %notmask = xor i32 %mask, -1
    342   %mx = and i32 %mask, %x
    343   %my = and i32 %notmask, -1
    344   %r = or i32 %mx, %my
    345   ret i32 %r
    346 }
    347 define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
    348 ; CHECK-LABEL: in_constant_varx_mone:
    349 ; CHECK:       // %bb.0:
    350 ; CHECK-NEXT:    bic w8, w2, w0
    351 ; CHECK-NEXT:    mvn w0, w8
    352 ; CHECK-NEXT:    ret
    353   %n0 = xor i32 %x, -1 ; %x
    354   %n1 = and i32 %n0, %mask
    355   %r = xor i32 %n1, -1
    356   ret i32 %r
    357 }
    358 ; This is not a canonical form. Testing for completeness only.
    359 define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
    360 ; CHECK-LABEL: out_constant_varx_mone_invmask:
    361 ; CHECK:       // %bb.0:
    362 ; CHECK-NEXT:    bic w8, w0, w2
    363 ; CHECK-NEXT:    orr w0, w8, w2
    364 ; CHECK-NEXT:    ret
    365   %notmask = xor i32 %mask, -1
    366   %mx = and i32 %notmask, %x
    367   %my = and i32 %mask, -1
    368   %r = or i32 %mx, %my
    369   ret i32 %r
    370 }
    371 ; This is not a canonical form. Testing for completeness only.
    372 define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
    373 ; CHECK-LABEL: in_constant_varx_mone_invmask:
    374 ; CHECK:       // %bb.0:
    375 ; CHECK-NEXT:    mvn w8, w0
    376 ; CHECK-NEXT:    bic w8, w8, w2
    377 ; CHECK-NEXT:    mvn w0, w8
    378 ; CHECK-NEXT:    ret
    379   %notmask = xor i32 %mask, -1
    380   %n0 = xor i32 %x, -1 ; %x
    381   %n1 = and i32 %n0, %notmask
    382   %r = xor i32 %n1, -1
    383   ret i32 %r
    384 }
    385 define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
    386 ; CHECK-LABEL: out_constant_varx_42:
    387 ; CHECK:       // %bb.0:
    388 ; CHECK-NEXT:    mov w9, #42
    389 ; CHECK-NEXT:    and w8, w2, w0
    390 ; CHECK-NEXT:    bic w9, w9, w2
    391 ; CHECK-NEXT:    orr w0, w8, w9
    392 ; CHECK-NEXT:    ret
    393   %notmask = xor i32 %mask, -1
    394   %mx = and i32 %mask, %x
    395   %my = and i32 %notmask, 42
    396   %r = or i32 %mx, %my
    397   ret i32 %r
    398 }
    399 define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
    400 ; CHECK-LABEL: in_constant_varx_42:
    401 ; CHECK:       // %bb.0:
    402 ; CHECK-NEXT:    mov w8, #42
    403 ; CHECK-NEXT:    bic w8, w8, w2
    404 ; CHECK-NEXT:    and w9, w0, w2
    405 ; CHECK-NEXT:    orr w0, w9, w8
    406 ; CHECK-NEXT:    ret
    407   %n0 = xor i32 %x, 42 ; %x
    408   %n1 = and i32 %n0, %mask
    409   %r = xor i32 %n1, 42
    410   ret i32 %r
    411 }
    412 ; This is not a canonical form. Testing for completeness only.
    413 define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
    414 ; CHECK-LABEL: out_constant_varx_42_invmask:
    415 ; CHECK:       // %bb.0:
    416 ; CHECK-NEXT:    mov w9, #42
    417 ; CHECK-NEXT:    bic w8, w0, w2
    418 ; CHECK-NEXT:    and w9, w2, w9
    419 ; CHECK-NEXT:    orr w0, w8, w9
    420 ; CHECK-NEXT:    ret
    421   %notmask = xor i32 %mask, -1
    422   %mx = and i32 %notmask, %x
    423   %my = and i32 %mask, 42
    424   %r = or i32 %mx, %my
    425   ret i32 %r
    426 }
    427 ; This is not a canonical form. Testing for completeness only.
    428 define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
    429 ; CHECK-LABEL: in_constant_varx_42_invmask:
    430 ; CHECK:       // %bb.0:
    431 ; CHECK-NEXT:    mov w8, #42
    432 ; CHECK-NEXT:    and w8, w2, w8
    433 ; CHECK-NEXT:    bic w9, w0, w2
    434 ; CHECK-NEXT:    orr w0, w9, w8
    435 ; CHECK-NEXT:    ret
    436   %notmask = xor i32 %mask, -1
    437   %n0 = xor i32 %x, 42 ; %x
    438   %n1 = and i32 %n0, %notmask
    439   %r = xor i32 %n1, 42
    440   ret i32 %r
    441 }
    442 define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
    443 ; CHECK-LABEL: out_constant_mone_vary:
    444 ; CHECK:       // %bb.0:
    445 ; CHECK-NEXT:    bic w8, w1, w2
    446 ; CHECK-NEXT:    orr w0, w2, w8
    447 ; CHECK-NEXT:    ret
    448   %notmask = xor i32 %mask, -1
    449   %mx = and i32 %mask, -1
    450   %my = and i32 %notmask, %y
    451   %r = or i32 %mx, %my
    452   ret i32 %r
    453 }
    454 define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
    455 ; CHECK-LABEL: in_constant_mone_vary:
    456 ; CHECK:       // %bb.0:
    457 ; CHECK-NEXT:    bic w8, w2, w1
    458 ; CHECK-NEXT:    eor w0, w8, w1
    459 ; CHECK-NEXT:    ret
    460   %n0 = xor i32 -1, %y ; %x
    461   %n1 = and i32 %n0, %mask
    462   %r = xor i32 %n1, %y
    463   ret i32 %r
    464 }
    465 ; This is not a canonical form. Testing for completeness only.
    466 define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    467 ; CHECK-LABEL: out_constant_mone_vary_invmask:
    468 ; CHECK:       // %bb.0:
    469 ; CHECK-NEXT:    and w8, w2, w1
    470 ; CHECK-NEXT:    orn w0, w8, w2
    471 ; CHECK-NEXT:    ret
    472   %notmask = xor i32 %mask, -1
    473   %mx = and i32 %notmask, -1
    474   %my = and i32 %mask, %y
    475   %r = or i32 %mx, %my
    476   ret i32 %r
    477 }
    478 ; This is not a canonical form. Testing for completeness only.
    479 define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    480 ; CHECK-LABEL: in_constant_mone_vary_invmask:
    481 ; CHECK:       // %bb.0:
    482 ; CHECK-NEXT:    mvn w8, w1
    483 ; CHECK-NEXT:    bic w8, w8, w2
    484 ; CHECK-NEXT:    eor w0, w8, w1
    485 ; CHECK-NEXT:    ret
    486   %notmask = xor i32 %mask, -1
    487   %n0 = xor i32 -1, %y ; %x
    488   %n1 = and i32 %n0, %notmask
    489   %r = xor i32 %n1, %y
    490   ret i32 %r
    491 }
    492 define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
    493 ; CHECK-LABEL: out_constant_42_vary:
    494 ; CHECK:       // %bb.0:
    495 ; CHECK-NEXT:    mov w8, #42
    496 ; CHECK-NEXT:    and w8, w2, w8
    497 ; CHECK-NEXT:    bic w9, w1, w2
    498 ; CHECK-NEXT:    orr w0, w8, w9
    499 ; CHECK-NEXT:    ret
    500   %notmask = xor i32 %mask, -1
    501   %mx = and i32 %mask, 42
    502   %my = and i32 %notmask, %y
    503   %r = or i32 %mx, %my
    504   ret i32 %r
    505 }
    506 define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
    507 ; CHECK-LABEL: in_constant_42_vary:
    508 ; CHECK:       // %bb.0:
    509 ; CHECK-NEXT:    mov w9, #42
    510 ; CHECK-NEXT:    bic w8, w1, w2
    511 ; CHECK-NEXT:    and w9, w2, w9
    512 ; CHECK-NEXT:    orr w0, w9, w8
    513 ; CHECK-NEXT:    ret
    514   %n0 = xor i32 42, %y ; %x
    515   %n1 = and i32 %n0, %mask
    516   %r = xor i32 %n1, %y
    517   ret i32 %r
    518 }
    519 ; This is not a canonical form. Testing for completeness only.
    520 define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    521 ; CHECK-LABEL: out_constant_42_vary_invmask:
    522 ; CHECK:       // %bb.0:
    523 ; CHECK-NEXT:    mov w8, #42
    524 ; CHECK-NEXT:    bic w8, w8, w2
    525 ; CHECK-NEXT:    and w9, w2, w1
    526 ; CHECK-NEXT:    orr w0, w8, w9
    527 ; CHECK-NEXT:    ret
    528   %notmask = xor i32 %mask, -1
    529   %mx = and i32 %notmask, 42
    530   %my = and i32 %mask, %y
    531   %r = or i32 %mx, %my
    532   ret i32 %r
    533 }
    534 ; This is not a canonical form. Testing for completeness only.
    535 define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    536 ; CHECK-LABEL: in_constant_42_vary_invmask:
    537 ; CHECK:       // %bb.0:
    538 ; CHECK-NEXT:    mov w9, #42
    539 ; CHECK-NEXT:    and w8, w1, w2
    540 ; CHECK-NEXT:    bic w9, w9, w2
    541 ; CHECK-NEXT:    orr w0, w9, w8
    542 ; CHECK-NEXT:    ret
    543   %notmask = xor i32 %mask, -1
    544   %n0 = xor i32 42, %y ; %x
    545   %n1 = and i32 %n0, %notmask
    546   %r = xor i32 %n1, %y
    547   ret i32 %r
    548 }
    549 ; ============================================================================ ;
    550 ; Negative tests. Should not be folded.
    551 ; ============================================================================ ;
    552 ; Multi-use tests.
    553 declare void @use32(i32) nounwind
    554 define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
    555 ; CHECK-LABEL: in_multiuse_A:
    556 ; CHECK:       // %bb.0:
    557 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
    558 ; CHECK-NEXT:    eor w8, w0, w1
    559 ; CHECK-NEXT:    and w20, w8, w3
    560 ; CHECK-NEXT:    mov w0, w20
    561 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 8-byte Folded Spill
    562 ; CHECK-NEXT:    mov w19, w1
    563 ; CHECK-NEXT:    bl use32
    564 ; CHECK-NEXT:    eor w0, w20, w19
    565 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 8-byte Folded Reload
    566 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
    567 ; CHECK-NEXT:    ret
    568   %n0 = xor i32 %x, %y
    569   %n1 = and i32 %n0, %mask
    570   call void @use32(i32 %n1)
    571   %r = xor i32 %n1, %y
    572   ret i32 %r
    573 }
    574 define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
    575 ; CHECK-LABEL: in_multiuse_B:
    576 ; CHECK:       // %bb.0:
    577 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
    578 ; CHECK-NEXT:    eor w0, w0, w1
    579 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 8-byte Folded Spill
    580 ; CHECK-NEXT:    mov w19, w1
    581 ; CHECK-NEXT:    and w20, w0, w3
    582 ; CHECK-NEXT:    bl use32
    583 ; CHECK-NEXT:    eor w0, w20, w19
    584 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 8-byte Folded Reload
    585 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
    586 ; CHECK-NEXT:    ret
    587   %n0 = xor i32 %x, %y
    588   %n1 = and i32 %n0, %mask
    589   call void @use32(i32 %n0)
    590   %r = xor i32 %n1, %y
    591   ret i32 %r
    592 }
    593 ; Various bad variants
    594 define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) {
    595 ; CHECK-LABEL: n0_badmask:
    596 ; CHECK:       // %bb.0:
    597 ; CHECK-NEXT:    and w8, w0, w2
    598 ; CHECK-NEXT:    bic w9, w1, w3
    599 ; CHECK-NEXT:    orr w0, w8, w9
    600 ; CHECK-NEXT:    ret
    601   %mx = and i32 %x, %mask
    602   %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask
    603   %my = and i32 %y, %notmask
    604   %r = or i32 %mx, %my
    605   ret i32 %r
    606 }
    607 define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) {
    608 ; CHECK-LABEL: n0_badxor:
    609 ; CHECK:       // %bb.0:
    610 ; CHECK-NEXT:    eor w9, w2, #0x1
    611 ; CHECK-NEXT:    and w8, w0, w2
    612 ; CHECK-NEXT:    and w9, w1, w9
    613 ; CHECK-NEXT:    orr w0, w8, w9
    614 ; CHECK-NEXT:    ret
    615   %mx = and i32 %x, %mask
    616   %notmask = xor i32 %mask, 1 ; instead of -1
    617   %my = and i32 %y, %notmask
    618   %r = or i32 %mx, %my
    619   ret i32 %r
    620 }
    621 define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) {
    622 ; CHECK-LABEL: n1_thirdvar:
    623 ; CHECK:       // %bb.0:
    624 ; CHECK-NEXT:    eor w8, w0, w1
    625 ; CHECK-NEXT:    and w8, w8, w3
    626 ; CHECK-NEXT:    eor w0, w8, w2
    627 ; CHECK-NEXT:    ret
    628   %n0 = xor i32 %x, %y
    629   %n1 = and i32 %n0, %mask
    630   %r = xor i32 %n1, %z ; instead of %y
    631   ret i32 %r
    632 }
    633