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-unknown -mattr=+tbm < %s | FileCheck %s
      3 
      4 ; TODO - Patterns fail to fold with ZF flags and prevents TBM instruction selection.
      5 
      6 define i32 @test_x86_tbm_bextri_u32(i32 %a) nounwind {
      7 ; CHECK-LABEL: test_x86_tbm_bextri_u32:
      8 ; CHECK:       # %bb.0:
      9 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
     10 ; CHECK-NEXT:    retq
     11   %t0 = lshr i32 %a, 4
     12   %t1 = and i32 %t0, 4095
     13   ret i32 %t1
     14 }
     15 
     16 ; Make sure we still use AH subreg trick for extracting bits 15:8
     17 define i32 @test_x86_tbm_bextri_u32_subreg(i32 %a) nounwind {
     18 ; CHECK-LABEL: test_x86_tbm_bextri_u32_subreg:
     19 ; CHECK:       # %bb.0:
     20 ; CHECK-NEXT:    movl %edi, %eax
     21 ; CHECK-NEXT:    movzbl %ah, %eax
     22 ; CHECK-NEXT:    retq
     23   %t0 = lshr i32 %a, 8
     24   %t1 = and i32 %t0, 255
     25   ret i32 %t1
     26 }
     27 
     28 define i32 @test_x86_tbm_bextri_u32_m(i32* nocapture %a) nounwind {
     29 ; CHECK-LABEL: test_x86_tbm_bextri_u32_m:
     30 ; CHECK:       # %bb.0:
     31 ; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
     32 ; CHECK-NEXT:    retq
     33   %t0 = load i32, i32* %a
     34   %t1 = lshr i32 %t0, 4
     35   %t2 = and i32 %t1, 4095
     36   ret i32 %t2
     37 }
     38 
     39 define i32 @test_x86_tbm_bextri_u32_z(i32 %a, i32 %b) nounwind {
     40 ; CHECK-LABEL: test_x86_tbm_bextri_u32_z:
     41 ; CHECK:       # %bb.0:
     42 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
     43 ; CHECK-NEXT:    cmovel %esi, %eax
     44 ; CHECK-NEXT:    retq
     45   %t0 = lshr i32 %a, 4
     46   %t1 = and i32 %t0, 4095
     47   %t2 = icmp eq i32 %t1, 0
     48   %t3 = select i1 %t2, i32 %b, i32 %t1
     49   ret i32 %t3
     50 }
     51 
     52 define i32 @test_x86_tbm_bextri_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
     53 ; CHECK-LABEL: test_x86_tbm_bextri_u32_z2:
     54 ; CHECK:       # %bb.0:
     55 ; CHECK-NEXT:    shrl $4, %edi
     56 ; CHECK-NEXT:    testl $4095, %edi # imm = 0xFFF
     57 ; CHECK-NEXT:    cmovnel %edx, %esi
     58 ; CHECK-NEXT:    movl %esi, %eax
     59 ; CHECK-NEXT:    retq
     60   %t0 = lshr i32 %a, 4
     61   %t1 = and i32 %t0, 4095
     62   %t2 = icmp eq i32 %t1, 0
     63   %t3 = select i1 %t2, i32 %b, i32 %c
     64   ret i32 %t3
     65 }
     66 
     67 define i64 @test_x86_tbm_bextri_u64(i64 %a) nounwind {
     68 ; CHECK-LABEL: test_x86_tbm_bextri_u64:
     69 ; CHECK:       # %bb.0:
     70 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
     71 ; CHECK-NEXT:    retq
     72   %t0 = lshr i64 %a, 4
     73   %t1 = and i64 %t0, 4095
     74   ret i64 %t1
     75 }
     76 
     77 ; Make sure we still use AH subreg trick for extracting bits 15:8
     78 define i64 @test_x86_tbm_bextri_u64_subreg(i64 %a) nounwind {
     79 ; CHECK-LABEL: test_x86_tbm_bextri_u64_subreg:
     80 ; CHECK:       # %bb.0:
     81 ; CHECK-NEXT:    movq %rdi, %rax
     82 ; CHECK-NEXT:    movzbl %ah, %eax
     83 ; CHECK-NEXT:    retq
     84   %t0 = lshr i64 %a, 8
     85   %t1 = and i64 %t0, 255
     86   ret i64 %t1
     87 }
     88 
     89 define i64 @test_x86_tbm_bextri_u64_m(i64* nocapture %a) nounwind {
     90 ; CHECK-LABEL: test_x86_tbm_bextri_u64_m:
     91 ; CHECK:       # %bb.0:
     92 ; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
     93 ; CHECK-NEXT:    retq
     94   %t0 = load i64, i64* %a
     95   %t1 = lshr i64 %t0, 4
     96   %t2 = and i64 %t1, 4095
     97   ret i64 %t2
     98 }
     99 
    100 define i64 @test_x86_tbm_bextri_u64_z(i64 %a, i64 %b) nounwind {
    101 ; CHECK-LABEL: test_x86_tbm_bextri_u64_z:
    102 ; CHECK:       # %bb.0:
    103 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
    104 ; CHECK-NEXT:    cmoveq %rsi, %rax
    105 ; CHECK-NEXT:    retq
    106   %t0 = lshr i64 %a, 4
    107   %t1 = and i64 %t0, 4095
    108   %t2 = icmp eq i64 %t1, 0
    109   %t3 = select i1 %t2, i64 %b, i64 %t1
    110   ret i64 %t3
    111 }
    112 
    113 define i64 @test_x86_tbm_bextri_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    114 ; CHECK-LABEL: test_x86_tbm_bextri_u64_z2:
    115 ; CHECK:       # %bb.0:
    116 ; CHECK-NEXT:    shrl $4, %edi
    117 ; CHECK-NEXT:    testl $4095, %edi # imm = 0xFFF
    118 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    119 ; CHECK-NEXT:    movq %rsi, %rax
    120 ; CHECK-NEXT:    retq
    121   %t0 = lshr i64 %a, 4
    122   %t1 = and i64 %t0, 4095
    123   %t2 = icmp eq i64 %t1, 0
    124   %t3 = select i1 %t2, i64 %b, i64 %c
    125   ret i64 %t3
    126 }
    127 
    128 define i32 @test_x86_tbm_blcfill_u32(i32 %a) nounwind {
    129 ; CHECK-LABEL: test_x86_tbm_blcfill_u32:
    130 ; CHECK:       # %bb.0:
    131 ; CHECK-NEXT:    blcfilll %edi, %eax
    132 ; CHECK-NEXT:    retq
    133   %t0 = add i32 %a, 1
    134   %t1 = and i32 %t0, %a
    135   ret i32 %t1
    136 }
    137 
    138 define i32 @test_x86_tbm_blcfill_u32_z(i32 %a, i32 %b) nounwind {
    139 ; CHECK-LABEL: test_x86_tbm_blcfill_u32_z:
    140 ; CHECK:       # %bb.0:
    141 ; CHECK-NEXT:    blcfilll %edi, %eax
    142 ; CHECK-NEXT:    cmovel %esi, %eax
    143 ; CHECK-NEXT:    retq
    144   %t0 = add i32 %a, 1
    145   %t1 = and i32 %t0, %a
    146   %t2 = icmp eq i32 %t1, 0
    147   %t3 = select i1 %t2, i32 %b, i32 %t1
    148   ret i32 %t3
    149 }
    150 
    151 define i32 @test_x86_tbm_blcfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    152 ; CHECK-LABEL: test_x86_tbm_blcfill_u32_z2:
    153 ; CHECK:       # %bb.0:
    154 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    155 ; CHECK-NEXT:    leal 1(%rdi), %eax
    156 ; CHECK-NEXT:    testl %edi, %eax
    157 ; CHECK-NEXT:    cmovnel %edx, %esi
    158 ; CHECK-NEXT:    movl %esi, %eax
    159 ; CHECK-NEXT:    retq
    160   %t0 = add i32 %a, 1
    161   %t1 = and i32 %t0, %a
    162   %t2 = icmp eq i32 %t1, 0
    163   %t3 = select i1 %t2, i32 %b, i32 %c
    164   ret i32 %t3
    165 }
    166 
    167 define i64 @test_x86_tbm_blcfill_u64(i64 %a) nounwind {
    168 ; CHECK-LABEL: test_x86_tbm_blcfill_u64:
    169 ; CHECK:       # %bb.0:
    170 ; CHECK-NEXT:    blcfillq %rdi, %rax
    171 ; CHECK-NEXT:    retq
    172   %t0 = add i64 %a, 1
    173   %t1 = and i64 %t0, %a
    174   ret i64 %t1
    175 }
    176 
    177 define i64 @test_x86_tbm_blcfill_u64_z(i64 %a, i64 %b) nounwind {
    178 ; CHECK-LABEL: test_x86_tbm_blcfill_u64_z:
    179 ; CHECK:       # %bb.0:
    180 ; CHECK-NEXT:    blcfillq %rdi, %rax
    181 ; CHECK-NEXT:    cmoveq %rsi, %rax
    182 ; CHECK-NEXT:    retq
    183   %t0 = add i64 %a, 1
    184   %t1 = and i64 %t0, %a
    185   %t2 = icmp eq i64 %t1, 0
    186   %t3 = select i1 %t2, i64 %b, i64 %t1
    187   ret i64 %t3
    188 }
    189 
    190 define i64 @test_x86_tbm_blcfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    191 ; CHECK-LABEL: test_x86_tbm_blcfill_u64_z2:
    192 ; CHECK:       # %bb.0:
    193 ; CHECK-NEXT:    leaq 1(%rdi), %rax
    194 ; CHECK-NEXT:    testq %rdi, %rax
    195 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    196 ; CHECK-NEXT:    movq %rsi, %rax
    197 ; CHECK-NEXT:    retq
    198   %t0 = add i64 %a, 1
    199   %t1 = and i64 %t0, %a
    200   %t2 = icmp eq i64 %t1, 0
    201   %t3 = select i1 %t2, i64 %b, i64 %c
    202   ret i64 %t3
    203 }
    204 
    205 define i32 @test_x86_tbm_blci_u32(i32 %a) nounwind {
    206 ; CHECK-LABEL: test_x86_tbm_blci_u32:
    207 ; CHECK:       # %bb.0:
    208 ; CHECK-NEXT:    blcil %edi, %eax
    209 ; CHECK-NEXT:    retq
    210   %t0 = add i32 1, %a
    211   %t1 = xor i32 %t0, -1
    212   %t2 = or i32 %t1, %a
    213   ret i32 %t2
    214 }
    215 
    216 define i32 @test_x86_tbm_blci_u32_z(i32 %a, i32 %b) nounwind {
    217 ; CHECK-LABEL: test_x86_tbm_blci_u32_z:
    218 ; CHECK:       # %bb.0:
    219 ; CHECK-NEXT:    blcil %edi, %eax
    220 ; CHECK-NEXT:    cmovel %esi, %eax
    221 ; CHECK-NEXT:    retq
    222   %t0 = add i32 1, %a
    223   %t1 = xor i32 %t0, -1
    224   %t2 = or i32 %t1, %a
    225   %t3 = icmp eq i32 %t2, 0
    226   %t4 = select i1 %t3, i32 %b, i32 %t2
    227   ret i32 %t4
    228 }
    229 
    230 define i32 @test_x86_tbm_blci_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    231 ; CHECK-LABEL: test_x86_tbm_blci_u32_z2:
    232 ; CHECK:       # %bb.0:
    233 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    234 ; CHECK-NEXT:    leal 1(%rdi), %eax
    235 ; CHECK-NEXT:    notl %eax
    236 ; CHECK-NEXT:    orl %edi, %eax
    237 ; CHECK-NEXT:    cmovnel %edx, %esi
    238 ; CHECK-NEXT:    movl %esi, %eax
    239 ; CHECK-NEXT:    retq
    240   %t0 = add i32 1, %a
    241   %t1 = xor i32 %t0, -1
    242   %t2 = or i32 %t1, %a
    243   %t3 = icmp eq i32 %t2, 0
    244   %t4 = select i1 %t3, i32 %b, i32 %c
    245   ret i32 %t4
    246 }
    247 
    248 define i64 @test_x86_tbm_blci_u64(i64 %a) nounwind {
    249 ; CHECK-LABEL: test_x86_tbm_blci_u64:
    250 ; CHECK:       # %bb.0:
    251 ; CHECK-NEXT:    blciq %rdi, %rax
    252 ; CHECK-NEXT:    retq
    253   %t0 = add i64 1, %a
    254   %t1 = xor i64 %t0, -1
    255   %t2 = or i64 %t1, %a
    256   ret i64 %t2
    257 }
    258 
    259 define i64 @test_x86_tbm_blci_u64_z(i64 %a, i64 %b) nounwind {
    260 ; CHECK-LABEL: test_x86_tbm_blci_u64_z:
    261 ; CHECK:       # %bb.0:
    262 ; CHECK-NEXT:    blciq %rdi, %rax
    263 ; CHECK-NEXT:    cmoveq %rsi, %rax
    264 ; CHECK-NEXT:    retq
    265   %t0 = add i64 1, %a
    266   %t1 = xor i64 %t0, -1
    267   %t2 = or i64 %t1, %a
    268   %t3 = icmp eq i64 %t2, 0
    269   %t4 = select i1 %t3, i64 %b, i64 %t2
    270   ret i64 %t4
    271 }
    272 
    273 define i64 @test_x86_tbm_blci_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    274 ; CHECK-LABEL: test_x86_tbm_blci_u64_z2:
    275 ; CHECK:       # %bb.0:
    276 ; CHECK-NEXT:    leaq 1(%rdi), %rax
    277 ; CHECK-NEXT:    notq %rax
    278 ; CHECK-NEXT:    orq %rdi, %rax
    279 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    280 ; CHECK-NEXT:    movq %rsi, %rax
    281 ; CHECK-NEXT:    retq
    282   %t0 = add i64 1, %a
    283   %t1 = xor i64 %t0, -1
    284   %t2 = or i64 %t1, %a
    285   %t3 = icmp eq i64 %t2, 0
    286   %t4 = select i1 %t3, i64 %b, i64 %c
    287   ret i64 %t4
    288 }
    289 
    290 define i32 @test_x86_tbm_blci_u32_b(i32 %a) nounwind {
    291 ; CHECK-LABEL: test_x86_tbm_blci_u32_b:
    292 ; CHECK:       # %bb.0:
    293 ; CHECK-NEXT:    blcil %edi, %eax
    294 ; CHECK-NEXT:    retq
    295   %t0 = sub i32 -2, %a
    296   %t1 = or i32 %t0, %a
    297   ret i32 %t1
    298 }
    299 
    300 define i64 @test_x86_tbm_blci_u64_b(i64 %a) nounwind {
    301 ; CHECK-LABEL: test_x86_tbm_blci_u64_b:
    302 ; CHECK:       # %bb.0:
    303 ; CHECK-NEXT:    blciq %rdi, %rax
    304 ; CHECK-NEXT:    retq
    305   %t0 = sub i64 -2, %a
    306   %t1 = or i64 %t0, %a
    307   ret i64 %t1
    308 }
    309 
    310 define i32 @test_x86_tbm_blcic_u32(i32 %a) nounwind {
    311 ; CHECK-LABEL: test_x86_tbm_blcic_u32:
    312 ; CHECK:       # %bb.0:
    313 ; CHECK-NEXT:    blcicl %edi, %eax
    314 ; CHECK-NEXT:    retq
    315   %t0 = xor i32 %a, -1
    316   %t1 = add i32 %a, 1
    317   %t2 = and i32 %t1, %t0
    318   ret i32 %t2
    319 }
    320 
    321 define i32 @test_x86_tbm_blcic_u32_z(i32 %a, i32 %b) nounwind {
    322 ; CHECK-LABEL: test_x86_tbm_blcic_u32_z:
    323 ; CHECK:       # %bb.0:
    324 ; CHECK-NEXT:    blcicl %edi, %eax
    325 ; CHECK-NEXT:    cmovel %esi, %eax
    326 ; CHECK-NEXT:    retq
    327   %t0 = xor i32 %a, -1
    328   %t1 = add i32 %a, 1
    329   %t2 = and i32 %t1, %t0
    330   %t3 = icmp eq i32 %t2, 0
    331   %t4 = select i1 %t3, i32 %b, i32 %t2
    332   ret i32 %t4
    333 }
    334 
    335 define i32 @test_x86_tbm_blcic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    336 ; CHECK-LABEL: test_x86_tbm_blcic_u32_z2:
    337 ; CHECK:       # %bb.0:
    338 ; CHECK-NEXT:    movl %edi, %eax
    339 ; CHECK-NEXT:    notl %eax
    340 ; CHECK-NEXT:    incl %edi
    341 ; CHECK-NEXT:    testl %eax, %edi
    342 ; CHECK-NEXT:    cmovnel %edx, %esi
    343 ; CHECK-NEXT:    movl %esi, %eax
    344 ; CHECK-NEXT:    retq
    345   %t0 = xor i32 %a, -1
    346   %t1 = add i32 %a, 1
    347   %t2 = and i32 %t1, %t0
    348   %t3 = icmp eq i32 %t2, 0
    349   %t4 = select i1 %t3, i32 %b, i32 %c
    350   ret i32 %t4
    351 }
    352 
    353 define i64 @test_x86_tbm_blcic_u64(i64 %a) nounwind {
    354 ; CHECK-LABEL: test_x86_tbm_blcic_u64:
    355 ; CHECK:       # %bb.0:
    356 ; CHECK-NEXT:    blcicq %rdi, %rax
    357 ; CHECK-NEXT:    retq
    358   %t0 = xor i64 %a, -1
    359   %t1 = add i64 %a, 1
    360   %t2 = and i64 %t1, %t0
    361   ret i64 %t2
    362 }
    363 
    364 define i64 @test_x86_tbm_blcic_u64_z(i64 %a, i64 %b) nounwind {
    365 ; CHECK-LABEL: test_x86_tbm_blcic_u64_z:
    366 ; CHECK:       # %bb.0:
    367 ; CHECK-NEXT:    blcicq %rdi, %rax
    368 ; CHECK-NEXT:    cmoveq %rsi, %rax
    369 ; CHECK-NEXT:    retq
    370   %t0 = xor i64 %a, -1
    371   %t1 = add i64 %a, 1
    372   %t2 = and i64 %t1, %t0
    373   %t3 = icmp eq i64 %t2, 0
    374   %t4 = select i1 %t3, i64 %b, i64 %t2
    375   ret i64 %t4
    376 }
    377 
    378 define i64 @test_x86_tbm_blcic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    379 ; CHECK-LABEL: test_x86_tbm_blcic_u64_z2:
    380 ; CHECK:       # %bb.0:
    381 ; CHECK-NEXT:    movq %rdi, %rax
    382 ; CHECK-NEXT:    notq %rax
    383 ; CHECK-NEXT:    incq %rdi
    384 ; CHECK-NEXT:    testq %rax, %rdi
    385 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    386 ; CHECK-NEXT:    movq %rsi, %rax
    387 ; CHECK-NEXT:    retq
    388   %t0 = xor i64 %a, -1
    389   %t1 = add i64 %a, 1
    390   %t2 = and i64 %t1, %t0
    391   %t3 = icmp eq i64 %t2, 0
    392   %t4 = select i1 %t3, i64 %b, i64 %c
    393   ret i64 %t4
    394 }
    395 
    396 define i32 @test_x86_tbm_blcmsk_u32(i32 %a) nounwind {
    397 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32:
    398 ; CHECK:       # %bb.0:
    399 ; CHECK-NEXT:    blcmskl %edi, %eax
    400 ; CHECK-NEXT:    retq
    401   %t0 = add i32 %a, 1
    402   %t1 = xor i32 %t0, %a
    403   ret i32 %t1
    404 }
    405 
    406 define i32 @test_x86_tbm_blcmsk_u32_z(i32 %a, i32 %b) nounwind {
    407 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z:
    408 ; CHECK:       # %bb.0:
    409 ; CHECK-NEXT:    blcmskl %edi, %eax
    410 ; CHECK-NEXT:    cmovel %esi, %eax
    411 ; CHECK-NEXT:    retq
    412   %t0 = add i32 %a, 1
    413   %t1 = xor i32 %t0, %a
    414   %t2 = icmp eq i32 %t1, 0
    415   %t3 = select i1 %t2, i32 %b, i32 %t1
    416   ret i32 %t3
    417 }
    418 
    419 define i32 @test_x86_tbm_blcmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    420 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z2:
    421 ; CHECK:       # %bb.0:
    422 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    423 ; CHECK-NEXT:    leal 1(%rdi), %eax
    424 ; CHECK-NEXT:    xorl %edi, %eax
    425 ; CHECK-NEXT:    cmovnel %edx, %esi
    426 ; CHECK-NEXT:    movl %esi, %eax
    427 ; CHECK-NEXT:    retq
    428   %t0 = add i32 %a, 1
    429   %t1 = xor i32 %t0, %a
    430   %t2 = icmp eq i32 %t1, 0
    431   %t3 = select i1 %t2, i32 %b, i32 %c
    432   ret i32 %t3
    433 }
    434 
    435 define i64 @test_x86_tbm_blcmsk_u64(i64 %a) nounwind {
    436 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64:
    437 ; CHECK:       # %bb.0:
    438 ; CHECK-NEXT:    blcmskq %rdi, %rax
    439 ; CHECK-NEXT:    retq
    440   %t0 = add i64 %a, 1
    441   %t1 = xor i64 %t0, %a
    442   ret i64 %t1
    443 }
    444 
    445 define i64 @test_x86_tbm_blcmsk_u64_z(i64 %a, i64 %b) nounwind {
    446 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z:
    447 ; CHECK:       # %bb.0:
    448 ; CHECK-NEXT:    blcmskq %rdi, %rax
    449 ; CHECK-NEXT:    cmoveq %rsi, %rax
    450 ; CHECK-NEXT:    retq
    451   %t0 = add i64 %a, 1
    452   %t1 = xor i64 %t0, %a
    453   %t2 = icmp eq i64 %t1, 0
    454   %t3 = select i1 %t2, i64 %b, i64 %t1
    455   ret i64 %t3
    456 }
    457 
    458 define i64 @test_x86_tbm_blcmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    459 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z2:
    460 ; CHECK:       # %bb.0:
    461 ; CHECK-NEXT:    leaq 1(%rdi), %rax
    462 ; CHECK-NEXT:    xorq %rdi, %rax
    463 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    464 ; CHECK-NEXT:    movq %rsi, %rax
    465 ; CHECK-NEXT:    retq
    466   %t0 = add i64 %a, 1
    467   %t1 = xor i64 %t0, %a
    468   %t2 = icmp eq i64 %t1, 0
    469   %t3 = select i1 %t2, i64 %b, i64 %c
    470   ret i64 %t3
    471 }
    472 
    473 define i32 @test_x86_tbm_blcs_u32(i32 %a) nounwind {
    474 ; CHECK-LABEL: test_x86_tbm_blcs_u32:
    475 ; CHECK:       # %bb.0:
    476 ; CHECK-NEXT:    blcsl %edi, %eax
    477 ; CHECK-NEXT:    retq
    478   %t0 = add i32 %a, 1
    479   %t1 = or i32 %t0, %a
    480   ret i32 %t1
    481 }
    482 
    483 define i32 @test_x86_tbm_blcs_u32_z(i32 %a, i32 %b) nounwind {
    484 ; CHECK-LABEL: test_x86_tbm_blcs_u32_z:
    485 ; CHECK:       # %bb.0:
    486 ; CHECK-NEXT:    blcsl %edi, %eax
    487 ; CHECK-NEXT:    cmovel %esi, %eax
    488 ; CHECK-NEXT:    retq
    489   %t0 = add i32 %a, 1
    490   %t1 = or i32 %t0, %a
    491   %t2 = icmp eq i32 %t1, 0
    492   %t3 = select i1 %t2, i32 %b, i32 %t1
    493   ret i32 %t3
    494 }
    495 
    496 define i32 @test_x86_tbm_blcs_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    497 ; CHECK-LABEL: test_x86_tbm_blcs_u32_z2:
    498 ; CHECK:       # %bb.0:
    499 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    500 ; CHECK-NEXT:    leal 1(%rdi), %eax
    501 ; CHECK-NEXT:    orl %edi, %eax
    502 ; CHECK-NEXT:    cmovnel %edx, %esi
    503 ; CHECK-NEXT:    movl %esi, %eax
    504 ; CHECK-NEXT:    retq
    505   %t0 = add i32 %a, 1
    506   %t1 = or i32 %t0, %a
    507   %t2 = icmp eq i32 %t1, 0
    508   %t3 = select i1 %t2, i32 %b, i32 %c
    509   ret i32 %t3
    510 }
    511 
    512 define i64 @test_x86_tbm_blcs_u64(i64 %a) nounwind {
    513 ; CHECK-LABEL: test_x86_tbm_blcs_u64:
    514 ; CHECK:       # %bb.0:
    515 ; CHECK-NEXT:    blcsq %rdi, %rax
    516 ; CHECK-NEXT:    retq
    517   %t0 = add i64 %a, 1
    518   %t1 = or i64 %t0, %a
    519   ret i64 %t1
    520 }
    521 
    522 define i64 @test_x86_tbm_blcs_u64_z(i64 %a, i64 %b) nounwind {
    523 ; CHECK-LABEL: test_x86_tbm_blcs_u64_z:
    524 ; CHECK:       # %bb.0:
    525 ; CHECK-NEXT:    blcsq %rdi, %rax
    526 ; CHECK-NEXT:    cmoveq %rsi, %rax
    527 ; CHECK-NEXT:    retq
    528   %t0 = add i64 %a, 1
    529   %t1 = or i64 %t0, %a
    530   %t2 = icmp eq i64 %t1, 0
    531   %t3 = select i1 %t2, i64 %b, i64 %t1
    532   ret i64 %t3
    533 }
    534 
    535 define i64 @test_x86_tbm_blcs_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    536 ; CHECK-LABEL: test_x86_tbm_blcs_u64_z2:
    537 ; CHECK:       # %bb.0:
    538 ; CHECK-NEXT:    leaq 1(%rdi), %rax
    539 ; CHECK-NEXT:    orq %rdi, %rax
    540 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    541 ; CHECK-NEXT:    movq %rsi, %rax
    542 ; CHECK-NEXT:    retq
    543   %t0 = add i64 %a, 1
    544   %t1 = or i64 %t0, %a
    545   %t2 = icmp eq i64 %t1, 0
    546   %t3 = select i1 %t2, i64 %b, i64 %c
    547   ret i64 %t3
    548 }
    549 
    550 define i32 @test_x86_tbm_blsfill_u32(i32 %a) nounwind {
    551 ; CHECK-LABEL: test_x86_tbm_blsfill_u32:
    552 ; CHECK:       # %bb.0:
    553 ; CHECK-NEXT:    blsfilll %edi, %eax
    554 ; CHECK-NEXT:    retq
    555   %t0 = add i32 %a, -1
    556   %t1 = or i32 %t0, %a
    557   ret i32 %t1
    558 }
    559 
    560 define i32 @test_x86_tbm_blsfill_u32_z(i32 %a, i32 %b) nounwind {
    561 ; CHECK-LABEL: test_x86_tbm_blsfill_u32_z:
    562 ; CHECK:       # %bb.0:
    563 ; CHECK-NEXT:    blsfilll %edi, %eax
    564 ; CHECK-NEXT:    cmovel %esi, %eax
    565 ; CHECK-NEXT:    retq
    566   %t0 = add i32 %a, -1
    567   %t1 = or i32 %t0, %a
    568   %t2 = icmp eq i32 %t1, 0
    569   %t3 = select i1 %t2, i32 %b, i32 %t1
    570   ret i32 %t3
    571 }
    572 
    573 define i32 @test_x86_tbm_blsfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    574 ; CHECK-LABEL: test_x86_tbm_blsfill_u32_z2:
    575 ; CHECK:       # %bb.0:
    576 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    577 ; CHECK-NEXT:    leal -1(%rdi), %eax
    578 ; CHECK-NEXT:    orl %edi, %eax
    579 ; CHECK-NEXT:    cmovnel %edx, %esi
    580 ; CHECK-NEXT:    movl %esi, %eax
    581 ; CHECK-NEXT:    retq
    582   %t0 = add i32 %a, -1
    583   %t1 = or i32 %t0, %a
    584   %t2 = icmp eq i32 %t1, 0
    585   %t3 = select i1 %t2, i32 %b, i32 %c
    586   ret i32 %t3
    587 }
    588 
    589 define i64 @test_x86_tbm_blsfill_u64(i64 %a) nounwind {
    590 ; CHECK-LABEL: test_x86_tbm_blsfill_u64:
    591 ; CHECK:       # %bb.0:
    592 ; CHECK-NEXT:    blsfillq %rdi, %rax
    593 ; CHECK-NEXT:    retq
    594   %t0 = add i64 %a, -1
    595   %t1 = or i64 %t0, %a
    596   ret i64 %t1
    597 }
    598 
    599 define i64 @test_x86_tbm_blsfill_u64_z(i64 %a, i64 %b) nounwind {
    600 ; CHECK-LABEL: test_x86_tbm_blsfill_u64_z:
    601 ; CHECK:       # %bb.0:
    602 ; CHECK-NEXT:    blsfillq %rdi, %rax
    603 ; CHECK-NEXT:    cmoveq %rsi, %rax
    604 ; CHECK-NEXT:    retq
    605   %t0 = add i64 %a, -1
    606   %t1 = or i64 %t0, %a
    607   %t2 = icmp eq i64 %t1, 0
    608   %t3 = select i1 %t2, i64 %b, i64 %t1
    609   ret i64 %t3
    610 }
    611 
    612 define i64 @test_x86_tbm_blsfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    613 ; CHECK-LABEL: test_x86_tbm_blsfill_u64_z2:
    614 ; CHECK:       # %bb.0:
    615 ; CHECK-NEXT:    leaq -1(%rdi), %rax
    616 ; CHECK-NEXT:    orq %rdi, %rax
    617 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    618 ; CHECK-NEXT:    movq %rsi, %rax
    619 ; CHECK-NEXT:    retq
    620   %t0 = add i64 %a, -1
    621   %t1 = or i64 %t0, %a
    622   %t2 = icmp eq i64 %t1, 0
    623   %t3 = select i1 %t2, i64 %b, i64 %c
    624   ret i64 %t3
    625 }
    626 
    627 define i32 @test_x86_tbm_blsic_u32(i32 %a) nounwind {
    628 ; CHECK-LABEL: test_x86_tbm_blsic_u32:
    629 ; CHECK:       # %bb.0:
    630 ; CHECK-NEXT:    blsicl %edi, %eax
    631 ; CHECK-NEXT:    retq
    632   %t0 = xor i32 %a, -1
    633   %t1 = add i32 %a, -1
    634   %t2 = or i32 %t0, %t1
    635   ret i32 %t2
    636 }
    637 
    638 define i32 @test_x86_tbm_blsic_u32_z(i32 %a, i32 %b) nounwind {
    639 ; CHECK-LABEL: test_x86_tbm_blsic_u32_z:
    640 ; CHECK:       # %bb.0:
    641 ; CHECK-NEXT:    blsicl %edi, %eax
    642 ; CHECK-NEXT:    cmovel %esi, %eax
    643 ; CHECK-NEXT:    retq
    644   %t0 = xor i32 %a, -1
    645   %t1 = add i32 %a, -1
    646   %t2 = or i32 %t0, %t1
    647   %t3 = icmp eq i32 %t2, 0
    648   %t4 = select i1 %t3, i32 %b, i32 %t2
    649   ret i32 %t4
    650 }
    651 
    652 define i32 @test_x86_tbm_blsic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    653 ; CHECK-LABEL: test_x86_tbm_blsic_u32_z2:
    654 ; CHECK:       # %bb.0:
    655 ; CHECK-NEXT:    movl %edi, %eax
    656 ; CHECK-NEXT:    notl %eax
    657 ; CHECK-NEXT:    decl %edi
    658 ; CHECK-NEXT:    orl %eax, %edi
    659 ; CHECK-NEXT:    cmovnel %edx, %esi
    660 ; CHECK-NEXT:    movl %esi, %eax
    661 ; CHECK-NEXT:    retq
    662   %t0 = xor i32 %a, -1
    663   %t1 = add i32 %a, -1
    664   %t2 = or i32 %t0, %t1
    665   %t3 = icmp eq i32 %t2, 0
    666   %t4 = select i1 %t3, i32 %b, i32 %c
    667   ret i32 %t4
    668 }
    669 
    670 define i64 @test_x86_tbm_blsic_u64(i64 %a) nounwind {
    671 ; CHECK-LABEL: test_x86_tbm_blsic_u64:
    672 ; CHECK:       # %bb.0:
    673 ; CHECK-NEXT:    blsicq %rdi, %rax
    674 ; CHECK-NEXT:    retq
    675   %t0 = xor i64 %a, -1
    676   %t1 = add i64 %a, -1
    677   %t2 = or i64 %t0, %t1
    678   ret i64 %t2
    679 }
    680 
    681 define i64 @test_x86_tbm_blsic_u64_z(i64 %a, i64 %b) nounwind {
    682 ; CHECK-LABEL: test_x86_tbm_blsic_u64_z:
    683 ; CHECK:       # %bb.0:
    684 ; CHECK-NEXT:    blsicq %rdi, %rax
    685 ; CHECK-NEXT:    cmoveq %rsi, %rax
    686 ; CHECK-NEXT:    retq
    687   %t0 = xor i64 %a, -1
    688   %t1 = add i64 %a, -1
    689   %t2 = or i64 %t0, %t1
    690   %t3 = icmp eq i64 %t2, 0
    691   %t4 = select i1 %t3, i64 %b, i64 %t2
    692   ret i64 %t4
    693 }
    694 
    695 define i64 @test_x86_tbm_blsic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    696 ; CHECK-LABEL: test_x86_tbm_blsic_u64_z2:
    697 ; CHECK:       # %bb.0:
    698 ; CHECK-NEXT:    movq %rdi, %rax
    699 ; CHECK-NEXT:    notq %rax
    700 ; CHECK-NEXT:    decq %rdi
    701 ; CHECK-NEXT:    orq %rax, %rdi
    702 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    703 ; CHECK-NEXT:    movq %rsi, %rax
    704 ; CHECK-NEXT:    retq
    705   %t0 = xor i64 %a, -1
    706   %t1 = add i64 %a, -1
    707   %t2 = or i64 %t0, %t1
    708   %t3 = icmp eq i64 %t2, 0
    709   %t4 = select i1 %t3, i64 %b, i64 %c
    710   ret i64 %t4
    711 }
    712 
    713 define i32 @test_x86_tbm_t1mskc_u32(i32 %a) nounwind {
    714 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32:
    715 ; CHECK:       # %bb.0:
    716 ; CHECK-NEXT:    t1mskcl %edi, %eax
    717 ; CHECK-NEXT:    retq
    718   %t0 = xor i32 %a, -1
    719   %t1 = add i32 %a, 1
    720   %t2 = or i32 %t0, %t1
    721   ret i32 %t2
    722 }
    723 
    724 define i32 @test_x86_tbm_t1mskc_u32_z(i32 %a, i32 %b) nounwind {
    725 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z:
    726 ; CHECK:       # %bb.0:
    727 ; CHECK-NEXT:    t1mskcl %edi, %eax
    728 ; CHECK-NEXT:    testl %eax, %eax
    729 ; CHECK-NEXT:    cmovel %esi, %eax
    730 ; CHECK-NEXT:    retq
    731   %t0 = xor i32 %a, -1
    732   %t1 = add i32 %a, 1
    733   %t2 = or i32 %t0, %t1
    734   %t3 = icmp eq i32 %t2, 0
    735   %t4 = select i1 %t3, i32 %b, i32 %t2
    736   ret i32 %t4
    737 }
    738 
    739 define i32 @test_x86_tbm_t1mskc_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    740 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z2:
    741 ; CHECK:       # %bb.0:
    742 ; CHECK-NEXT:    movl %edi, %eax
    743 ; CHECK-NEXT:    notl %eax
    744 ; CHECK-NEXT:    incl %edi
    745 ; CHECK-NEXT:    orl %eax, %edi
    746 ; CHECK-NEXT:    cmovnel %edx, %esi
    747 ; CHECK-NEXT:    movl %esi, %eax
    748 ; CHECK-NEXT:    retq
    749   %t0 = xor i32 %a, -1
    750   %t1 = add i32 %a, 1
    751   %t2 = or i32 %t0, %t1
    752   %t3 = icmp eq i32 %t2, 0
    753   %t4 = select i1 %t3, i32 %b, i32 %c
    754   ret i32 %t4
    755 }
    756 
    757 define i64 @test_x86_tbm_t1mskc_u64(i64 %a) nounwind {
    758 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64:
    759 ; CHECK:       # %bb.0:
    760 ; CHECK-NEXT:    t1mskcq %rdi, %rax
    761 ; CHECK-NEXT:    retq
    762   %t0 = xor i64 %a, -1
    763   %t1 = add i64 %a, 1
    764   %t2 = or i64 %t0, %t1
    765   ret i64 %t2
    766 }
    767 
    768 define i64 @test_x86_tbm_t1mskc_u64_z(i64 %a, i64 %b) nounwind {
    769 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z:
    770 ; CHECK:       # %bb.0:
    771 ; CHECK-NEXT:    t1mskcq %rdi, %rax
    772 ; CHECK-NEXT:    testq %rax, %rax
    773 ; CHECK-NEXT:    cmoveq %rsi, %rax
    774 ; CHECK-NEXT:    retq
    775   %t0 = xor i64 %a, -1
    776   %t1 = add i64 %a, 1
    777   %t2 = or i64 %t0, %t1
    778   %t3 = icmp eq i64 %t2, 0
    779   %t4 = select i1 %t3, i64 %b, i64 %t2
    780   ret i64 %t4
    781 }
    782 
    783 define i64 @test_x86_tbm_t1mskc_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    784 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z2:
    785 ; CHECK:       # %bb.0:
    786 ; CHECK-NEXT:    movq %rdi, %rax
    787 ; CHECK-NEXT:    notq %rax
    788 ; CHECK-NEXT:    incq %rdi
    789 ; CHECK-NEXT:    orq %rax, %rdi
    790 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    791 ; CHECK-NEXT:    movq %rsi, %rax
    792 ; CHECK-NEXT:    retq
    793   %t0 = xor i64 %a, -1
    794   %t1 = add i64 %a, 1
    795   %t2 = or i64 %t0, %t1
    796   %t3 = icmp eq i64 %t2, 0
    797   %t4 = select i1 %t3, i64 %b, i64 %c
    798   ret i64 %t4
    799 }
    800 
    801 define i32 @test_x86_tbm_tzmsk_u32(i32 %a) nounwind {
    802 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32:
    803 ; CHECK:       # %bb.0:
    804 ; CHECK-NEXT:    tzmskl %edi, %eax
    805 ; CHECK-NEXT:    retq
    806   %t0 = xor i32 %a, -1
    807   %t1 = add i32 %a, -1
    808   %t2 = and i32 %t0, %t1
    809   ret i32 %t2
    810 }
    811 
    812 define i32 @test_x86_tbm_tzmsk_u32_z(i32 %a, i32 %b) nounwind {
    813 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z:
    814 ; CHECK:       # %bb.0:
    815 ; CHECK-NEXT:    tzmskl %edi, %eax
    816 ; CHECK-NEXT:    testl %eax, %eax
    817 ; CHECK-NEXT:    cmovel %esi, %eax
    818 ; CHECK-NEXT:    retq
    819   %t0 = xor i32 %a, -1
    820   %t1 = add i32 %a, -1
    821   %t2 = and i32 %t0, %t1
    822   %t3 = icmp eq i32 %t2, 0
    823   %t4 = select i1 %t3, i32 %b, i32 %t2
    824   ret i32 %t4
    825 }
    826 
    827 define i32 @test_x86_tbm_tzmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
    828 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z2:
    829 ; CHECK:       # %bb.0:
    830 ; CHECK-NEXT:    movl %edi, %eax
    831 ; CHECK-NEXT:    notl %eax
    832 ; CHECK-NEXT:    decl %edi
    833 ; CHECK-NEXT:    testl %edi, %eax
    834 ; CHECK-NEXT:    cmovnel %edx, %esi
    835 ; CHECK-NEXT:    movl %esi, %eax
    836 ; CHECK-NEXT:    retq
    837   %t0 = xor i32 %a, -1
    838   %t1 = add i32 %a, -1
    839   %t2 = and i32 %t0, %t1
    840   %t3 = icmp eq i32 %t2, 0
    841   %t4 = select i1 %t3, i32 %b, i32 %c
    842   ret i32 %t4
    843 }
    844 
    845 define i64 @test_x86_tbm_tzmsk_u64(i64 %a) nounwind {
    846 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64:
    847 ; CHECK:       # %bb.0:
    848 ; CHECK-NEXT:    tzmskq %rdi, %rax
    849 ; CHECK-NEXT:    retq
    850   %t0 = xor i64 %a, -1
    851   %t1 = add i64 %a, -1
    852   %t2 = and i64 %t0, %t1
    853   ret i64 %t2
    854 }
    855 
    856 define i64 @test_x86_tbm_tzmsk_u64_z(i64 %a, i64 %b) nounwind {
    857 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z:
    858 ; CHECK:       # %bb.0:
    859 ; CHECK-NEXT:    tzmskq %rdi, %rax
    860 ; CHECK-NEXT:    testq %rax, %rax
    861 ; CHECK-NEXT:    cmoveq %rsi, %rax
    862 ; CHECK-NEXT:    retq
    863   %t0 = xor i64 %a, -1
    864   %t1 = add i64 %a, -1
    865   %t2 = and i64 %t0, %t1
    866   %t3 = icmp eq i64 %t2, 0
    867   %t4 = select i1 %t3, i64 %b, i64 %t2
    868   ret i64 %t4
    869 }
    870 
    871 define i64 @test_x86_tbm_tzmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
    872 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z2:
    873 ; CHECK:       # %bb.0:
    874 ; CHECK-NEXT:    movq %rdi, %rax
    875 ; CHECK-NEXT:    notq %rax
    876 ; CHECK-NEXT:    decq %rdi
    877 ; CHECK-NEXT:    testq %rdi, %rax
    878 ; CHECK-NEXT:    cmovneq %rdx, %rsi
    879 ; CHECK-NEXT:    movq %rsi, %rax
    880 ; CHECK-NEXT:    retq
    881   %t0 = xor i64 %a, -1
    882   %t1 = add i64 %a, -1
    883   %t2 = and i64 %t0, %t1
    884   %t3 = icmp eq i64 %t2, 0
    885   %t4 = select i1 %t3, i64 %b, i64 %c
    886   ret i64 %t4
    887 }
    888 
    889 define i64 @test_and_large_constant_mask(i64 %x) {
    890 ; CHECK-LABEL: test_and_large_constant_mask:
    891 ; CHECK:       # %bb.0: # %entry
    892 ; CHECK-NEXT:    bextrq $15872, %rdi, %rax # imm = 0x3E00
    893 ; CHECK-NEXT:    retq
    894 entry:
    895   %and = and i64 %x, 4611686018427387903
    896   ret i64 %and
    897 }
    898 
    899 define i64 @test_and_large_constant_mask_load(i64* %x) {
    900 ; CHECK-LABEL: test_and_large_constant_mask_load:
    901 ; CHECK:       # %bb.0: # %entry
    902 ; CHECK-NEXT:    bextrq $15872, (%rdi), %rax # imm = 0x3E00
    903 ; CHECK-NEXT:    retq
    904 entry:
    905   %x1 = load i64, i64* %x
    906   %and = and i64 %x1, 4611686018427387903
    907   ret i64 %and
    908 }
    909 
    910 ; Make sure the mask doesn't break our matching of blcic
    911 define  i64 @masked_blcic(i64) {
    912 ; CHECK-LABEL: masked_blcic:
    913 ; CHECK:       # %bb.0:
    914 ; CHECK-NEXT:    movzwl %di, %eax
    915 ; CHECK-NEXT:    blcicl %eax, %eax
    916 ; CHECK-NEXT:    retq
    917   %2 = and i64 %0, 65535
    918   %3 = xor i64 %2, -1
    919   %4 = add nuw nsw i64 %2, 1
    920   %5 = and i64 %4, %3
    921   ret i64 %5
    922 }
    923