Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI
      3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI
      4 ; https://bugs.llvm.org/show_bug.cgi?id=37104
      5 
      6 define i8 @out8(i8 %x, i8 %y, i8 %mask) {
      7 ; CHECK-NOBMI-LABEL: out8:
      8 ; CHECK-NOBMI:       # %bb.0:
      9 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
     10 ; CHECK-NOBMI-NEXT:    notb %dl
     11 ; CHECK-NOBMI-NEXT:    andb %sil, %dl
     12 ; CHECK-NOBMI-NEXT:    orb %dil, %dl
     13 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
     14 ; CHECK-NOBMI-NEXT:    retq
     15 ;
     16 ; CHECK-BMI-LABEL: out8:
     17 ; CHECK-BMI:       # %bb.0:
     18 ; CHECK-BMI-NEXT:    andl %edx, %edi
     19 ; CHECK-BMI-NEXT:    notb %dl
     20 ; CHECK-BMI-NEXT:    andb %sil, %dl
     21 ; CHECK-BMI-NEXT:    orb %dil, %dl
     22 ; CHECK-BMI-NEXT:    movl %edx, %eax
     23 ; CHECK-BMI-NEXT:    retq
     24   %mx = and i8 %x, %mask
     25   %notmask = xor i8 %mask, -1
     26   %my = and i8 %y, %notmask
     27   %r = or i8 %mx, %my
     28   ret i8 %r
     29 }
     30 
     31 define i16 @out16(i16 %x, i16 %y, i16 %mask) {
     32 ; CHECK-NOBMI-LABEL: out16:
     33 ; CHECK-NOBMI:       # %bb.0:
     34 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
     35 ; CHECK-NOBMI-NEXT:    notl %edx
     36 ; CHECK-NOBMI-NEXT:    andl %esi, %edx
     37 ; CHECK-NOBMI-NEXT:    orl %edi, %edx
     38 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
     39 ; CHECK-NOBMI-NEXT:    retq
     40 ;
     41 ; CHECK-BMI-LABEL: out16:
     42 ; CHECK-BMI:       # %bb.0:
     43 ; CHECK-BMI-NEXT:    andl %edx, %edi
     44 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
     45 ; CHECK-BMI-NEXT:    orl %edi, %eax
     46 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
     47 ; CHECK-BMI-NEXT:    retq
     48   %mx = and i16 %x, %mask
     49   %notmask = xor i16 %mask, -1
     50   %my = and i16 %y, %notmask
     51   %r = or i16 %mx, %my
     52   ret i16 %r
     53 }
     54 
     55 define i32 @out32(i32 %x, i32 %y, i32 %mask) {
     56 ; CHECK-NOBMI-LABEL: out32:
     57 ; CHECK-NOBMI:       # %bb.0:
     58 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
     59 ; CHECK-NOBMI-NEXT:    notl %edx
     60 ; CHECK-NOBMI-NEXT:    andl %esi, %edx
     61 ; CHECK-NOBMI-NEXT:    orl %edi, %edx
     62 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
     63 ; CHECK-NOBMI-NEXT:    retq
     64 ;
     65 ; CHECK-BMI-LABEL: out32:
     66 ; CHECK-BMI:       # %bb.0:
     67 ; CHECK-BMI-NEXT:    andl %edx, %edi
     68 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
     69 ; CHECK-BMI-NEXT:    orl %edi, %eax
     70 ; CHECK-BMI-NEXT:    retq
     71   %mx = and i32 %x, %mask
     72   %notmask = xor i32 %mask, -1
     73   %my = and i32 %y, %notmask
     74   %r = or i32 %mx, %my
     75   ret i32 %r
     76 }
     77 
     78 define i64 @out64(i64 %x, i64 %y, i64 %mask) {
     79 ; CHECK-NOBMI-LABEL: out64:
     80 ; CHECK-NOBMI:       # %bb.0:
     81 ; CHECK-NOBMI-NEXT:    andq %rdx, %rdi
     82 ; CHECK-NOBMI-NEXT:    notq %rdx
     83 ; CHECK-NOBMI-NEXT:    andq %rsi, %rdx
     84 ; CHECK-NOBMI-NEXT:    orq %rdi, %rdx
     85 ; CHECK-NOBMI-NEXT:    movq %rdx, %rax
     86 ; CHECK-NOBMI-NEXT:    retq
     87 ;
     88 ; CHECK-BMI-LABEL: out64:
     89 ; CHECK-BMI:       # %bb.0:
     90 ; CHECK-BMI-NEXT:    andq %rdx, %rdi
     91 ; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
     92 ; CHECK-BMI-NEXT:    orq %rdi, %rax
     93 ; CHECK-BMI-NEXT:    retq
     94   %mx = and i64 %x, %mask
     95   %notmask = xor i64 %mask, -1
     96   %my = and i64 %y, %notmask
     97   %r = or i64 %mx, %my
     98   ret i64 %r
     99 }
    100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    101 ; Should be the same as the previous one.
    102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    103 
    104 define i8 @in8(i8 %x, i8 %y, i8 %mask) {
    105 ; CHECK-NOBMI-LABEL: in8:
    106 ; CHECK-NOBMI:       # %bb.0:
    107 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    108 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    109 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    110 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    111 ; CHECK-NOBMI-NEXT:    retq
    112 ;
    113 ; CHECK-BMI-LABEL: in8:
    114 ; CHECK-BMI:       # %bb.0:
    115 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    116 ; CHECK-BMI-NEXT:    andl %edx, %edi
    117 ; CHECK-BMI-NEXT:    orl %edi, %eax
    118 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
    119 ; CHECK-BMI-NEXT:    retq
    120   %n0 = xor i8 %x, %y
    121   %n1 = and i8 %n0, %mask
    122   %r = xor i8 %n1, %y
    123   ret i8 %r
    124 }
    125 
    126 define i16 @in16(i16 %x, i16 %y, i16 %mask) {
    127 ; CHECK-NOBMI-LABEL: in16:
    128 ; CHECK-NOBMI:       # %bb.0:
    129 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    130 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    131 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    132 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    133 ; CHECK-NOBMI-NEXT:    retq
    134 ;
    135 ; CHECK-BMI-LABEL: in16:
    136 ; CHECK-BMI:       # %bb.0:
    137 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    138 ; CHECK-BMI-NEXT:    andl %edx, %edi
    139 ; CHECK-BMI-NEXT:    orl %edi, %eax
    140 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
    141 ; CHECK-BMI-NEXT:    retq
    142   %n0 = xor i16 %x, %y
    143   %n1 = and i16 %n0, %mask
    144   %r = xor i16 %n1, %y
    145   ret i16 %r
    146 }
    147 
    148 define i32 @in32(i32 %x, i32 %y, i32 %mask) {
    149 ; CHECK-NOBMI-LABEL: in32:
    150 ; CHECK-NOBMI:       # %bb.0:
    151 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    152 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    153 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    154 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    155 ; CHECK-NOBMI-NEXT:    retq
    156 ;
    157 ; CHECK-BMI-LABEL: in32:
    158 ; CHECK-BMI:       # %bb.0:
    159 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    160 ; CHECK-BMI-NEXT:    andl %edx, %edi
    161 ; CHECK-BMI-NEXT:    orl %edi, %eax
    162 ; CHECK-BMI-NEXT:    retq
    163   %n0 = xor i32 %x, %y
    164   %n1 = and i32 %n0, %mask
    165   %r = xor i32 %n1, %y
    166   ret i32 %r
    167 }
    168 
    169 define i64 @in64(i64 %x, i64 %y, i64 %mask) {
    170 ; CHECK-NOBMI-LABEL: in64:
    171 ; CHECK-NOBMI:       # %bb.0:
    172 ; CHECK-NOBMI-NEXT:    xorq %rsi, %rdi
    173 ; CHECK-NOBMI-NEXT:    andq %rdx, %rdi
    174 ; CHECK-NOBMI-NEXT:    xorq %rsi, %rdi
    175 ; CHECK-NOBMI-NEXT:    movq %rdi, %rax
    176 ; CHECK-NOBMI-NEXT:    retq
    177 ;
    178 ; CHECK-BMI-LABEL: in64:
    179 ; CHECK-BMI:       # %bb.0:
    180 ; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
    181 ; CHECK-BMI-NEXT:    andq %rdx, %rdi
    182 ; CHECK-BMI-NEXT:    orq %rdi, %rax
    183 ; CHECK-BMI-NEXT:    retq
    184   %n0 = xor i64 %x, %y
    185   %n1 = and i64 %n0, %mask
    186   %r = xor i64 %n1, %y
    187   ret i64 %r
    188 }
    189 ; ============================================================================ ;
    190 ; Commutativity tests.
    191 ; ============================================================================ ;
    192 define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) {
    193 ; CHECK-NOBMI-LABEL: in_commutativity_0_0_1:
    194 ; CHECK-NOBMI:       # %bb.0:
    195 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    196 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    197 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    198 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    199 ; CHECK-NOBMI-NEXT:    retq
    200 ;
    201 ; CHECK-BMI-LABEL: in_commutativity_0_0_1:
    202 ; CHECK-BMI:       # %bb.0:
    203 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    204 ; CHECK-BMI-NEXT:    andl %edx, %edi
    205 ; CHECK-BMI-NEXT:    orl %edi, %eax
    206 ; CHECK-BMI-NEXT:    retq
    207   %n0 = xor i32 %x, %y
    208   %n1 = and i32 %mask, %n0 ; swapped
    209   %r = xor i32 %n1, %y
    210   ret i32 %r
    211 }
    212 define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) {
    213 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_0:
    214 ; CHECK-NOBMI:       # %bb.0:
    215 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    216 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    217 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    218 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    219 ; CHECK-NOBMI-NEXT:    retq
    220 ;
    221 ; CHECK-BMI-LABEL: in_commutativity_0_1_0:
    222 ; CHECK-BMI:       # %bb.0:
    223 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    224 ; CHECK-BMI-NEXT:    andl %edx, %edi
    225 ; CHECK-BMI-NEXT:    orl %edi, %eax
    226 ; CHECK-BMI-NEXT:    retq
    227   %n0 = xor i32 %x, %y
    228   %n1 = and i32 %n0, %mask
    229   %r = xor i32 %y, %n1 ; swapped
    230   ret i32 %r
    231 }
    232 define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) {
    233 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_1:
    234 ; CHECK-NOBMI:       # %bb.0:
    235 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    236 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    237 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    238 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    239 ; CHECK-NOBMI-NEXT:    retq
    240 ;
    241 ; CHECK-BMI-LABEL: in_commutativity_0_1_1:
    242 ; CHECK-BMI:       # %bb.0:
    243 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    244 ; CHECK-BMI-NEXT:    andl %edx, %edi
    245 ; CHECK-BMI-NEXT:    orl %edi, %eax
    246 ; CHECK-BMI-NEXT:    retq
    247   %n0 = xor i32 %x, %y
    248   %n1 = and i32 %mask, %n0 ; swapped
    249   %r = xor i32 %y, %n1 ; swapped
    250   ret i32 %r
    251 }
    252 define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) {
    253 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_0:
    254 ; CHECK-NOBMI:       # %bb.0:
    255 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    256 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    257 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    258 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    259 ; CHECK-NOBMI-NEXT:    retq
    260 ;
    261 ; CHECK-BMI-LABEL: in_commutativity_1_0_0:
    262 ; CHECK-BMI:       # %bb.0:
    263 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    264 ; CHECK-BMI-NEXT:    andl %edx, %esi
    265 ; CHECK-BMI-NEXT:    orl %esi, %eax
    266 ; CHECK-BMI-NEXT:    retq
    267   %n0 = xor i32 %x, %y
    268   %n1 = and i32 %n0, %mask
    269   %r = xor i32 %n1, %x ; %x instead of %y
    270   ret i32 %r
    271 }
    272 define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) {
    273 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_1:
    274 ; CHECK-NOBMI:       # %bb.0:
    275 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    276 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    277 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    278 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    279 ; CHECK-NOBMI-NEXT:    retq
    280 ;
    281 ; CHECK-BMI-LABEL: in_commutativity_1_0_1:
    282 ; CHECK-BMI:       # %bb.0:
    283 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    284 ; CHECK-BMI-NEXT:    andl %edx, %esi
    285 ; CHECK-BMI-NEXT:    orl %esi, %eax
    286 ; CHECK-BMI-NEXT:    retq
    287   %n0 = xor i32 %x, %y
    288   %n1 = and i32 %mask, %n0 ; swapped
    289   %r = xor i32 %n1, %x ; %x instead of %y
    290   ret i32 %r
    291 }
    292 define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) {
    293 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_0:
    294 ; CHECK-NOBMI:       # %bb.0:
    295 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    296 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    297 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    298 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    299 ; CHECK-NOBMI-NEXT:    retq
    300 ;
    301 ; CHECK-BMI-LABEL: in_commutativity_1_1_0:
    302 ; CHECK-BMI:       # %bb.0:
    303 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    304 ; CHECK-BMI-NEXT:    andl %edx, %esi
    305 ; CHECK-BMI-NEXT:    orl %esi, %eax
    306 ; CHECK-BMI-NEXT:    retq
    307   %n0 = xor i32 %x, %y
    308   %n1 = and i32 %n0, %mask
    309   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
    310   ret i32 %r
    311 }
    312 define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) {
    313 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_1:
    314 ; CHECK-NOBMI:       # %bb.0:
    315 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    316 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    317 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
    318 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    319 ; CHECK-NOBMI-NEXT:    retq
    320 ;
    321 ; CHECK-BMI-LABEL: in_commutativity_1_1_1:
    322 ; CHECK-BMI:       # %bb.0:
    323 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    324 ; CHECK-BMI-NEXT:    andl %edx, %esi
    325 ; CHECK-BMI-NEXT:    orl %esi, %eax
    326 ; CHECK-BMI-NEXT:    retq
    327   %n0 = xor i32 %x, %y
    328   %n1 = and i32 %mask, %n0 ; swapped
    329   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
    330   ret i32 %r
    331 }
    332 ; ============================================================================ ;
    333 ; Y is an 'and' too.
    334 ; ============================================================================ ;
    335 define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
    336 ; CHECK-NOBMI-LABEL: in_complex_y0:
    337 ; CHECK-NOBMI:       # %bb.0:
    338 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    339 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    340 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    341 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    342 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    343 ; CHECK-NOBMI-NEXT:    retq
    344 ;
    345 ; CHECK-BMI-LABEL: in_complex_y0:
    346 ; CHECK-BMI:       # %bb.0:
    347 ; CHECK-BMI-NEXT:    andl %edx, %esi
    348 ; CHECK-BMI-NEXT:    andl %ecx, %edi
    349 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    350 ; CHECK-BMI-NEXT:    orl %edi, %eax
    351 ; CHECK-BMI-NEXT:    retq
    352   %y = and i32 %y_hi, %y_low
    353   %n0 = xor i32 %x, %y
    354   %n1 = and i32 %n0, %mask
    355   %r = xor i32 %n1, %y
    356   ret i32 %r
    357 }
    358 define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
    359 ; CHECK-NOBMI-LABEL: in_complex_y1:
    360 ; CHECK-NOBMI:       # %bb.0:
    361 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    362 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    363 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    364 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    365 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    366 ; CHECK-NOBMI-NEXT:    retq
    367 ;
    368 ; CHECK-BMI-LABEL: in_complex_y1:
    369 ; CHECK-BMI:       # %bb.0:
    370 ; CHECK-BMI-NEXT:    andl %edx, %esi
    371 ; CHECK-BMI-NEXT:    andl %ecx, %edi
    372 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    373 ; CHECK-BMI-NEXT:    orl %edi, %eax
    374 ; CHECK-BMI-NEXT:    retq
    375   %y = and i32 %y_hi, %y_low
    376   %n0 = xor i32 %x, %y
    377   %n1 = and i32 %n0, %mask
    378   %r = xor i32 %y, %n1
    379   ret i32 %r
    380 }
    381 ; ============================================================================ ;
    382 ; M is an 'xor' too.
    383 ; ============================================================================ ;
    384 define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
    385 ; CHECK-NOBMI-LABEL: in_complex_m0:
    386 ; CHECK-NOBMI:       # %bb.0:
    387 ; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
    388 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    389 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    390 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    391 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    392 ; CHECK-NOBMI-NEXT:    retq
    393 ;
    394 ; CHECK-BMI-LABEL: in_complex_m0:
    395 ; CHECK-BMI:       # %bb.0:
    396 ; CHECK-BMI-NEXT:    xorl %ecx, %edx
    397 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    398 ; CHECK-BMI-NEXT:    andl %edi, %edx
    399 ; CHECK-BMI-NEXT:    orl %edx, %eax
    400 ; CHECK-BMI-NEXT:    retq
    401   %mask = xor i32 %m_a, %m_b
    402   %n0 = xor i32 %x, %y
    403   %n1 = and i32 %n0, %mask
    404   %r = xor i32 %n1, %y
    405   ret i32 %r
    406 }
    407 define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
    408 ; CHECK-NOBMI-LABEL: in_complex_m1:
    409 ; CHECK-NOBMI:       # %bb.0:
    410 ; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
    411 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    412 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    413 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    414 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    415 ; CHECK-NOBMI-NEXT:    retq
    416 ;
    417 ; CHECK-BMI-LABEL: in_complex_m1:
    418 ; CHECK-BMI:       # %bb.0:
    419 ; CHECK-BMI-NEXT:    xorl %ecx, %edx
    420 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    421 ; CHECK-BMI-NEXT:    andl %edi, %edx
    422 ; CHECK-BMI-NEXT:    orl %edx, %eax
    423 ; CHECK-BMI-NEXT:    retq
    424   %mask = xor i32 %m_a, %m_b
    425   %n0 = xor i32 %x, %y
    426   %n1 = and i32 %mask, %n0
    427   %r = xor i32 %n1, %y
    428   ret i32 %r
    429 }
    430 ; ============================================================================ ;
    431 ; Both Y and M are complex.
    432 ; ============================================================================ ;
    433 define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    434 ; CHECK-NOBMI-LABEL: in_complex_y0_m0:
    435 ; CHECK-NOBMI:       # %bb.0:
    436 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    437 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
    438 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    439 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    440 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    441 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    442 ; CHECK-NOBMI-NEXT:    retq
    443 ;
    444 ; CHECK-BMI-LABEL: in_complex_y0_m0:
    445 ; CHECK-BMI:       # %bb.0:
    446 ; CHECK-BMI-NEXT:    andl %edx, %esi
    447 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
    448 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    449 ; CHECK-BMI-NEXT:    andl %edi, %ecx
    450 ; CHECK-BMI-NEXT:    orl %ecx, %eax
    451 ; CHECK-BMI-NEXT:    retq
    452   %y = and i32 %y_hi, %y_low
    453   %mask = xor i32 %m_a, %m_b
    454   %n0 = xor i32 %x, %y
    455   %n1 = and i32 %n0, %mask
    456   %r = xor i32 %n1, %y
    457   ret i32 %r
    458 }
    459 define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    460 ; CHECK-NOBMI-LABEL: in_complex_y1_m0:
    461 ; CHECK-NOBMI:       # %bb.0:
    462 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    463 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
    464 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    465 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    466 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    467 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    468 ; CHECK-NOBMI-NEXT:    retq
    469 ;
    470 ; CHECK-BMI-LABEL: in_complex_y1_m0:
    471 ; CHECK-BMI:       # %bb.0:
    472 ; CHECK-BMI-NEXT:    andl %edx, %esi
    473 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
    474 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    475 ; CHECK-BMI-NEXT:    andl %edi, %ecx
    476 ; CHECK-BMI-NEXT:    orl %ecx, %eax
    477 ; CHECK-BMI-NEXT:    retq
    478   %y = and i32 %y_hi, %y_low
    479   %mask = xor i32 %m_a, %m_b
    480   %n0 = xor i32 %x, %y
    481   %n1 = and i32 %n0, %mask
    482   %r = xor i32 %y, %n1
    483   ret i32 %r
    484 }
    485 define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    486 ; CHECK-NOBMI-LABEL: in_complex_y0_m1:
    487 ; CHECK-NOBMI:       # %bb.0:
    488 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    489 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
    490 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    491 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    492 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    493 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    494 ; CHECK-NOBMI-NEXT:    retq
    495 ;
    496 ; CHECK-BMI-LABEL: in_complex_y0_m1:
    497 ; CHECK-BMI:       # %bb.0:
    498 ; CHECK-BMI-NEXT:    andl %edx, %esi
    499 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
    500 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    501 ; CHECK-BMI-NEXT:    andl %edi, %ecx
    502 ; CHECK-BMI-NEXT:    orl %ecx, %eax
    503 ; CHECK-BMI-NEXT:    retq
    504   %y = and i32 %y_hi, %y_low
    505   %mask = xor i32 %m_a, %m_b
    506   %n0 = xor i32 %x, %y
    507   %n1 = and i32 %mask, %n0
    508   %r = xor i32 %n1, %y
    509   ret i32 %r
    510 }
    511 define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
    512 ; CHECK-NOBMI-LABEL: in_complex_y1_m1:
    513 ; CHECK-NOBMI:       # %bb.0:
    514 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    515 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
    516 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    517 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
    518 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    519 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    520 ; CHECK-NOBMI-NEXT:    retq
    521 ;
    522 ; CHECK-BMI-LABEL: in_complex_y1_m1:
    523 ; CHECK-BMI:       # %bb.0:
    524 ; CHECK-BMI-NEXT:    andl %edx, %esi
    525 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
    526 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    527 ; CHECK-BMI-NEXT:    andl %edi, %ecx
    528 ; CHECK-BMI-NEXT:    orl %ecx, %eax
    529 ; CHECK-BMI-NEXT:    retq
    530   %y = and i32 %y_hi, %y_low
    531   %mask = xor i32 %m_a, %m_b
    532   %n0 = xor i32 %x, %y
    533   %n1 = and i32 %mask, %n0
    534   %r = xor i32 %y, %n1
    535   ret i32 %r
    536 }
    537 ; ============================================================================ ;
    538 ; Various cases with %x and/or %y being a constant
    539 ; ============================================================================ ;
    540 define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
    541 ; CHECK-NOBMI-LABEL: out_constant_varx_mone:
    542 ; CHECK-NOBMI:       # %bb.0:
    543 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    544 ; CHECK-NOBMI-NEXT:    notl %edx
    545 ; CHECK-NOBMI-NEXT:    orl %edx, %edi
    546 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    547 ; CHECK-NOBMI-NEXT:    retq
    548 ;
    549 ; CHECK-BMI-LABEL: out_constant_varx_mone:
    550 ; CHECK-BMI:       # %bb.0:
    551 ; CHECK-BMI-NEXT:    andl %edx, %edi
    552 ; CHECK-BMI-NEXT:    notl %edx
    553 ; CHECK-BMI-NEXT:    orl %edx, %edi
    554 ; CHECK-BMI-NEXT:    movl %edi, %eax
    555 ; CHECK-BMI-NEXT:    retq
    556   %notmask = xor i32 %mask, -1
    557   %mx = and i32 %mask, %x
    558   %my = and i32 %notmask, -1
    559   %r = or i32 %mx, %my
    560   ret i32 %r
    561 }
    562 define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
    563 ; CHECK-NOBMI-LABEL: in_constant_varx_mone:
    564 ; CHECK-NOBMI:       # %bb.0:
    565 ; CHECK-NOBMI-NEXT:    notl %edi
    566 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    567 ; CHECK-NOBMI-NEXT:    notl %edi
    568 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    569 ; CHECK-NOBMI-NEXT:    retq
    570 ;
    571 ; CHECK-BMI-LABEL: in_constant_varx_mone:
    572 ; CHECK-BMI:       # %bb.0:
    573 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
    574 ; CHECK-BMI-NEXT:    notl %eax
    575 ; CHECK-BMI-NEXT:    retq
    576   %n0 = xor i32 %x, -1 ; %x
    577   %n1 = and i32 %n0, %mask
    578   %r = xor i32 %n1, -1
    579   ret i32 %r
    580 }
    581 ; This is not a canonical form. Testing for completeness only.
    582 define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
    583 ; CHECK-NOBMI-LABEL: out_constant_varx_mone_invmask:
    584 ; CHECK-NOBMI:       # %bb.0:
    585 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    586 ; CHECK-NOBMI-NEXT:    notl %eax
    587 ; CHECK-NOBMI-NEXT:    andl %edi, %eax
    588 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
    589 ; CHECK-NOBMI-NEXT:    retq
    590 ;
    591 ; CHECK-BMI-LABEL: out_constant_varx_mone_invmask:
    592 ; CHECK-BMI:       # %bb.0:
    593 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    594 ; CHECK-BMI-NEXT:    orl %edx, %eax
    595 ; CHECK-BMI-NEXT:    retq
    596   %notmask = xor i32 %mask, -1
    597   %mx = and i32 %notmask, %x
    598   %my = and i32 %mask, -1
    599   %r = or i32 %mx, %my
    600   ret i32 %r
    601 }
    602 ; This is not a canonical form. Testing for completeness only.
    603 define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
    604 ; CHECK-NOBMI-LABEL: in_constant_varx_mone_invmask:
    605 ; CHECK-NOBMI:       # %bb.0:
    606 ; CHECK-NOBMI-NEXT:    notl %edx
    607 ; CHECK-NOBMI-NEXT:    notl %edi
    608 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    609 ; CHECK-NOBMI-NEXT:    notl %edi
    610 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    611 ; CHECK-NOBMI-NEXT:    retq
    612 ;
    613 ; CHECK-BMI-LABEL: in_constant_varx_mone_invmask:
    614 ; CHECK-BMI:       # %bb.0:
    615 ; CHECK-BMI-NEXT:    notl %edx
    616 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
    617 ; CHECK-BMI-NEXT:    notl %eax
    618 ; CHECK-BMI-NEXT:    retq
    619   %notmask = xor i32 %mask, -1
    620   %n0 = xor i32 %x, -1 ; %x
    621   %n1 = and i32 %n0, %notmask
    622   %r = xor i32 %n1, -1
    623   ret i32 %r
    624 }
    625 define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
    626 ; CHECK-NOBMI-LABEL: out_constant_varx_42:
    627 ; CHECK-NOBMI:       # %bb.0:
    628 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    629 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    630 ; CHECK-NOBMI-NEXT:    notl %eax
    631 ; CHECK-NOBMI-NEXT:    andl $42, %eax
    632 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
    633 ; CHECK-NOBMI-NEXT:    retq
    634 ;
    635 ; CHECK-BMI-LABEL: out_constant_varx_42:
    636 ; CHECK-BMI:       # %bb.0:
    637 ; CHECK-BMI-NEXT:    andl %edx, %edi
    638 ; CHECK-BMI-NEXT:    movl %edx, %eax
    639 ; CHECK-BMI-NEXT:    notl %eax
    640 ; CHECK-BMI-NEXT:    andl $42, %eax
    641 ; CHECK-BMI-NEXT:    orl %edi, %eax
    642 ; CHECK-BMI-NEXT:    retq
    643   %notmask = xor i32 %mask, -1
    644   %mx = and i32 %mask, %x
    645   %my = and i32 %notmask, 42
    646   %r = or i32 %mx, %my
    647   ret i32 %r
    648 }
    649 define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
    650 ; CHECK-NOBMI-LABEL: in_constant_varx_42:
    651 ; CHECK-NOBMI:       # %bb.0:
    652 ; CHECK-NOBMI-NEXT:    xorl $42, %edi
    653 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    654 ; CHECK-NOBMI-NEXT:    xorl $42, %edi
    655 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    656 ; CHECK-NOBMI-NEXT:    retq
    657 ;
    658 ; CHECK-BMI-LABEL: in_constant_varx_42:
    659 ; CHECK-BMI:       # %bb.0:
    660 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
    661 ; CHECK-BMI-NEXT:    orl $42, %edx
    662 ; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
    663 ; CHECK-BMI-NEXT:    retq
    664   %n0 = xor i32 %x, 42 ; %x
    665   %n1 = and i32 %n0, %mask
    666   %r = xor i32 %n1, 42
    667   ret i32 %r
    668 }
    669 ; This is not a canonical form. Testing for completeness only.
    670 define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
    671 ; CHECK-NOBMI-LABEL: out_constant_varx_42_invmask:
    672 ; CHECK-NOBMI:       # %bb.0:
    673 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    674 ; CHECK-NOBMI-NEXT:    notl %eax
    675 ; CHECK-NOBMI-NEXT:    andl %edi, %eax
    676 ; CHECK-NOBMI-NEXT:    andl $42, %edx
    677 ; CHECK-NOBMI-NEXT:    orl %eax, %edx
    678 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    679 ; CHECK-NOBMI-NEXT:    retq
    680 ;
    681 ; CHECK-BMI-LABEL: out_constant_varx_42_invmask:
    682 ; CHECK-BMI:       # %bb.0:
    683 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
    684 ; CHECK-BMI-NEXT:    andl $42, %edx
    685 ; CHECK-BMI-NEXT:    orl %edx, %eax
    686 ; CHECK-BMI-NEXT:    retq
    687   %notmask = xor i32 %mask, -1
    688   %mx = and i32 %notmask, %x
    689   %my = and i32 %mask, 42
    690   %r = or i32 %mx, %my
    691   ret i32 %r
    692 }
    693 ; This is not a canonical form. Testing for completeness only.
    694 define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
    695 ; CHECK-NOBMI-LABEL: in_constant_varx_42_invmask:
    696 ; CHECK-NOBMI:       # %bb.0:
    697 ; CHECK-NOBMI-NEXT:    notl %edx
    698 ; CHECK-NOBMI-NEXT:    xorl $42, %edi
    699 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    700 ; CHECK-NOBMI-NEXT:    xorl $42, %edi
    701 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
    702 ; CHECK-NOBMI-NEXT:    retq
    703 ;
    704 ; CHECK-BMI-LABEL: in_constant_varx_42_invmask:
    705 ; CHECK-BMI:       # %bb.0:
    706 ; CHECK-BMI-NEXT:    notl %edx
    707 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
    708 ; CHECK-BMI-NEXT:    orl $42, %edx
    709 ; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
    710 ; CHECK-BMI-NEXT:    retq
    711   %notmask = xor i32 %mask, -1
    712   %n0 = xor i32 %x, 42 ; %x
    713   %n1 = and i32 %n0, %notmask
    714   %r = xor i32 %n1, 42
    715   ret i32 %r
    716 }
    717 define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
    718 ; CHECK-NOBMI-LABEL: out_constant_mone_vary:
    719 ; CHECK-NOBMI:       # %bb.0:
    720 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    721 ; CHECK-NOBMI-NEXT:    notl %eax
    722 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
    723 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
    724 ; CHECK-NOBMI-NEXT:    retq
    725 ;
    726 ; CHECK-BMI-LABEL: out_constant_mone_vary:
    727 ; CHECK-BMI:       # %bb.0:
    728 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    729 ; CHECK-BMI-NEXT:    orl %edx, %eax
    730 ; CHECK-BMI-NEXT:    retq
    731   %notmask = xor i32 %mask, -1
    732   %mx = and i32 %mask, -1
    733   %my = and i32 %notmask, %y
    734   %r = or i32 %mx, %my
    735   ret i32 %r
    736 }
    737 define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
    738 ; CHECK-NOBMI-LABEL: in_constant_mone_vary:
    739 ; CHECK-NOBMI:       # %bb.0:
    740 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    741 ; CHECK-NOBMI-NEXT:    notl %eax
    742 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
    743 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
    744 ; CHECK-NOBMI-NEXT:    retq
    745 ;
    746 ; CHECK-BMI-LABEL: in_constant_mone_vary:
    747 ; CHECK-BMI:       # %bb.0:
    748 ; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
    749 ; CHECK-BMI-NEXT:    xorl %esi, %eax
    750 ; CHECK-BMI-NEXT:    retq
    751   %n0 = xor i32 -1, %y ; %x
    752   %n1 = and i32 %n0, %mask
    753   %r = xor i32 %n1, %y
    754   ret i32 %r
    755 }
    756 ; This is not a canonical form. Testing for completeness only.
    757 define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    758 ; CHECK-NOBMI-LABEL: out_constant_mone_vary_invmask:
    759 ; CHECK-NOBMI:       # %bb.0:
    760 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    761 ; CHECK-NOBMI-NEXT:    notl %edx
    762 ; CHECK-NOBMI-NEXT:    orl %edx, %esi
    763 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    764 ; CHECK-NOBMI-NEXT:    retq
    765 ;
    766 ; CHECK-BMI-LABEL: out_constant_mone_vary_invmask:
    767 ; CHECK-BMI:       # %bb.0:
    768 ; CHECK-BMI-NEXT:    andl %edx, %esi
    769 ; CHECK-BMI-NEXT:    notl %edx
    770 ; CHECK-BMI-NEXT:    orl %edx, %esi
    771 ; CHECK-BMI-NEXT:    movl %esi, %eax
    772 ; CHECK-BMI-NEXT:    retq
    773   %notmask = xor i32 %mask, -1
    774   %mx = and i32 %notmask, -1
    775   %my = and i32 %mask, %y
    776   %r = or i32 %mx, %my
    777   ret i32 %r
    778 }
    779 ; This is not a canonical form. Testing for completeness only.
    780 define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    781 ; CHECK-NOBMI-LABEL: in_constant_mone_vary_invmask:
    782 ; CHECK-NOBMI:       # %bb.0:
    783 ; CHECK-NOBMI-NEXT:    notl %edx
    784 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    785 ; CHECK-NOBMI-NEXT:    notl %eax
    786 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
    787 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
    788 ; CHECK-NOBMI-NEXT:    retq
    789 ;
    790 ; CHECK-BMI-LABEL: in_constant_mone_vary_invmask:
    791 ; CHECK-BMI:       # %bb.0:
    792 ; CHECK-BMI-NEXT:    notl %edx
    793 ; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
    794 ; CHECK-BMI-NEXT:    xorl %esi, %eax
    795 ; CHECK-BMI-NEXT:    retq
    796   %notmask = xor i32 %mask, -1
    797   %n0 = xor i32 -1, %y ; %x
    798   %n1 = and i32 %n0, %notmask
    799   %r = xor i32 %n1, %y
    800   ret i32 %r
    801 }
    802 define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
    803 ; CHECK-NOBMI-LABEL: out_constant_42_vary:
    804 ; CHECK-NOBMI:       # %bb.0:
    805 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
    806 ; CHECK-NOBMI-NEXT:    notl %eax
    807 ; CHECK-NOBMI-NEXT:    andl $42, %edx
    808 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
    809 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
    810 ; CHECK-NOBMI-NEXT:    retq
    811 ;
    812 ; CHECK-BMI-LABEL: out_constant_42_vary:
    813 ; CHECK-BMI:       # %bb.0:
    814 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    815 ; CHECK-BMI-NEXT:    andl $42, %edx
    816 ; CHECK-BMI-NEXT:    orl %edx, %eax
    817 ; CHECK-BMI-NEXT:    retq
    818   %notmask = xor i32 %mask, -1
    819   %mx = and i32 %mask, 42
    820   %my = and i32 %notmask, %y
    821   %r = or i32 %mx, %my
    822   ret i32 %r
    823 }
    824 define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
    825 ; CHECK-NOBMI-LABEL: in_constant_42_vary:
    826 ; CHECK-NOBMI:       # %bb.0:
    827 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    828 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
    829 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
    830 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
    831 ; CHECK-NOBMI-NEXT:    retq
    832 ;
    833 ; CHECK-BMI-LABEL: in_constant_42_vary:
    834 ; CHECK-BMI:       # %bb.0:
    835 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
    836 ; CHECK-BMI-NEXT:    andl $42, %edx
    837 ; CHECK-BMI-NEXT:    orl %edx, %eax
    838 ; CHECK-BMI-NEXT:    retq
    839   %n0 = xor i32 42, %y ; %x
    840   %n1 = and i32 %n0, %mask
    841   %r = xor i32 %n1, %y
    842   ret i32 %r
    843 }
    844 ; This is not a canonical form. Testing for completeness only.
    845 define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    846 ; CHECK-NOBMI-LABEL: out_constant_42_vary_invmask:
    847 ; CHECK-NOBMI:       # %bb.0:
    848 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
    849 ; CHECK-NOBMI-NEXT:    notl %edx
    850 ; CHECK-NOBMI-NEXT:    andl $42, %edx
    851 ; CHECK-NOBMI-NEXT:    orl %edx, %esi
    852 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    853 ; CHECK-NOBMI-NEXT:    retq
    854 ;
    855 ; CHECK-BMI-LABEL: out_constant_42_vary_invmask:
    856 ; CHECK-BMI:       # %bb.0:
    857 ; CHECK-BMI-NEXT:    andl %edx, %esi
    858 ; CHECK-BMI-NEXT:    notl %edx
    859 ; CHECK-BMI-NEXT:    andl $42, %edx
    860 ; CHECK-BMI-NEXT:    orl %edx, %esi
    861 ; CHECK-BMI-NEXT:    movl %esi, %eax
    862 ; CHECK-BMI-NEXT:    retq
    863   %notmask = xor i32 %mask, -1
    864   %mx = and i32 %notmask, 42
    865   %my = and i32 %mask, %y
    866   %r = or i32 %mx, %my
    867   ret i32 %r
    868 }
    869 ; This is not a canonical form. Testing for completeness only.
    870 define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
    871 ; CHECK-NOBMI-LABEL: in_constant_42_vary_invmask:
    872 ; CHECK-NOBMI:       # %bb.0:
    873 ; CHECK-NOBMI-NEXT:    notl %edx
    874 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
    875 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
    876 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
    877 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
    878 ; CHECK-NOBMI-NEXT:    retq
    879 ;
    880 ; CHECK-BMI-LABEL: in_constant_42_vary_invmask:
    881 ; CHECK-BMI:       # %bb.0:
    882 ; CHECK-BMI-NEXT:    andl %edx, %esi
    883 ; CHECK-BMI-NEXT:    notl %edx
    884 ; CHECK-BMI-NEXT:    andl $42, %edx
    885 ; CHECK-BMI-NEXT:    orl %esi, %edx
    886 ; CHECK-BMI-NEXT:    movl %edx, %eax
    887 ; CHECK-BMI-NEXT:    retq
    888   %notmask = xor i32 %mask, -1
    889   %n0 = xor i32 42, %y ; %x
    890   %n1 = and i32 %n0, %notmask
    891   %r = xor i32 %n1, %y
    892   ret i32 %r
    893 }
    894 ; ============================================================================ ;
    895 ; Negative tests. Should not be folded.
    896 ; ============================================================================ ;
    897 ; Multi-use tests.
    898 declare void @use32(i32) nounwind
    899 define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
    900 ; CHECK-NOBMI-LABEL: in_multiuse_A:
    901 ; CHECK-NOBMI:       # %bb.0:
    902 ; CHECK-NOBMI-NEXT:    pushq %rbp
    903 ; CHECK-NOBMI-NEXT:    pushq %rbx
    904 ; CHECK-NOBMI-NEXT:    pushq %rax
    905 ; CHECK-NOBMI-NEXT:    movl %esi, %ebx
    906 ; CHECK-NOBMI-NEXT:    movl %edi, %ebp
    907 ; CHECK-NOBMI-NEXT:    xorl %esi, %ebp
    908 ; CHECK-NOBMI-NEXT:    andl %ecx, %ebp
    909 ; CHECK-NOBMI-NEXT:    movl %ebp, %edi
    910 ; CHECK-NOBMI-NEXT:    callq use32
    911 ; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
    912 ; CHECK-NOBMI-NEXT:    movl %ebp, %eax
    913 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
    914 ; CHECK-NOBMI-NEXT:    popq %rbx
    915 ; CHECK-NOBMI-NEXT:    popq %rbp
    916 ; CHECK-NOBMI-NEXT:    retq
    917 ;
    918 ; CHECK-BMI-LABEL: in_multiuse_A:
    919 ; CHECK-BMI:       # %bb.0:
    920 ; CHECK-BMI-NEXT:    pushq %rbp
    921 ; CHECK-BMI-NEXT:    pushq %rbx
    922 ; CHECK-BMI-NEXT:    pushq %rax
    923 ; CHECK-BMI-NEXT:    movl %esi, %ebx
    924 ; CHECK-BMI-NEXT:    movl %edi, %ebp
    925 ; CHECK-BMI-NEXT:    xorl %esi, %ebp
    926 ; CHECK-BMI-NEXT:    andl %ecx, %ebp
    927 ; CHECK-BMI-NEXT:    movl %ebp, %edi
    928 ; CHECK-BMI-NEXT:    callq use32
    929 ; CHECK-BMI-NEXT:    xorl %ebx, %ebp
    930 ; CHECK-BMI-NEXT:    movl %ebp, %eax
    931 ; CHECK-BMI-NEXT:    addq $8, %rsp
    932 ; CHECK-BMI-NEXT:    popq %rbx
    933 ; CHECK-BMI-NEXT:    popq %rbp
    934 ; CHECK-BMI-NEXT:    retq
    935   %n0 = xor i32 %x, %y
    936   %n1 = and i32 %n0, %mask
    937   call void @use32(i32 %n1)
    938   %r = xor i32 %n1, %y
    939   ret i32 %r
    940 }
    941 define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
    942 ; CHECK-NOBMI-LABEL: in_multiuse_B:
    943 ; CHECK-NOBMI:       # %bb.0:
    944 ; CHECK-NOBMI-NEXT:    pushq %rbp
    945 ; CHECK-NOBMI-NEXT:    pushq %rbx
    946 ; CHECK-NOBMI-NEXT:    pushq %rax
    947 ; CHECK-NOBMI-NEXT:    movl %ecx, %ebx
    948 ; CHECK-NOBMI-NEXT:    movl %esi, %ebp
    949 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
    950 ; CHECK-NOBMI-NEXT:    andl %edi, %ebx
    951 ; CHECK-NOBMI-NEXT:    callq use32
    952 ; CHECK-NOBMI-NEXT:    xorl %ebp, %ebx
    953 ; CHECK-NOBMI-NEXT:    movl %ebx, %eax
    954 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
    955 ; CHECK-NOBMI-NEXT:    popq %rbx
    956 ; CHECK-NOBMI-NEXT:    popq %rbp
    957 ; CHECK-NOBMI-NEXT:    retq
    958 ;
    959 ; CHECK-BMI-LABEL: in_multiuse_B:
    960 ; CHECK-BMI:       # %bb.0:
    961 ; CHECK-BMI-NEXT:    pushq %rbp
    962 ; CHECK-BMI-NEXT:    pushq %rbx
    963 ; CHECK-BMI-NEXT:    pushq %rax
    964 ; CHECK-BMI-NEXT:    movl %ecx, %ebx
    965 ; CHECK-BMI-NEXT:    movl %esi, %ebp
    966 ; CHECK-BMI-NEXT:    xorl %esi, %edi
    967 ; CHECK-BMI-NEXT:    andl %edi, %ebx
    968 ; CHECK-BMI-NEXT:    callq use32
    969 ; CHECK-BMI-NEXT:    xorl %ebp, %ebx
    970 ; CHECK-BMI-NEXT:    movl %ebx, %eax
    971 ; CHECK-BMI-NEXT:    addq $8, %rsp
    972 ; CHECK-BMI-NEXT:    popq %rbx
    973 ; CHECK-BMI-NEXT:    popq %rbp
    974 ; CHECK-BMI-NEXT:    retq
    975   %n0 = xor i32 %x, %y
    976   %n1 = and i32 %n0, %mask
    977   call void @use32(i32 %n0)
    978   %r = xor i32 %n1, %y
    979   ret i32 %r
    980 }
    981 ; Various bad variants
    982 define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) {
    983 ; CHECK-NOBMI-LABEL: n0_badmask:
    984 ; CHECK-NOBMI:       # %bb.0:
    985 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
    986 ; CHECK-NOBMI-NEXT:    notl %ecx
    987 ; CHECK-NOBMI-NEXT:    andl %esi, %ecx
    988 ; CHECK-NOBMI-NEXT:    orl %edi, %ecx
    989 ; CHECK-NOBMI-NEXT:    movl %ecx, %eax
    990 ; CHECK-NOBMI-NEXT:    retq
    991 ;
    992 ; CHECK-BMI-LABEL: n0_badmask:
    993 ; CHECK-BMI:       # %bb.0:
    994 ; CHECK-BMI-NEXT:    andl %edx, %edi
    995 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
    996 ; CHECK-BMI-NEXT:    orl %edi, %eax
    997 ; CHECK-BMI-NEXT:    retq
    998   %mx = and i32 %x, %mask
    999   %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask
   1000   %my = and i32 %y, %notmask
   1001   %r = or i32 %mx, %my
   1002   ret i32 %r
   1003 }
   1004 define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) {
   1005 ; CHECK-NOBMI-LABEL: n0_badxor:
   1006 ; CHECK-NOBMI:       # %bb.0:
   1007 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
   1008 ; CHECK-NOBMI-NEXT:    xorl $1, %edx
   1009 ; CHECK-NOBMI-NEXT:    andl %esi, %edx
   1010 ; CHECK-NOBMI-NEXT:    orl %edi, %edx
   1011 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
   1012 ; CHECK-NOBMI-NEXT:    retq
   1013 ;
   1014 ; CHECK-BMI-LABEL: n0_badxor:
   1015 ; CHECK-BMI:       # %bb.0:
   1016 ; CHECK-BMI-NEXT:    andl %edx, %edi
   1017 ; CHECK-BMI-NEXT:    xorl $1, %edx
   1018 ; CHECK-BMI-NEXT:    andl %esi, %edx
   1019 ; CHECK-BMI-NEXT:    orl %edi, %edx
   1020 ; CHECK-BMI-NEXT:    movl %edx, %eax
   1021 ; CHECK-BMI-NEXT:    retq
   1022   %mx = and i32 %x, %mask
   1023   %notmask = xor i32 %mask, 1 ; instead of -1
   1024   %my = and i32 %y, %notmask
   1025   %r = or i32 %mx, %my
   1026   ret i32 %r
   1027 }
   1028 define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) {
   1029 ; CHECK-NOBMI-LABEL: n1_thirdvar:
   1030 ; CHECK-NOBMI:       # %bb.0:
   1031 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
   1032 ; CHECK-NOBMI-NEXT:    andl %ecx, %edi
   1033 ; CHECK-NOBMI-NEXT:    xorl %edx, %edi
   1034 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
   1035 ; CHECK-NOBMI-NEXT:    retq
   1036 ;
   1037 ; CHECK-BMI-LABEL: n1_thirdvar:
   1038 ; CHECK-BMI:       # %bb.0:
   1039 ; CHECK-BMI-NEXT:    xorl %esi, %edi
   1040 ; CHECK-BMI-NEXT:    andl %ecx, %edi
   1041 ; CHECK-BMI-NEXT:    xorl %edx, %edi
   1042 ; CHECK-BMI-NEXT:    movl %edi, %eax
   1043 ; CHECK-BMI-NEXT:    retq
   1044   %n0 = xor i32 %x, %y
   1045   %n1 = and i32 %n0, %mask
   1046   %r = xor i32 %n1, %z ; instead of %y
   1047   ret i32 %r
   1048 }
   1049