Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
      3 
      4 ; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?).
      5 ; Test the zeroext/signext variants of each pattern to see if that makes a difference.
      6 
      7 ; select Cond, 0, 1 --> zext (!Cond)
      8 
      9 define i32 @select_0_or_1(i1 %cond) {
     10 ; CHECK-LABEL: select_0_or_1:
     11 ; CHECK:       # %bb.0:
     12 ; CHECK-NEXT:    notb %dil
     13 ; CHECK-NEXT:    movzbl %dil, %eax
     14 ; CHECK-NEXT:    andl $1, %eax
     15 ; CHECK-NEXT:    retq
     16   %sel = select i1 %cond, i32 0, i32 1
     17   ret i32 %sel
     18 }
     19 
     20 define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
     21 ; CHECK-LABEL: select_0_or_1_zeroext:
     22 ; CHECK:       # %bb.0:
     23 ; CHECK-NEXT:    xorb $1, %dil
     24 ; CHECK-NEXT:    movzbl %dil, %eax
     25 ; CHECK-NEXT:    retq
     26   %sel = select i1 %cond, i32 0, i32 1
     27   ret i32 %sel
     28 }
     29 
     30 define i32 @select_0_or_1_signext(i1 signext %cond) {
     31 ; CHECK-LABEL: select_0_or_1_signext:
     32 ; CHECK:       # %bb.0:
     33 ; CHECK-NEXT:    notb %dil
     34 ; CHECK-NEXT:    movzbl %dil, %eax
     35 ; CHECK-NEXT:    andl $1, %eax
     36 ; CHECK-NEXT:    retq
     37   %sel = select i1 %cond, i32 0, i32 1
     38   ret i32 %sel
     39 }
     40 
     41 ; select Cond, 1, 0 --> zext (Cond)
     42 
     43 define i32 @select_1_or_0(i1 %cond) {
     44 ; CHECK-LABEL: select_1_or_0:
     45 ; CHECK:       # %bb.0:
     46 ; CHECK-NEXT:    andl $1, %edi
     47 ; CHECK-NEXT:    movl %edi, %eax
     48 ; CHECK-NEXT:    retq
     49   %sel = select i1 %cond, i32 1, i32 0
     50   ret i32 %sel
     51 }
     52 
     53 define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
     54 ; CHECK-LABEL: select_1_or_0_zeroext:
     55 ; CHECK:       # %bb.0:
     56 ; CHECK-NEXT:    movl %edi, %eax
     57 ; CHECK-NEXT:    retq
     58   %sel = select i1 %cond, i32 1, i32 0
     59   ret i32 %sel
     60 }
     61 
     62 define i32 @select_1_or_0_signext(i1 signext %cond) {
     63 ; CHECK-LABEL: select_1_or_0_signext:
     64 ; CHECK:       # %bb.0:
     65 ; CHECK-NEXT:    andl $1, %edi
     66 ; CHECK-NEXT:    movl %edi, %eax
     67 ; CHECK-NEXT:    retq
     68   %sel = select i1 %cond, i32 1, i32 0
     69   ret i32 %sel
     70 }
     71 
     72 ; select Cond, 0, -1 --> sext (!Cond)
     73 
     74 define i32 @select_0_or_neg1(i1 %cond) {
     75 ; CHECK-LABEL: select_0_or_neg1:
     76 ; CHECK:       # %bb.0:
     77 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
     78 ; CHECK-NEXT:    andl $1, %edi
     79 ; CHECK-NEXT:    leal -1(%rdi), %eax
     80 ; CHECK-NEXT:    retq
     81   %sel = select i1 %cond, i32 0, i32 -1
     82   ret i32 %sel
     83 }
     84 
     85 define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
     86 ; CHECK-LABEL: select_0_or_neg1_zeroext:
     87 ; CHECK:       # %bb.0:
     88 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
     89 ; CHECK-NEXT:    leal -1(%rdi), %eax
     90 ; CHECK-NEXT:    retq
     91   %sel = select i1 %cond, i32 0, i32 -1
     92   ret i32 %sel
     93 }
     94 
     95 define i32 @select_0_or_neg1_signext(i1 signext %cond) {
     96 ; CHECK-LABEL: select_0_or_neg1_signext:
     97 ; CHECK:       # %bb.0:
     98 ; CHECK-NEXT:    notl %edi
     99 ; CHECK-NEXT:    movl %edi, %eax
    100 ; CHECK-NEXT:    retq
    101   %sel = select i1 %cond, i32 0, i32 -1
    102   ret i32 %sel
    103 }
    104 
    105 ; select Cond, -1, 0 --> sext (Cond)
    106 
    107 define i32 @select_neg1_or_0(i1 %cond) {
    108 ; CHECK-LABEL: select_neg1_or_0:
    109 ; CHECK:       # %bb.0:
    110 ; CHECK-NEXT:    andl $1, %edi
    111 ; CHECK-NEXT:    negl %edi
    112 ; CHECK-NEXT:    movl %edi, %eax
    113 ; CHECK-NEXT:    retq
    114   %sel = select i1 %cond, i32 -1, i32 0
    115   ret i32 %sel
    116 }
    117 
    118 define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
    119 ; CHECK-LABEL: select_neg1_or_0_zeroext:
    120 ; CHECK:       # %bb.0:
    121 ; CHECK-NEXT:    negl %edi
    122 ; CHECK-NEXT:    movl %edi, %eax
    123 ; CHECK-NEXT:    retq
    124   %sel = select i1 %cond, i32 -1, i32 0
    125   ret i32 %sel
    126 }
    127 
    128 define i32 @select_neg1_or_0_signext(i1 signext %cond) {
    129 ; CHECK-LABEL: select_neg1_or_0_signext:
    130 ; CHECK:       # %bb.0:
    131 ; CHECK-NEXT:    movl %edi, %eax
    132 ; CHECK-NEXT:    retq
    133   %sel = select i1 %cond, i32 -1, i32 0
    134   ret i32 %sel
    135 }
    136 
    137 ; select Cond, C+1, C --> add (zext Cond), C
    138 
    139 define i32 @select_Cplus1_C(i1 %cond) {
    140 ; CHECK-LABEL: select_Cplus1_C:
    141 ; CHECK:       # %bb.0:
    142 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    143 ; CHECK-NEXT:    andl $1, %edi
    144 ; CHECK-NEXT:    leal 41(%rdi), %eax
    145 ; CHECK-NEXT:    retq
    146   %sel = select i1 %cond, i32 42, i32 41
    147   ret i32 %sel
    148 }
    149 
    150 define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
    151 ; CHECK-LABEL: select_Cplus1_C_zeroext:
    152 ; CHECK:       # %bb.0:
    153 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
    154 ; CHECK-NEXT:    leal 41(%rdi), %eax
    155 ; CHECK-NEXT:    retq
    156   %sel = select i1 %cond, i32 42, i32 41
    157   ret i32 %sel
    158 }
    159 
    160 define i32 @select_Cplus1_C_signext(i1 signext %cond) {
    161 ; CHECK-LABEL: select_Cplus1_C_signext:
    162 ; CHECK:       # %bb.0:
    163 ; CHECK-NEXT:    movl $41, %eax
    164 ; CHECK-NEXT:    subl %edi, %eax
    165 ; CHECK-NEXT:    retq
    166   %sel = select i1 %cond, i32 42, i32 41
    167   ret i32 %sel
    168 }
    169 
    170 ; select Cond, C, C+1 --> add (sext Cond), C
    171 
    172 define i32 @select_C_Cplus1(i1 %cond) {
    173 ; CHECK-LABEL: select_C_Cplus1:
    174 ; CHECK:       # %bb.0:
    175 ; CHECK-NEXT:    andl $1, %edi
    176 ; CHECK-NEXT:    movl $42, %eax
    177 ; CHECK-NEXT:    subl %edi, %eax
    178 ; CHECK-NEXT:    retq
    179   %sel = select i1 %cond, i32 41, i32 42
    180   ret i32 %sel
    181 }
    182 
    183 define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
    184 ; CHECK-LABEL: select_C_Cplus1_zeroext:
    185 ; CHECK:       # %bb.0:
    186 ; CHECK-NEXT:    movl $42, %eax
    187 ; CHECK-NEXT:    subl %edi, %eax
    188 ; CHECK-NEXT:    retq
    189   %sel = select i1 %cond, i32 41, i32 42
    190   ret i32 %sel
    191 }
    192 
    193 define i32 @select_C_Cplus1_signext(i1 signext %cond) {
    194 ; CHECK-LABEL: select_C_Cplus1_signext:
    195 ; CHECK:       # %bb.0:
    196 ; CHECK-NEXT:    andl $1, %edi
    197 ; CHECK-NEXT:    movl $42, %eax
    198 ; CHECK-NEXT:    subl %edi, %eax
    199 ; CHECK-NEXT:    retq
    200   %sel = select i1 %cond, i32 41, i32 42
    201   ret i32 %sel
    202 }
    203 
    204 ; If the constants differ by a small multiplier, use LEA.
    205 ; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> LEA C2(Cond * (C1-C2))
    206 
    207 define i32 @select_lea_2(i1 zeroext %cond) {
    208 ; CHECK-LABEL: select_lea_2:
    209 ; CHECK:       # %bb.0:
    210 ; CHECK-NEXT:    xorb $1, %dil
    211 ; CHECK-NEXT:    movzbl %dil, %eax
    212 ; CHECK-NEXT:    leal -1(%rax,%rax), %eax
    213 ; CHECK-NEXT:    retq
    214   %sel = select i1 %cond, i32 -1, i32 1
    215   ret i32 %sel
    216 }
    217 
    218 define i64 @select_lea_3(i1 zeroext %cond) {
    219 ; CHECK-LABEL: select_lea_3:
    220 ; CHECK:       # %bb.0:
    221 ; CHECK-NEXT:    xorb $1, %dil
    222 ; CHECK-NEXT:    movzbl %dil, %eax
    223 ; CHECK-NEXT:    leaq -2(%rax,%rax,2), %rax
    224 ; CHECK-NEXT:    retq
    225   %sel = select i1 %cond, i64 -2, i64 1
    226   ret i64 %sel
    227 }
    228 
    229 define i32 @select_lea_5(i1 zeroext %cond) {
    230 ; CHECK-LABEL: select_lea_5:
    231 ; CHECK:       # %bb.0:
    232 ; CHECK-NEXT:    xorb $1, %dil
    233 ; CHECK-NEXT:    movzbl %dil, %eax
    234 ; CHECK-NEXT:    leal -2(%rax,%rax,4), %eax
    235 ; CHECK-NEXT:    retq
    236   %sel = select i1 %cond, i32 -2, i32 3
    237   ret i32 %sel
    238 }
    239 
    240 define i64 @select_lea_9(i1 zeroext %cond) {
    241 ; CHECK-LABEL: select_lea_9:
    242 ; CHECK:       # %bb.0:
    243 ; CHECK-NEXT:    xorb $1, %dil
    244 ; CHECK-NEXT:    movzbl %dil, %eax
    245 ; CHECK-NEXT:    leaq -7(%rax,%rax,8), %rax
    246 ; CHECK-NEXT:    retq
    247   %sel = select i1 %cond, i64 -7, i64 2
    248   ret i64 %sel
    249 }
    250 
    251 ; Should this be 'sbb x,x' or 'sbb 0,x' with simpler LEA or add?
    252 
    253 define i64 @sel_1_2(i64 %x, i64 %y) {
    254 ; CHECK-LABEL: sel_1_2:
    255 ; CHECK:       # %bb.0:
    256 ; CHECK-NEXT:    cmpq $42, %rdi
    257 ; CHECK-NEXT:    sbbq $0, %rsi
    258 ; CHECK-NEXT:    leaq 2(%rsi), %rax
    259 ; CHECK-NEXT:    retq
    260   %cmp = icmp ult i64 %x, 42
    261   %sel = select i1 %cmp, i64 1, i64 2
    262   %sub = add i64 %sel, %y
    263   ret i64 %sub
    264 }
    265 
    266 ; No LEA with 8-bit, but this shouldn't need branches or cmov.
    267 
    268 define i8 @sel_1_neg1(i32 %x) {
    269 ; CHECK-LABEL: sel_1_neg1:
    270 ; CHECK:       # %bb.0:
    271 ; CHECK-NEXT:    cmpl $42, %edi
    272 ; CHECK-NEXT:    setg %al
    273 ; CHECK-NEXT:    shlb $2, %al
    274 ; CHECK-NEXT:    decb %al
    275 ; CHECK-NEXT:    retq
    276   %cmp = icmp sgt i32 %x, 42
    277   %sel = select i1 %cmp, i8 3, i8 -1
    278   ret i8 %sel
    279 }
    280 
    281 ; We get an LEA for 16-bit because we ignore the high-bits.
    282 
    283 define i16 @sel_neg1_1(i32 %x) {
    284 ; CHECK-LABEL: sel_neg1_1:
    285 ; CHECK:       # %bb.0:
    286 ; CHECK-NEXT:    xorl %eax, %eax
    287 ; CHECK-NEXT:    cmpl $43, %edi
    288 ; CHECK-NEXT:    setl %al
    289 ; CHECK-NEXT:    leal -1(,%rax,4), %eax
    290 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
    291 ; CHECK-NEXT:    retq
    292   %cmp = icmp sgt i32 %x, 42
    293   %sel = select i1 %cmp, i16 -1, i16 3
    294   ret i16 %sel
    295 }
    296 
    297 ; If the comparison is available, the predicate can be inverted.
    298 
    299 define i32 @sel_1_neg1_32(i32 %x) {
    300 ; CHECK-LABEL: sel_1_neg1_32:
    301 ; CHECK:       # %bb.0:
    302 ; CHECK-NEXT:    xorl %eax, %eax
    303 ; CHECK-NEXT:    cmpl $42, %edi
    304 ; CHECK-NEXT:    setg %al
    305 ; CHECK-NEXT:    leal -1(%rax,%rax,8), %eax
    306 ; CHECK-NEXT:    retq
    307   %cmp = icmp sgt i32 %x, 42
    308   %sel = select i1 %cmp, i32 8, i32 -1
    309   ret i32 %sel
    310 }
    311 
    312 define i32 @sel_neg1_1_32(i32 %x) {
    313 ; CHECK-LABEL: sel_neg1_1_32:
    314 ; CHECK:       # %bb.0:
    315 ; CHECK-NEXT:    xorl %eax, %eax
    316 ; CHECK-NEXT:    cmpl $43, %edi
    317 ; CHECK-NEXT:    setl %al
    318 ; CHECK-NEXT:    leal -7(%rax,%rax,8), %eax
    319 ; CHECK-NEXT:    retq
    320   %cmp = icmp sgt i32 %x, 42
    321   %sel = select i1 %cmp, i32 -7, i32 2
    322   ret i32 %sel
    323 }
    324 
    325 
    326 ; If the constants differ by a large power-of-2, that can be a shift of the difference plus the smaller constant.
    327 ; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2
    328 
    329 define i8 @select_pow2_diff(i1 zeroext %cond) {
    330 ; CHECK-LABEL: select_pow2_diff:
    331 ; CHECK:       # %bb.0:
    332 ; CHECK-NEXT:    shlb $4, %dil
    333 ; CHECK-NEXT:    orb $3, %dil
    334 ; CHECK-NEXT:    movl %edi, %eax
    335 ; CHECK-NEXT:    retq
    336   %sel = select i1 %cond, i8 19, i8 3
    337   ret i8 %sel
    338 }
    339 
    340 define i16 @select_pow2_diff_invert(i1 zeroext %cond) {
    341 ; CHECK-LABEL: select_pow2_diff_invert:
    342 ; CHECK:       # %bb.0:
    343 ; CHECK-NEXT:    xorb $1, %dil
    344 ; CHECK-NEXT:    movzbl %dil, %eax
    345 ; CHECK-NEXT:    shll $6, %eax
    346 ; CHECK-NEXT:    orl $7, %eax
    347 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
    348 ; CHECK-NEXT:    retq
    349   %sel = select i1 %cond, i16 7, i16 71
    350   ret i16 %sel
    351 }
    352 
    353 define i32 @select_pow2_diff_neg(i1 zeroext %cond) {
    354 ; CHECK-LABEL: select_pow2_diff_neg:
    355 ; CHECK:       # %bb.0:
    356 ; CHECK-NEXT:    shlb $4, %dil
    357 ; CHECK-NEXT:    movzbl %dil, %eax
    358 ; CHECK-NEXT:    orl $-25, %eax
    359 ; CHECK-NEXT:    retq
    360   %sel = select i1 %cond, i32 -9, i32 -25
    361   ret i32 %sel
    362 }
    363 
    364 define i64 @select_pow2_diff_neg_invert(i1 zeroext %cond) {
    365 ; CHECK-LABEL: select_pow2_diff_neg_invert:
    366 ; CHECK:       # %bb.0:
    367 ; CHECK-NEXT:    xorb $1, %dil
    368 ; CHECK-NEXT:    movzbl %dil, %eax
    369 ; CHECK-NEXT:    shlq $7, %rax
    370 ; CHECK-NEXT:    addq $-99, %rax
    371 ; CHECK-NEXT:    retq
    372   %sel = select i1 %cond, i64 -99, i64 29
    373   ret i64 %sel
    374 }
    375 
    376 ; This doesn't need a branch, but don't do the wrong thing if subtraction of the constants overflows.
    377 
    378 define i8 @sel_67_neg125(i32 %x) {
    379 ; CHECK-LABEL: sel_67_neg125:
    380 ; CHECK:       # %bb.0:
    381 ; CHECK-NEXT:    cmpl $42, %edi
    382 ; CHECK-NEXT:    movb $67, %al
    383 ; CHECK-NEXT:    jg .LBB31_2
    384 ; CHECK-NEXT:  # %bb.1:
    385 ; CHECK-NEXT:    movb $-125, %al
    386 ; CHECK-NEXT:  .LBB31_2:
    387 ; CHECK-NEXT:    retq
    388   %cmp = icmp sgt i32 %x, 42
    389   %sel = select i1 %cmp, i8 67, i8 -125
    390   ret i8 %sel
    391 }
    392 
    393 
    394 ; In general, select of 2 constants could be:
    395 ; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
    396 
    397 define i32 @select_C1_C2(i1 %cond) {
    398 ; CHECK-LABEL: select_C1_C2:
    399 ; CHECK:       # %bb.0:
    400 ; CHECK-NEXT:    testb $1, %dil
    401 ; CHECK-NEXT:    movl $421, %ecx # imm = 0x1A5
    402 ; CHECK-NEXT:    movl $42, %eax
    403 ; CHECK-NEXT:    cmovnel %ecx, %eax
    404 ; CHECK-NEXT:    retq
    405   %sel = select i1 %cond, i32 421, i32 42
    406   ret i32 %sel
    407 }
    408 
    409 define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
    410 ; CHECK-LABEL: select_C1_C2_zeroext:
    411 ; CHECK:       # %bb.0:
    412 ; CHECK-NEXT:    testl %edi, %edi
    413 ; CHECK-NEXT:    movl $421, %ecx # imm = 0x1A5
    414 ; CHECK-NEXT:    movl $42, %eax
    415 ; CHECK-NEXT:    cmovnel %ecx, %eax
    416 ; CHECK-NEXT:    retq
    417   %sel = select i1 %cond, i32 421, i32 42
    418   ret i32 %sel
    419 }
    420 
    421 define i32 @select_C1_C2_signext(i1 signext %cond) {
    422 ; CHECK-LABEL: select_C1_C2_signext:
    423 ; CHECK:       # %bb.0:
    424 ; CHECK-NEXT:    testb $1, %dil
    425 ; CHECK-NEXT:    movl $421, %ecx # imm = 0x1A5
    426 ; CHECK-NEXT:    movl $42, %eax
    427 ; CHECK-NEXT:    cmovnel %ecx, %eax
    428 ; CHECK-NEXT:    retq
    429   %sel = select i1 %cond, i32 421, i32 42
    430   ret i32 %sel
    431 }
    432 
    433 ; select (x == 2), 2, (x + 1) --> select (x == 2), x, (x + 1)
    434 
    435 define i64 @select_2_or_inc(i64 %x) {
    436 ; CHECK-LABEL: select_2_or_inc:
    437 ; CHECK:       # %bb.0:
    438 ; CHECK-NEXT:    leaq 1(%rdi), %rax
    439 ; CHECK-NEXT:    cmpq $2, %rdi
    440 ; CHECK-NEXT:    cmoveq %rdi, %rax
    441 ; CHECK-NEXT:    retq
    442   %cmp = icmp eq i64 %x, 2
    443   %add = add i64 %x, 1
    444   %retval.0 = select i1 %cmp, i64 2, i64 %add
    445   ret i64 %retval.0
    446 }
    447 
    448 define <4 x i32> @sel_constants_add_constant_vec(i1 %cond) {
    449 ; CHECK-LABEL: sel_constants_add_constant_vec:
    450 ; CHECK:       # %bb.0:
    451 ; CHECK-NEXT:    testb $1, %dil
    452 ; CHECK-NEXT:    jne .LBB36_1
    453 ; CHECK-NEXT:  # %bb.2:
    454 ; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [12,13,14,15]
    455 ; CHECK-NEXT:    retq
    456 ; CHECK-NEXT:  .LBB36_1:
    457 ; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [4294967293,14,4,4]
    458 ; CHECK-NEXT:    retq
    459   %sel = select i1 %cond, <4 x i32> <i32 -4, i32 12, i32 1, i32 0>, <4 x i32> <i32 11, i32 11, i32 11, i32 11>
    460   %bo = add <4 x i32> %sel, <i32 1, i32 2, i32 3, i32 4>
    461   ret <4 x i32> %bo
    462 }
    463 
    464 define <2 x double> @sel_constants_fmul_constant_vec(i1 %cond) {
    465 ; CHECK-LABEL: sel_constants_fmul_constant_vec:
    466 ; CHECK:       # %bb.0:
    467 ; CHECK-NEXT:    testb $1, %dil
    468 ; CHECK-NEXT:    jne .LBB37_1
    469 ; CHECK-NEXT:  # %bb.2:
    470 ; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [1.188300e+02,3.454000e+01]
    471 ; CHECK-NEXT:    retq
    472 ; CHECK-NEXT:  .LBB37_1:
    473 ; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [-2.040000e+01,3.768000e+01]
    474 ; CHECK-NEXT:    retq
    475   %sel = select i1 %cond, <2 x double> <double -4.0, double 12.0>, <2 x double> <double 23.3, double 11.0>
    476   %bo = fmul <2 x double> %sel, <double 5.1, double 3.14>
    477   ret <2 x double> %bo
    478 }
    479 
    480 ; 4294967297 = 0x100000001.
    481 ; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
    482 
    483 define i64 @opaque_constant(i1 %cond, i64 %x) {
    484 ; CHECK-LABEL: opaque_constant:
    485 ; CHECK:       # %bb.0:
    486 ; CHECK-NEXT:    testb $1, %dil
    487 ; CHECK-NEXT:    movl $23, %ecx
    488 ; CHECK-NEXT:    movq $-4, %rax
    489 ; CHECK-NEXT:    cmoveq %rcx, %rax
    490 ; CHECK-NEXT:    movabsq $4294967297, %rcx # imm = 0x100000001
    491 ; CHECK-NEXT:    andq %rcx, %rax
    492 ; CHECK-NEXT:    xorl %edx, %edx
    493 ; CHECK-NEXT:    cmpq %rcx, %rsi
    494 ; CHECK-NEXT:    sete %dl
    495 ; CHECK-NEXT:    subq %rdx, %rax
    496 ; CHECK-NEXT:    retq
    497   %sel = select i1 %cond, i64 -4, i64 23
    498   %bo = and i64 %sel, 4294967297
    499   %cmp = icmp eq i64 %x, 4294967297
    500   %sext = sext i1 %cmp to i64
    501   %add = add i64 %bo, %sext
    502   ret i64 %add
    503 }
    504 
    505