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 ; *Please* keep in sync with test/CodeGen/X86/extract-lowbits.ll
      5 
      6 ; https://bugs.llvm.org/show_bug.cgi?id=36419
      7 ; https://bugs.llvm.org/show_bug.cgi?id=37603
      8 ; https://bugs.llvm.org/show_bug.cgi?id=37610
      9 
     10 ; Patterns:
     11 ;   a) x &  (1 << nbits) - 1
     12 ;   b) x & ~(-1 << nbits)
     13 ;   c) x &  (-1 >> (32 - y))
     14 ;   d) x << (32 - y) >> (32 - y)
     15 ; are equivalent.
     16 
     17 ; ---------------------------------------------------------------------------- ;
     18 ; Pattern a. 32-bit
     19 ; ---------------------------------------------------------------------------- ;
     20 
     21 define i32 @bzhi32_a0(i32 %val, i32 %numlowbits) nounwind {
     22 ; CHECK-LABEL: bzhi32_a0:
     23 ; CHECK:       // %bb.0:
     24 ; CHECK-NEXT:    orr w8, wzr, #0x1
     25 ; CHECK-NEXT:    lsl w8, w8, w1
     26 ; CHECK-NEXT:    sub w8, w8, #1 // =1
     27 ; CHECK-NEXT:    and w0, w8, w0
     28 ; CHECK-NEXT:    ret
     29   %onebit = shl i32 1, %numlowbits
     30   %mask = add nsw i32 %onebit, -1
     31   %masked = and i32 %mask, %val
     32   ret i32 %masked
     33 }
     34 
     35 define i32 @bzhi32_a1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {
     36 ; CHECK-LABEL: bzhi32_a1_indexzext:
     37 ; CHECK:       // %bb.0:
     38 ; CHECK-NEXT:    orr w8, wzr, #0x1
     39 ; CHECK-NEXT:    lsl w8, w8, w1
     40 ; CHECK-NEXT:    sub w8, w8, #1 // =1
     41 ; CHECK-NEXT:    and w0, w8, w0
     42 ; CHECK-NEXT:    ret
     43   %conv = zext i8 %numlowbits to i32
     44   %onebit = shl i32 1, %conv
     45   %mask = add nsw i32 %onebit, -1
     46   %masked = and i32 %mask, %val
     47   ret i32 %masked
     48 }
     49 
     50 define i32 @bzhi32_a2_load(i32* %w, i32 %numlowbits) nounwind {
     51 ; CHECK-LABEL: bzhi32_a2_load:
     52 ; CHECK:       // %bb.0:
     53 ; CHECK-NEXT:    ldr w8, [x0]
     54 ; CHECK-NEXT:    orr w9, wzr, #0x1
     55 ; CHECK-NEXT:    lsl w9, w9, w1
     56 ; CHECK-NEXT:    sub w9, w9, #1 // =1
     57 ; CHECK-NEXT:    and w0, w9, w8
     58 ; CHECK-NEXT:    ret
     59   %val = load i32, i32* %w
     60   %onebit = shl i32 1, %numlowbits
     61   %mask = add nsw i32 %onebit, -1
     62   %masked = and i32 %mask, %val
     63   ret i32 %masked
     64 }
     65 
     66 define i32 @bzhi32_a3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind {
     67 ; CHECK-LABEL: bzhi32_a3_load_indexzext:
     68 ; CHECK:       // %bb.0:
     69 ; CHECK-NEXT:    ldr w8, [x0]
     70 ; CHECK-NEXT:    orr w9, wzr, #0x1
     71 ; CHECK-NEXT:    lsl w9, w9, w1
     72 ; CHECK-NEXT:    sub w9, w9, #1 // =1
     73 ; CHECK-NEXT:    and w0, w9, w8
     74 ; CHECK-NEXT:    ret
     75   %val = load i32, i32* %w
     76   %conv = zext i8 %numlowbits to i32
     77   %onebit = shl i32 1, %conv
     78   %mask = add nsw i32 %onebit, -1
     79   %masked = and i32 %mask, %val
     80   ret i32 %masked
     81 }
     82 
     83 define i32 @bzhi32_a4_commutative(i32 %val, i32 %numlowbits) nounwind {
     84 ; CHECK-LABEL: bzhi32_a4_commutative:
     85 ; CHECK:       // %bb.0:
     86 ; CHECK-NEXT:    orr w8, wzr, #0x1
     87 ; CHECK-NEXT:    lsl w8, w8, w1
     88 ; CHECK-NEXT:    sub w8, w8, #1 // =1
     89 ; CHECK-NEXT:    and w0, w0, w8
     90 ; CHECK-NEXT:    ret
     91   %onebit = shl i32 1, %numlowbits
     92   %mask = add nsw i32 %onebit, -1
     93   %masked = and i32 %val, %mask ; swapped order
     94   ret i32 %masked
     95 }
     96 
     97 ; 64-bit
     98 
     99 define i64 @bzhi64_a0(i64 %val, i64 %numlowbits) nounwind {
    100 ; CHECK-LABEL: bzhi64_a0:
    101 ; CHECK:       // %bb.0:
    102 ; CHECK-NEXT:    orr w8, wzr, #0x1
    103 ; CHECK-NEXT:    lsl x8, x8, x1
    104 ; CHECK-NEXT:    sub x8, x8, #1 // =1
    105 ; CHECK-NEXT:    and x0, x8, x0
    106 ; CHECK-NEXT:    ret
    107   %onebit = shl i64 1, %numlowbits
    108   %mask = add nsw i64 %onebit, -1
    109   %masked = and i64 %mask, %val
    110   ret i64 %masked
    111 }
    112 
    113 define i64 @bzhi64_a1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
    114 ; CHECK-LABEL: bzhi64_a1_indexzext:
    115 ; CHECK:       // %bb.0:
    116 ; CHECK-NEXT:    orr w8, wzr, #0x1
    117 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
    118 ; CHECK-NEXT:    lsl x8, x8, x1
    119 ; CHECK-NEXT:    sub x8, x8, #1 // =1
    120 ; CHECK-NEXT:    and x0, x8, x0
    121 ; CHECK-NEXT:    ret
    122   %conv = zext i8 %numlowbits to i64
    123   %onebit = shl i64 1, %conv
    124   %mask = add nsw i64 %onebit, -1
    125   %masked = and i64 %mask, %val
    126   ret i64 %masked
    127 }
    128 
    129 define i64 @bzhi64_a2_load(i64* %w, i64 %numlowbits) nounwind {
    130 ; CHECK-LABEL: bzhi64_a2_load:
    131 ; CHECK:       // %bb.0:
    132 ; CHECK-NEXT:    ldr x8, [x0]
    133 ; CHECK-NEXT:    orr w9, wzr, #0x1
    134 ; CHECK-NEXT:    lsl x9, x9, x1
    135 ; CHECK-NEXT:    sub x9, x9, #1 // =1
    136 ; CHECK-NEXT:    and x0, x9, x8
    137 ; CHECK-NEXT:    ret
    138   %val = load i64, i64* %w
    139   %onebit = shl i64 1, %numlowbits
    140   %mask = add nsw i64 %onebit, -1
    141   %masked = and i64 %mask, %val
    142   ret i64 %masked
    143 }
    144 
    145 define i64 @bzhi64_a3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind {
    146 ; CHECK-LABEL: bzhi64_a3_load_indexzext:
    147 ; CHECK:       // %bb.0:
    148 ; CHECK-NEXT:    ldr x8, [x0]
    149 ; CHECK-NEXT:    orr w9, wzr, #0x1
    150 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
    151 ; CHECK-NEXT:    lsl x9, x9, x1
    152 ; CHECK-NEXT:    sub x9, x9, #1 // =1
    153 ; CHECK-NEXT:    and x0, x9, x8
    154 ; CHECK-NEXT:    ret
    155   %val = load i64, i64* %w
    156   %conv = zext i8 %numlowbits to i64
    157   %onebit = shl i64 1, %conv
    158   %mask = add nsw i64 %onebit, -1
    159   %masked = and i64 %mask, %val
    160   ret i64 %masked
    161 }
    162 
    163 define i64 @bzhi64_a4_commutative(i64 %val, i64 %numlowbits) nounwind {
    164 ; CHECK-LABEL: bzhi64_a4_commutative:
    165 ; CHECK:       // %bb.0:
    166 ; CHECK-NEXT:    orr w8, wzr, #0x1
    167 ; CHECK-NEXT:    lsl x8, x8, x1
    168 ; CHECK-NEXT:    sub x8, x8, #1 // =1
    169 ; CHECK-NEXT:    and x0, x0, x8
    170 ; CHECK-NEXT:    ret
    171   %onebit = shl i64 1, %numlowbits
    172   %mask = add nsw i64 %onebit, -1
    173   %masked = and i64 %val, %mask ; swapped order
    174   ret i64 %masked
    175 }
    176 
    177 ; ---------------------------------------------------------------------------- ;
    178 ; Pattern b. 32-bit
    179 ; ---------------------------------------------------------------------------- ;
    180 
    181 define i32 @bzhi32_b0(i32 %val, i32 %numlowbits) nounwind {
    182 ; CHECK-LABEL: bzhi32_b0:
    183 ; CHECK:       // %bb.0:
    184 ; CHECK-NEXT:    mov w8, #-1
    185 ; CHECK-NEXT:    lsl w8, w8, w1
    186 ; CHECK-NEXT:    bic w0, w0, w8
    187 ; CHECK-NEXT:    ret
    188   %notmask = shl i32 -1, %numlowbits
    189   %mask = xor i32 %notmask, -1
    190   %masked = and i32 %mask, %val
    191   ret i32 %masked
    192 }
    193 
    194 define i32 @bzhi32_b1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {
    195 ; CHECK-LABEL: bzhi32_b1_indexzext:
    196 ; CHECK:       // %bb.0:
    197 ; CHECK-NEXT:    mov w8, #-1
    198 ; CHECK-NEXT:    lsl w8, w8, w1
    199 ; CHECK-NEXT:    bic w0, w0, w8
    200 ; CHECK-NEXT:    ret
    201   %conv = zext i8 %numlowbits to i32
    202   %notmask = shl i32 -1, %conv
    203   %mask = xor i32 %notmask, -1
    204   %masked = and i32 %mask, %val
    205   ret i32 %masked
    206 }
    207 
    208 define i32 @bzhi32_b2_load(i32* %w, i32 %numlowbits) nounwind {
    209 ; CHECK-LABEL: bzhi32_b2_load:
    210 ; CHECK:       // %bb.0:
    211 ; CHECK-NEXT:    ldr w8, [x0]
    212 ; CHECK-NEXT:    mov w9, #-1
    213 ; CHECK-NEXT:    lsl w9, w9, w1
    214 ; CHECK-NEXT:    bic w0, w8, w9
    215 ; CHECK-NEXT:    ret
    216   %val = load i32, i32* %w
    217   %notmask = shl i32 -1, %numlowbits
    218   %mask = xor i32 %notmask, -1
    219   %masked = and i32 %mask, %val
    220   ret i32 %masked
    221 }
    222 
    223 define i32 @bzhi32_b3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind {
    224 ; CHECK-LABEL: bzhi32_b3_load_indexzext:
    225 ; CHECK:       // %bb.0:
    226 ; CHECK-NEXT:    ldr w8, [x0]
    227 ; CHECK-NEXT:    mov w9, #-1
    228 ; CHECK-NEXT:    lsl w9, w9, w1
    229 ; CHECK-NEXT:    bic w0, w8, w9
    230 ; CHECK-NEXT:    ret
    231   %val = load i32, i32* %w
    232   %conv = zext i8 %numlowbits to i32
    233   %notmask = shl i32 -1, %conv
    234   %mask = xor i32 %notmask, -1
    235   %masked = and i32 %mask, %val
    236   ret i32 %masked
    237 }
    238 
    239 define i32 @bzhi32_b4_commutative(i32 %val, i32 %numlowbits) nounwind {
    240 ; CHECK-LABEL: bzhi32_b4_commutative:
    241 ; CHECK:       // %bb.0:
    242 ; CHECK-NEXT:    mov w8, #-1
    243 ; CHECK-NEXT:    lsl w8, w8, w1
    244 ; CHECK-NEXT:    bic w0, w0, w8
    245 ; CHECK-NEXT:    ret
    246   %notmask = shl i32 -1, %numlowbits
    247   %mask = xor i32 %notmask, -1
    248   %masked = and i32 %val, %mask ; swapped order
    249   ret i32 %masked
    250 }
    251 
    252 ; 64-bit
    253 
    254 define i64 @bzhi64_b0(i64 %val, i64 %numlowbits) nounwind {
    255 ; CHECK-LABEL: bzhi64_b0:
    256 ; CHECK:       // %bb.0:
    257 ; CHECK-NEXT:    mov x8, #-1
    258 ; CHECK-NEXT:    lsl x8, x8, x1
    259 ; CHECK-NEXT:    bic x0, x0, x8
    260 ; CHECK-NEXT:    ret
    261   %notmask = shl i64 -1, %numlowbits
    262   %mask = xor i64 %notmask, -1
    263   %masked = and i64 %mask, %val
    264   ret i64 %masked
    265 }
    266 
    267 define i64 @bzhi64_b1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
    268 ; CHECK-LABEL: bzhi64_b1_indexzext:
    269 ; CHECK:       // %bb.0:
    270 ; CHECK-NEXT:    mov x8, #-1
    271 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
    272 ; CHECK-NEXT:    lsl x8, x8, x1
    273 ; CHECK-NEXT:    bic x0, x0, x8
    274 ; CHECK-NEXT:    ret
    275   %conv = zext i8 %numlowbits to i64
    276   %notmask = shl i64 -1, %conv
    277   %mask = xor i64 %notmask, -1
    278   %masked = and i64 %mask, %val
    279   ret i64 %masked
    280 }
    281 
    282 define i64 @bzhi64_b2_load(i64* %w, i64 %numlowbits) nounwind {
    283 ; CHECK-LABEL: bzhi64_b2_load:
    284 ; CHECK:       // %bb.0:
    285 ; CHECK-NEXT:    ldr x8, [x0]
    286 ; CHECK-NEXT:    mov x9, #-1
    287 ; CHECK-NEXT:    lsl x9, x9, x1
    288 ; CHECK-NEXT:    bic x0, x8, x9
    289 ; CHECK-NEXT:    ret
    290   %val = load i64, i64* %w
    291   %notmask = shl i64 -1, %numlowbits
    292   %mask = xor i64 %notmask, -1
    293   %masked = and i64 %mask, %val
    294   ret i64 %masked
    295 }
    296 
    297 define i64 @bzhi64_b3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind {
    298 ; CHECK-LABEL: bzhi64_b3_load_indexzext:
    299 ; CHECK:       // %bb.0:
    300 ; CHECK-NEXT:    ldr x8, [x0]
    301 ; CHECK-NEXT:    mov x9, #-1
    302 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
    303 ; CHECK-NEXT:    lsl x9, x9, x1
    304 ; CHECK-NEXT:    bic x0, x8, x9
    305 ; CHECK-NEXT:    ret
    306   %val = load i64, i64* %w
    307   %conv = zext i8 %numlowbits to i64
    308   %notmask = shl i64 -1, %conv
    309   %mask = xor i64 %notmask, -1
    310   %masked = and i64 %mask, %val
    311   ret i64 %masked
    312 }
    313 
    314 define i64 @bzhi64_b4_commutative(i64 %val, i64 %numlowbits) nounwind {
    315 ; CHECK-LABEL: bzhi64_b4_commutative:
    316 ; CHECK:       // %bb.0:
    317 ; CHECK-NEXT:    mov x8, #-1
    318 ; CHECK-NEXT:    lsl x8, x8, x1
    319 ; CHECK-NEXT:    bic x0, x0, x8
    320 ; CHECK-NEXT:    ret
    321   %notmask = shl i64 -1, %numlowbits
    322   %mask = xor i64 %notmask, -1
    323   %masked = and i64 %val, %mask ; swapped order
    324   ret i64 %masked
    325 }
    326 
    327 ; ---------------------------------------------------------------------------- ;
    328 ; Pattern c. 32-bit
    329 ; ---------------------------------------------------------------------------- ;
    330 
    331 define i32 @bzhi32_c0(i32 %val, i32 %numlowbits) nounwind {
    332 ; CHECK-LABEL: bzhi32_c0:
    333 ; CHECK:       // %bb.0:
    334 ; CHECK-NEXT:    neg w8, w1
    335 ; CHECK-NEXT:    mov w9, #-1
    336 ; CHECK-NEXT:    lsr w8, w9, w8
    337 ; CHECK-NEXT:    and w0, w8, w0
    338 ; CHECK-NEXT:    ret
    339   %numhighbits = sub i32 32, %numlowbits
    340   %mask = lshr i32 -1, %numhighbits
    341   %masked = and i32 %mask, %val
    342   ret i32 %masked
    343 }
    344 
    345 define i32 @bzhi32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind {
    346 ; CHECK-LABEL: bzhi32_c1_indexzext:
    347 ; CHECK:       // %bb.0:
    348 ; CHECK-NEXT:    orr w8, wzr, #0x20
    349 ; CHECK-NEXT:    sub w8, w8, w1
    350 ; CHECK-NEXT:    mov w9, #-1
    351 ; CHECK-NEXT:    lsr w8, w9, w8
    352 ; CHECK-NEXT:    and w0, w8, w0
    353 ; CHECK-NEXT:    ret
    354   %numhighbits = sub i8 32, %numlowbits
    355   %sh_prom = zext i8 %numhighbits to i32
    356   %mask = lshr i32 -1, %sh_prom
    357   %masked = and i32 %mask, %val
    358   ret i32 %masked
    359 }
    360 
    361 define i32 @bzhi32_c2_load(i32* %w, i32 %numlowbits) nounwind {
    362 ; CHECK-LABEL: bzhi32_c2_load:
    363 ; CHECK:       // %bb.0:
    364 ; CHECK-NEXT:    ldr w8, [x0]
    365 ; CHECK-NEXT:    neg w9, w1
    366 ; CHECK-NEXT:    mov w10, #-1
    367 ; CHECK-NEXT:    lsr w9, w10, w9
    368 ; CHECK-NEXT:    and w0, w9, w8
    369 ; CHECK-NEXT:    ret
    370   %val = load i32, i32* %w
    371   %numhighbits = sub i32 32, %numlowbits
    372   %mask = lshr i32 -1, %numhighbits
    373   %masked = and i32 %mask, %val
    374   ret i32 %masked
    375 }
    376 
    377 define i32 @bzhi32_c3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
    378 ; CHECK-LABEL: bzhi32_c3_load_indexzext:
    379 ; CHECK:       // %bb.0:
    380 ; CHECK-NEXT:    ldr w8, [x0]
    381 ; CHECK-NEXT:    orr w9, wzr, #0x20
    382 ; CHECK-NEXT:    sub w9, w9, w1
    383 ; CHECK-NEXT:    mov w10, #-1
    384 ; CHECK-NEXT:    lsr w9, w10, w9
    385 ; CHECK-NEXT:    and w0, w9, w8
    386 ; CHECK-NEXT:    ret
    387   %val = load i32, i32* %w
    388   %numhighbits = sub i8 32, %numlowbits
    389   %sh_prom = zext i8 %numhighbits to i32
    390   %mask = lshr i32 -1, %sh_prom
    391   %masked = and i32 %mask, %val
    392   ret i32 %masked
    393 }
    394 
    395 define i32 @bzhi32_c4_commutative(i32 %val, i32 %numlowbits) nounwind {
    396 ; CHECK-LABEL: bzhi32_c4_commutative:
    397 ; CHECK:       // %bb.0:
    398 ; CHECK-NEXT:    neg w8, w1
    399 ; CHECK-NEXT:    mov w9, #-1
    400 ; CHECK-NEXT:    lsr w8, w9, w8
    401 ; CHECK-NEXT:    and w0, w0, w8
    402 ; CHECK-NEXT:    ret
    403   %numhighbits = sub i32 32, %numlowbits
    404   %mask = lshr i32 -1, %numhighbits
    405   %masked = and i32 %val, %mask ; swapped order
    406   ret i32 %masked
    407 }
    408 
    409 ; 64-bit
    410 
    411 define i64 @bzhi64_c0(i64 %val, i64 %numlowbits) nounwind {
    412 ; CHECK-LABEL: bzhi64_c0:
    413 ; CHECK:       // %bb.0:
    414 ; CHECK-NEXT:    neg x8, x1
    415 ; CHECK-NEXT:    mov x9, #-1
    416 ; CHECK-NEXT:    lsr x8, x9, x8
    417 ; CHECK-NEXT:    and x0, x8, x0
    418 ; CHECK-NEXT:    ret
    419   %numhighbits = sub i64 64, %numlowbits
    420   %mask = lshr i64 -1, %numhighbits
    421   %masked = and i64 %mask, %val
    422   ret i64 %masked
    423 }
    424 
    425 define i64 @bzhi64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind {
    426 ; CHECK-LABEL: bzhi64_c1_indexzext:
    427 ; CHECK:       // %bb.0:
    428 ; CHECK-NEXT:    orr w8, wzr, #0x40
    429 ; CHECK-NEXT:    sub w8, w8, w1
    430 ; CHECK-NEXT:    mov x9, #-1
    431 ; CHECK-NEXT:    lsr x8, x9, x8
    432 ; CHECK-NEXT:    and x0, x8, x0
    433 ; CHECK-NEXT:    ret
    434   %numhighbits = sub i8 64, %numlowbits
    435   %sh_prom = zext i8 %numhighbits to i64
    436   %mask = lshr i64 -1, %sh_prom
    437   %masked = and i64 %mask, %val
    438   ret i64 %masked
    439 }
    440 
    441 define i64 @bzhi64_c2_load(i64* %w, i64 %numlowbits) nounwind {
    442 ; CHECK-LABEL: bzhi64_c2_load:
    443 ; CHECK:       // %bb.0:
    444 ; CHECK-NEXT:    ldr x8, [x0]
    445 ; CHECK-NEXT:    neg x9, x1
    446 ; CHECK-NEXT:    mov x10, #-1
    447 ; CHECK-NEXT:    lsr x9, x10, x9
    448 ; CHECK-NEXT:    and x0, x9, x8
    449 ; CHECK-NEXT:    ret
    450   %val = load i64, i64* %w
    451   %numhighbits = sub i64 64, %numlowbits
    452   %mask = lshr i64 -1, %numhighbits
    453   %masked = and i64 %mask, %val
    454   ret i64 %masked
    455 }
    456 
    457 define i64 @bzhi64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
    458 ; CHECK-LABEL: bzhi64_c3_load_indexzext:
    459 ; CHECK:       // %bb.0:
    460 ; CHECK-NEXT:    ldr x8, [x0]
    461 ; CHECK-NEXT:    orr w9, wzr, #0x40
    462 ; CHECK-NEXT:    sub w9, w9, w1
    463 ; CHECK-NEXT:    mov x10, #-1
    464 ; CHECK-NEXT:    lsr x9, x10, x9
    465 ; CHECK-NEXT:    and x0, x9, x8
    466 ; CHECK-NEXT:    ret
    467   %val = load i64, i64* %w
    468   %numhighbits = sub i8 64, %numlowbits
    469   %sh_prom = zext i8 %numhighbits to i64
    470   %mask = lshr i64 -1, %sh_prom
    471   %masked = and i64 %mask, %val
    472   ret i64 %masked
    473 }
    474 
    475 define i64 @bzhi64_c4_commutative(i64 %val, i64 %numlowbits) nounwind {
    476 ; CHECK-LABEL: bzhi64_c4_commutative:
    477 ; CHECK:       // %bb.0:
    478 ; CHECK-NEXT:    neg x8, x1
    479 ; CHECK-NEXT:    mov x9, #-1
    480 ; CHECK-NEXT:    lsr x8, x9, x8
    481 ; CHECK-NEXT:    and x0, x0, x8
    482 ; CHECK-NEXT:    ret
    483   %numhighbits = sub i64 64, %numlowbits
    484   %mask = lshr i64 -1, %numhighbits
    485   %masked = and i64 %val, %mask ; swapped order
    486   ret i64 %masked
    487 }
    488 
    489 ; ---------------------------------------------------------------------------- ;
    490 ; Pattern d. 32-bit.
    491 ; ---------------------------------------------------------------------------- ;
    492 
    493 define i32 @bzhi32_d0(i32 %val, i32 %numlowbits) nounwind {
    494 ; CHECK-LABEL: bzhi32_d0:
    495 ; CHECK:       // %bb.0:
    496 ; CHECK-NEXT:    neg w8, w1
    497 ; CHECK-NEXT:    lsl w9, w0, w8
    498 ; CHECK-NEXT:    lsr w0, w9, w8
    499 ; CHECK-NEXT:    ret
    500   %numhighbits = sub i32 32, %numlowbits
    501   %highbitscleared = shl i32 %val, %numhighbits
    502   %masked = lshr i32 %highbitscleared, %numhighbits
    503   ret i32 %masked
    504 }
    505 
    506 define i32 @bzhi32_d1_indexzext(i32 %val, i8 %numlowbits) nounwind {
    507 ; CHECK-LABEL: bzhi32_d1_indexzext:
    508 ; CHECK:       // %bb.0:
    509 ; CHECK-NEXT:    orr w8, wzr, #0x20
    510 ; CHECK-NEXT:    sub w8, w8, w1
    511 ; CHECK-NEXT:    lsl w9, w0, w8
    512 ; CHECK-NEXT:    lsr w0, w9, w8
    513 ; CHECK-NEXT:    ret
    514   %numhighbits = sub i8 32, %numlowbits
    515   %sh_prom = zext i8 %numhighbits to i32
    516   %highbitscleared = shl i32 %val, %sh_prom
    517   %masked = lshr i32 %highbitscleared, %sh_prom
    518   ret i32 %masked
    519 }
    520 
    521 define i32 @bzhi32_d2_load(i32* %w, i32 %numlowbits) nounwind {
    522 ; CHECK-LABEL: bzhi32_d2_load:
    523 ; CHECK:       // %bb.0:
    524 ; CHECK-NEXT:    ldr w8, [x0]
    525 ; CHECK-NEXT:    neg w9, w1
    526 ; CHECK-NEXT:    lsl w8, w8, w9
    527 ; CHECK-NEXT:    lsr w0, w8, w9
    528 ; CHECK-NEXT:    ret
    529   %val = load i32, i32* %w
    530   %numhighbits = sub i32 32, %numlowbits
    531   %highbitscleared = shl i32 %val, %numhighbits
    532   %masked = lshr i32 %highbitscleared, %numhighbits
    533   ret i32 %masked
    534 }
    535 
    536 define i32 @bzhi32_d3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
    537 ; CHECK-LABEL: bzhi32_d3_load_indexzext:
    538 ; CHECK:       // %bb.0:
    539 ; CHECK-NEXT:    ldr w8, [x0]
    540 ; CHECK-NEXT:    orr w9, wzr, #0x20
    541 ; CHECK-NEXT:    sub w9, w9, w1
    542 ; CHECK-NEXT:    lsl w8, w8, w9
    543 ; CHECK-NEXT:    lsr w0, w8, w9
    544 ; CHECK-NEXT:    ret
    545   %val = load i32, i32* %w
    546   %numhighbits = sub i8 32, %numlowbits
    547   %sh_prom = zext i8 %numhighbits to i32
    548   %highbitscleared = shl i32 %val, %sh_prom
    549   %masked = lshr i32 %highbitscleared, %sh_prom
    550   ret i32 %masked
    551 }
    552 
    553 ; 64-bit.
    554 
    555 define i64 @bzhi64_d0(i64 %val, i64 %numlowbits) nounwind {
    556 ; CHECK-LABEL: bzhi64_d0:
    557 ; CHECK:       // %bb.0:
    558 ; CHECK-NEXT:    neg x8, x1
    559 ; CHECK-NEXT:    lsl x9, x0, x8
    560 ; CHECK-NEXT:    lsr x0, x9, x8
    561 ; CHECK-NEXT:    ret
    562   %numhighbits = sub i64 64, %numlowbits
    563   %highbitscleared = shl i64 %val, %numhighbits
    564   %masked = lshr i64 %highbitscleared, %numhighbits
    565   ret i64 %masked
    566 }
    567 
    568 define i64 @bzhi64_d1_indexzext(i64 %val, i8 %numlowbits) nounwind {
    569 ; CHECK-LABEL: bzhi64_d1_indexzext:
    570 ; CHECK:       // %bb.0:
    571 ; CHECK-NEXT:    orr w8, wzr, #0x40
    572 ; CHECK-NEXT:    sub w8, w8, w1
    573 ; CHECK-NEXT:    lsl x9, x0, x8
    574 ; CHECK-NEXT:    lsr x0, x9, x8
    575 ; CHECK-NEXT:    ret
    576   %numhighbits = sub i8 64, %numlowbits
    577   %sh_prom = zext i8 %numhighbits to i64
    578   %highbitscleared = shl i64 %val, %sh_prom
    579   %masked = lshr i64 %highbitscleared, %sh_prom
    580   ret i64 %masked
    581 }
    582 
    583 define i64 @bzhi64_d2_load(i64* %w, i64 %numlowbits) nounwind {
    584 ; CHECK-LABEL: bzhi64_d2_load:
    585 ; CHECK:       // %bb.0:
    586 ; CHECK-NEXT:    ldr x8, [x0]
    587 ; CHECK-NEXT:    neg x9, x1
    588 ; CHECK-NEXT:    lsl x8, x8, x9
    589 ; CHECK-NEXT:    lsr x0, x8, x9
    590 ; CHECK-NEXT:    ret
    591   %val = load i64, i64* %w
    592   %numhighbits = sub i64 64, %numlowbits
    593   %highbitscleared = shl i64 %val, %numhighbits
    594   %masked = lshr i64 %highbitscleared, %numhighbits
    595   ret i64 %masked
    596 }
    597 
    598 define i64 @bzhi64_d3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
    599 ; CHECK-LABEL: bzhi64_d3_load_indexzext:
    600 ; CHECK:       // %bb.0:
    601 ; CHECK-NEXT:    ldr x8, [x0]
    602 ; CHECK-NEXT:    orr w9, wzr, #0x40
    603 ; CHECK-NEXT:    sub w9, w9, w1
    604 ; CHECK-NEXT:    lsl x8, x8, x9
    605 ; CHECK-NEXT:    lsr x0, x8, x9
    606 ; CHECK-NEXT:    ret
    607   %val = load i64, i64* %w
    608   %numhighbits = sub i8 64, %numlowbits
    609   %sh_prom = zext i8 %numhighbits to i64
    610   %highbitscleared = shl i64 %val, %sh_prom
    611   %masked = lshr i64 %highbitscleared, %sh_prom
    612   ret i64 %masked
    613 }
    614 
    615 ; ---------------------------------------------------------------------------- ;
    616 ; Constant mask
    617 ; ---------------------------------------------------------------------------- ;
    618 
    619 ; 32-bit
    620 
    621 define i32 @bzhi32_constant_mask32(i32 %val) nounwind {
    622 ; CHECK-LABEL: bzhi32_constant_mask32:
    623 ; CHECK:       // %bb.0:
    624 ; CHECK-NEXT:    and w0, w0, #0x7fffffff
    625 ; CHECK-NEXT:    ret
    626   %masked = and i32 %val, 2147483647
    627   ret i32 %masked
    628 }
    629 
    630 define i32 @bzhi32_constant_mask32_load(i32* %val) nounwind {
    631 ; CHECK-LABEL: bzhi32_constant_mask32_load:
    632 ; CHECK:       // %bb.0:
    633 ; CHECK-NEXT:    ldr w8, [x0]
    634 ; CHECK-NEXT:    and w0, w8, #0x7fffffff
    635 ; CHECK-NEXT:    ret
    636   %val1 = load i32, i32* %val
    637   %masked = and i32 %val1, 2147483647
    638   ret i32 %masked
    639 }
    640 
    641 define i32 @bzhi32_constant_mask16(i32 %val) nounwind {
    642 ; CHECK-LABEL: bzhi32_constant_mask16:
    643 ; CHECK:       // %bb.0:
    644 ; CHECK-NEXT:    and w0, w0, #0x7fff
    645 ; CHECK-NEXT:    ret
    646   %masked = and i32 %val, 32767
    647   ret i32 %masked
    648 }
    649 
    650 define i32 @bzhi32_constant_mask16_load(i32* %val) nounwind {
    651 ; CHECK-LABEL: bzhi32_constant_mask16_load:
    652 ; CHECK:       // %bb.0:
    653 ; CHECK-NEXT:    ldr w8, [x0]
    654 ; CHECK-NEXT:    and w0, w8, #0x7fff
    655 ; CHECK-NEXT:    ret
    656   %val1 = load i32, i32* %val
    657   %masked = and i32 %val1, 32767
    658   ret i32 %masked
    659 }
    660 
    661 define i32 @bzhi32_constant_mask8(i32 %val) nounwind {
    662 ; CHECK-LABEL: bzhi32_constant_mask8:
    663 ; CHECK:       // %bb.0:
    664 ; CHECK-NEXT:    and w0, w0, #0x7f
    665 ; CHECK-NEXT:    ret
    666   %masked = and i32 %val, 127
    667   ret i32 %masked
    668 }
    669 
    670 define i32 @bzhi32_constant_mask8_load(i32* %val) nounwind {
    671 ; CHECK-LABEL: bzhi32_constant_mask8_load:
    672 ; CHECK:       // %bb.0:
    673 ; CHECK-NEXT:    ldr w8, [x0]
    674 ; CHECK-NEXT:    and w0, w8, #0x7f
    675 ; CHECK-NEXT:    ret
    676   %val1 = load i32, i32* %val
    677   %masked = and i32 %val1, 127
    678   ret i32 %masked
    679 }
    680 
    681 ; 64-bit
    682 
    683 define i64 @bzhi64_constant_mask64(i64 %val) nounwind {
    684 ; CHECK-LABEL: bzhi64_constant_mask64:
    685 ; CHECK:       // %bb.0:
    686 ; CHECK-NEXT:    and x0, x0, #0x3fffffffffffffff
    687 ; CHECK-NEXT:    ret
    688   %masked = and i64 %val, 4611686018427387903
    689   ret i64 %masked
    690 }
    691 
    692 define i64 @bzhi64_constant_mask64_load(i64* %val) nounwind {
    693 ; CHECK-LABEL: bzhi64_constant_mask64_load:
    694 ; CHECK:       // %bb.0:
    695 ; CHECK-NEXT:    ldr x8, [x0]
    696 ; CHECK-NEXT:    and x0, x8, #0x3fffffffffffffff
    697 ; CHECK-NEXT:    ret
    698   %val1 = load i64, i64* %val
    699   %masked = and i64 %val1, 4611686018427387903
    700   ret i64 %masked
    701 }
    702 
    703 define i64 @bzhi64_constant_mask32(i64 %val) nounwind {
    704 ; CHECK-LABEL: bzhi64_constant_mask32:
    705 ; CHECK:       // %bb.0:
    706 ; CHECK-NEXT:    and x0, x0, #0x7fffffff
    707 ; CHECK-NEXT:    ret
    708   %masked = and i64 %val, 2147483647
    709   ret i64 %masked
    710 }
    711 
    712 define i64 @bzhi64_constant_mask32_load(i64* %val) nounwind {
    713 ; CHECK-LABEL: bzhi64_constant_mask32_load:
    714 ; CHECK:       // %bb.0:
    715 ; CHECK-NEXT:    ldr x8, [x0]
    716 ; CHECK-NEXT:    and x0, x8, #0x7fffffff
    717 ; CHECK-NEXT:    ret
    718   %val1 = load i64, i64* %val
    719   %masked = and i64 %val1, 2147483647
    720   ret i64 %masked
    721 }
    722 
    723 define i64 @bzhi64_constant_mask16(i64 %val) nounwind {
    724 ; CHECK-LABEL: bzhi64_constant_mask16:
    725 ; CHECK:       // %bb.0:
    726 ; CHECK-NEXT:    and x0, x0, #0x7fff
    727 ; CHECK-NEXT:    ret
    728   %masked = and i64 %val, 32767
    729   ret i64 %masked
    730 }
    731 
    732 define i64 @bzhi64_constant_mask16_load(i64* %val) nounwind {
    733 ; CHECK-LABEL: bzhi64_constant_mask16_load:
    734 ; CHECK:       // %bb.0:
    735 ; CHECK-NEXT:    ldr x8, [x0]
    736 ; CHECK-NEXT:    and x0, x8, #0x7fff
    737 ; CHECK-NEXT:    ret
    738   %val1 = load i64, i64* %val
    739   %masked = and i64 %val1, 32767
    740   ret i64 %masked
    741 }
    742 
    743 define i64 @bzhi64_constant_mask8(i64 %val) nounwind {
    744 ; CHECK-LABEL: bzhi64_constant_mask8:
    745 ; CHECK:       // %bb.0:
    746 ; CHECK-NEXT:    and x0, x0, #0x7f
    747 ; CHECK-NEXT:    ret
    748   %masked = and i64 %val, 127
    749   ret i64 %masked
    750 }
    751 
    752 define i64 @bzhi64_constant_mask8_load(i64* %val) nounwind {
    753 ; CHECK-LABEL: bzhi64_constant_mask8_load:
    754 ; CHECK:       // %bb.0:
    755 ; CHECK-NEXT:    ldr x8, [x0]
    756 ; CHECK-NEXT:    and x0, x8, #0x7f
    757 ; CHECK-NEXT:    ret
    758   %val1 = load i64, i64* %val
    759   %masked = and i64 %val1, 127
    760   ret i64 %masked
    761 }
    762