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 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,NOBMI -enable-var-scope
      3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs -mattr=+bmi | FileCheck %s -check-prefixes=CHECK,BMI -enable-var-scope
      4 
      5 define i32 @select_and1(i32 %x, i32 %y) {
      6 ; CHECK-LABEL: select_and1:
      7 ; CHECK:       # %bb.0:
      8 ; CHECK-NEXT:    xorl %eax, %eax
      9 ; CHECK-NEXT:    cmpl $11, %edi
     10 ; CHECK-NEXT:    cmovgel %esi, %eax
     11 ; CHECK-NEXT:    retq
     12   %c = icmp slt i32 %x, 11
     13   %s = select i1 %c, i32 0, i32 -1
     14   %a = and i32 %y, %s
     15   ret i32 %a
     16 }
     17 
     18 define i32 @select_and2(i32 %x, i32 %y) {
     19 ; CHECK-LABEL: select_and2:
     20 ; CHECK:       # %bb.0:
     21 ; CHECK-NEXT:    xorl %eax, %eax
     22 ; CHECK-NEXT:    cmpl $11, %edi
     23 ; CHECK-NEXT:    cmovgel %esi, %eax
     24 ; CHECK-NEXT:    retq
     25   %c = icmp slt i32 %x, 11
     26   %s = select i1 %c, i32 0, i32 -1
     27   %a = and i32 %s, %y
     28   ret i32 %a
     29 }
     30 
     31 define i32 @select_and3(i32 %x, i32 %y) {
     32 ; CHECK-LABEL: select_and3:
     33 ; CHECK:       # %bb.0:
     34 ; CHECK-NEXT:    xorl %eax, %eax
     35 ; CHECK-NEXT:    cmpl $11, %edi
     36 ; CHECK-NEXT:    cmovll %esi, %eax
     37 ; CHECK-NEXT:    retq
     38   %c = icmp slt i32 %x, 11
     39   %s = select i1 %c, i32 -1, i32 0
     40   %a = and i32 %y, %s
     41   ret i32 %a
     42 }
     43 
     44 define <4 x i32> @select_and_v4(i32 %x, <4 x i32> %y) {
     45 ; CHECK-LABEL: select_and_v4:
     46 ; CHECK:       # %bb.0:
     47 ; CHECK-NEXT:    cmpl $11, %edi
     48 ; CHECK-NEXT:    xorps %xmm1, %xmm1
     49 ; CHECK-NEXT:    jl .LBB3_2
     50 ; CHECK-NEXT:  # %bb.1:
     51 ; CHECK-NEXT:    movaps %xmm0, %xmm1
     52 ; CHECK-NEXT:  .LBB3_2:
     53 ; CHECK-NEXT:    movaps %xmm1, %xmm0
     54 ; CHECK-NEXT:    retq
     55   %c = icmp slt i32 %x, 11
     56   %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
     57   %a = and <4 x i32> %s, %y
     58   ret <4 x i32> %a
     59 }
     60 
     61 define i32 @select_or1(i32 %x, i32 %y) {
     62 ; CHECK-LABEL: select_or1:
     63 ; CHECK:       # %bb.0:
     64 ; CHECK-NEXT:    cmpl $11, %edi
     65 ; CHECK-NEXT:    movl $-1, %eax
     66 ; CHECK-NEXT:    cmovll %esi, %eax
     67 ; CHECK-NEXT:    retq
     68   %c = icmp slt i32 %x, 11
     69   %s = select i1 %c, i32 0, i32 -1
     70   %a = or i32 %y, %s
     71   ret i32 %a
     72 }
     73 
     74 define i32 @select_or2(i32 %x, i32 %y) {
     75 ; CHECK-LABEL: select_or2:
     76 ; CHECK:       # %bb.0:
     77 ; CHECK-NEXT:    cmpl $11, %edi
     78 ; CHECK-NEXT:    movl $-1, %eax
     79 ; CHECK-NEXT:    cmovll %esi, %eax
     80 ; CHECK-NEXT:    retq
     81   %c = icmp slt i32 %x, 11
     82   %s = select i1 %c, i32 0, i32 -1
     83   %a = or i32 %s, %y
     84   ret i32 %a
     85 }
     86 
     87 define i32 @select_or3(i32 %x, i32 %y) {
     88 ; CHECK-LABEL: select_or3:
     89 ; CHECK:       # %bb.0:
     90 ; CHECK-NEXT:    cmpl $11, %edi
     91 ; CHECK-NEXT:    movl $-1, %eax
     92 ; CHECK-NEXT:    cmovgel %esi, %eax
     93 ; CHECK-NEXT:    retq
     94   %c = icmp slt i32 %x, 11
     95   %s = select i1 %c, i32 -1, i32 0
     96   %a = or i32 %y, %s
     97   ret i32 %a
     98 }
     99 
    100 define <4 x i32> @select_or_v4(i32 %x, <4 x i32> %y) {
    101 ; CHECK-LABEL: select_or_v4:
    102 ; CHECK:       # %bb.0:
    103 ; CHECK-NEXT:    cmpl $11, %edi
    104 ; CHECK-NEXT:    jl .LBB7_2
    105 ; CHECK-NEXT:  # %bb.1:
    106 ; CHECK-NEXT:    pcmpeqd %xmm0, %xmm0
    107 ; CHECK-NEXT:  .LBB7_2:
    108 ; CHECK-NEXT:    retq
    109   %c = icmp slt i32 %x, 11
    110   %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
    111   %a = or <4 x i32> %s, %y
    112   ret <4 x i32> %a
    113 }
    114 
    115 define i32 @sel_constants_sub_constant_sel_constants(i1 %cond) {
    116 ; CHECK-LABEL: sel_constants_sub_constant_sel_constants:
    117 ; CHECK:       # %bb.0:
    118 ; CHECK-NEXT:    testb $1, %dil
    119 ; CHECK-NEXT:    movl $9, %ecx
    120 ; CHECK-NEXT:    movl $2, %eax
    121 ; CHECK-NEXT:    cmovnel %ecx, %eax
    122 ; CHECK-NEXT:    retq
    123   %sel = select i1 %cond, i32 -4, i32 3
    124   %bo = sub i32 5, %sel
    125   ret i32 %bo
    126 }
    127 
    128 define i32 @sdiv_constant_sel_constants(i1 %cond) {
    129 ; CHECK-LABEL: sdiv_constant_sel_constants:
    130 ; CHECK:       # %bb.0:
    131 ; CHECK-NEXT:    notb %dil
    132 ; CHECK-NEXT:    movzbl %dil, %eax
    133 ; CHECK-NEXT:    andl $1, %eax
    134 ; CHECK-NEXT:    leal (%rax,%rax,4), %eax
    135 ; CHECK-NEXT:    retq
    136   %sel = select i1 %cond, i32 121, i32 23
    137   %bo = sdiv i32 120, %sel
    138   ret i32 %bo
    139 }
    140 
    141 define i32 @udiv_constant_sel_constants(i1 %cond) {
    142 ; CHECK-LABEL: udiv_constant_sel_constants:
    143 ; CHECK:       # %bb.0:
    144 ; CHECK-NEXT:    notb %dil
    145 ; CHECK-NEXT:    movzbl %dil, %eax
    146 ; CHECK-NEXT:    andl $1, %eax
    147 ; CHECK-NEXT:    leal (%rax,%rax,4), %eax
    148 ; CHECK-NEXT:    retq
    149   %sel = select i1 %cond, i32 -4, i32 23
    150   %bo = udiv i32 120, %sel
    151   ret i32 %bo
    152 }
    153 
    154 define i32 @srem_constant_sel_constants(i1 %cond) {
    155 ; CHECK-LABEL: srem_constant_sel_constants:
    156 ; CHECK:       # %bb.0:
    157 ; CHECK-NEXT:    testb $1, %dil
    158 ; CHECK-NEXT:    movl $120, %ecx
    159 ; CHECK-NEXT:    movl $5, %eax
    160 ; CHECK-NEXT:    cmovnel %ecx, %eax
    161 ; CHECK-NEXT:    retq
    162   %sel = select i1 %cond, i32 121, i32 23
    163   %bo = srem i32 120, %sel
    164   ret i32 %bo
    165 }
    166 
    167 define i32 @urem_constant_sel_constants(i1 %cond) {
    168 ; CHECK-LABEL: urem_constant_sel_constants:
    169 ; CHECK:       # %bb.0:
    170 ; CHECK-NEXT:    testb $1, %dil
    171 ; CHECK-NEXT:    movl $120, %ecx
    172 ; CHECK-NEXT:    movl $5, %eax
    173 ; CHECK-NEXT:    cmovnel %ecx, %eax
    174 ; CHECK-NEXT:    retq
    175   %sel = select i1 %cond, i32 -4, i32 23
    176   %bo = urem i32 120, %sel
    177   ret i32 %bo
    178 }
    179 
    180 define i32 @sel_constants_shl_constant(i1 %cond) {
    181 ; CHECK-LABEL: sel_constants_shl_constant:
    182 ; CHECK:       # %bb.0:
    183 ; CHECK-NEXT:    notb %dil
    184 ; CHECK-NEXT:    movzbl %dil, %eax
    185 ; CHECK-NEXT:    andl $1, %eax
    186 ; CHECK-NEXT:    orl $2, %eax
    187 ; CHECK-NEXT:    shll $8, %eax
    188 ; CHECK-NEXT:    retq
    189   %sel = select i1 %cond, i32 2, i32 3
    190   %bo = shl i32 %sel, 8
    191   ret i32 %bo
    192 }
    193 
    194 define i32 @shl_constant_sel_constants(i1 %cond) {
    195 ; CHECK-LABEL: shl_constant_sel_constants:
    196 ; CHECK:       # %bb.0:
    197 ; CHECK-NEXT:    andb $1, %dil
    198 ; CHECK-NEXT:    xorb $3, %dil
    199 ; CHECK-NEXT:    movl $1, %eax
    200 ; CHECK-NEXT:    movl %edi, %ecx
    201 ; CHECK-NEXT:    shll %cl, %eax
    202 ; CHECK-NEXT:    retq
    203   %sel = select i1 %cond, i32 2, i32 3
    204   %bo = shl i32 1, %sel
    205   ret i32 %bo
    206 }
    207 
    208 define i32 @lshr_constant_sel_constants(i1 %cond) {
    209 ; CHECK-LABEL: lshr_constant_sel_constants:
    210 ; CHECK:       # %bb.0:
    211 ; CHECK-NEXT:    andb $1, %dil
    212 ; CHECK-NEXT:    xorb $3, %dil
    213 ; CHECK-NEXT:    movl $64, %eax
    214 ; CHECK-NEXT:    movl %edi, %ecx
    215 ; CHECK-NEXT:    shrl %cl, %eax
    216 ; CHECK-NEXT:    retq
    217   %sel = select i1 %cond, i32 2, i32 3
    218   %bo = lshr i32 64, %sel
    219   ret i32 %bo
    220 }
    221 
    222 define i32 @ashr_constant_sel_constants(i1 %cond) {
    223 ; CHECK-LABEL: ashr_constant_sel_constants:
    224 ; CHECK:       # %bb.0:
    225 ; CHECK-NEXT:    andb $1, %dil
    226 ; CHECK-NEXT:    xorb $3, %dil
    227 ; CHECK-NEXT:    movl $128, %eax
    228 ; CHECK-NEXT:    movl %edi, %ecx
    229 ; CHECK-NEXT:    shrl %cl, %eax
    230 ; CHECK-NEXT:    retq
    231   %sel = select i1 %cond, i32 2, i32 3
    232   %bo = ashr i32 128, %sel
    233   ret i32 %bo
    234 }
    235 
    236 define double @fsub_constant_sel_constants(i1 %cond) {
    237 ; CHECK-LABEL: fsub_constant_sel_constants:
    238 ; CHECK:       # %bb.0:
    239 ; CHECK-NEXT:    testb $1, %dil
    240 ; CHECK-NEXT:    jne .LBB17_1
    241 ; CHECK-NEXT:  # %bb.2:
    242 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    243 ; CHECK-NEXT:    retq
    244 ; CHECK-NEXT:  .LBB17_1:
    245 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    246 ; CHECK-NEXT:    retq
    247   %sel = select i1 %cond, double -4.0, double 23.3
    248   %bo = fsub double 5.1, %sel
    249   ret double %bo
    250 }
    251 
    252 define double @fdiv_constant_sel_constants(i1 %cond) {
    253 ; CHECK-LABEL: fdiv_constant_sel_constants:
    254 ; CHECK:       # %bb.0:
    255 ; CHECK-NEXT:    testb $1, %dil
    256 ; CHECK-NEXT:    jne .LBB18_1
    257 ; CHECK-NEXT:  # %bb.2:
    258 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    259 ; CHECK-NEXT:    retq
    260 ; CHECK-NEXT:  .LBB18_1:
    261 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    262 ; CHECK-NEXT:    retq
    263   %sel = select i1 %cond, double -4.0, double 23.3
    264   %bo = fdiv double 5.1, %sel
    265   ret double %bo
    266 }
    267 
    268 define double @frem_constant_sel_constants(i1 %cond) {
    269 ; CHECK-LABEL: frem_constant_sel_constants:
    270 ; CHECK:       # %bb.0:
    271 ; CHECK-NEXT:    testb $1, %dil
    272 ; CHECK-NEXT:    jne .LBB19_1
    273 ; CHECK-NEXT:  # %bb.2:
    274 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    275 ; CHECK-NEXT:    retq
    276 ; CHECK-NEXT:  .LBB19_1:
    277 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
    278 ; CHECK-NEXT:    retq
    279   %sel = select i1 %cond, double -4.0, double 23.3
    280   %bo = frem double 5.1, %sel
    281   ret double %bo
    282 }
    283 
    284 declare i64 @llvm.cttz.i64(i64, i1)
    285 define i64 @cttz_64_eq_select(i64 %v) nounwind {
    286 ; NOBMI-LABEL: cttz_64_eq_select:
    287 ; NOBMI:       # %bb.0:
    288 ; NOBMI-NEXT:    bsfq %rdi, %rcx
    289 ; NOBMI-NEXT:    movq $-1, %rax
    290 ; NOBMI-NEXT:    cmovneq %rcx, %rax
    291 ; NOBMI-NEXT:    addq $6, %rax
    292 ; NOBMI-NEXT:    retq
    293 ;
    294 ; BMI-LABEL: cttz_64_eq_select:
    295 ; BMI:       # %bb.0:
    296 ; BMI-NEXT:    tzcntq %rdi, %rcx
    297 ; BMI-NEXT:    movq $-1, %rax
    298 ; BMI-NEXT:    cmovaeq %rcx, %rax
    299 ; BMI-NEXT:    addq $6, %rax
    300 ; BMI-NEXT:    retq
    301 
    302   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    303   %tobool = icmp eq i64 %v, 0
    304   %.op = add nuw nsw i64 %cnt, 6
    305   %add = select i1 %tobool, i64 5, i64 %.op
    306   ret i64 %add
    307 }
    308 
    309 define i64 @cttz_64_ne_select(i64 %v) nounwind {
    310 ; NOBMI-LABEL: cttz_64_ne_select:
    311 ; NOBMI:       # %bb.0:
    312 ; NOBMI-NEXT:    bsfq %rdi, %rcx
    313 ; NOBMI-NEXT:    movq $-1, %rax
    314 ; NOBMI-NEXT:    cmovneq %rcx, %rax
    315 ; NOBMI-NEXT:    addq $6, %rax
    316 ; NOBMI-NEXT:    retq
    317 ;
    318 ; BMI-LABEL: cttz_64_ne_select:
    319 ; BMI:       # %bb.0:
    320 ; BMI-NEXT:    tzcntq %rdi, %rcx
    321 ; BMI-NEXT:    movq $-1, %rax
    322 ; BMI-NEXT:    cmovaeq %rcx, %rax
    323 ; BMI-NEXT:    addq $6, %rax
    324 ; BMI-NEXT:    retq
    325 
    326   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    327   %tobool = icmp ne i64 %v, 0
    328   %.op = add nuw nsw i64 %cnt, 6
    329   %add = select i1 %tobool, i64 %.op, i64 5
    330   ret i64 %add
    331 }
    332 
    333 declare i32 @llvm.cttz.i32(i32, i1)
    334 define i32 @cttz_32_eq_select(i32 %v) nounwind {
    335 ; NOBMI-LABEL: cttz_32_eq_select:
    336 ; NOBMI:       # %bb.0:
    337 ; NOBMI-NEXT:    bsfl %edi, %ecx
    338 ; NOBMI-NEXT:    movl $-1, %eax
    339 ; NOBMI-NEXT:    cmovnel %ecx, %eax
    340 ; NOBMI-NEXT:    addl $6, %eax
    341 ; NOBMI-NEXT:    retq
    342 ;
    343 ; BMI-LABEL: cttz_32_eq_select:
    344 ; BMI:       # %bb.0:
    345 ; BMI-NEXT:    tzcntl %edi, %ecx
    346 ; BMI-NEXT:    movl $-1, %eax
    347 ; BMI-NEXT:    cmovael %ecx, %eax
    348 ; BMI-NEXT:    addl $6, %eax
    349 ; BMI-NEXT:    retq
    350 
    351   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    352   %tobool = icmp eq i32 %v, 0
    353   %.op = add nuw nsw i32 %cnt, 6
    354   %add = select i1 %tobool, i32 5, i32 %.op
    355   ret i32 %add
    356 }
    357 
    358 define i32 @cttz_32_ne_select(i32 %v) nounwind {
    359 ; NOBMI-LABEL: cttz_32_ne_select:
    360 ; NOBMI:       # %bb.0:
    361 ; NOBMI-NEXT:    bsfl %edi, %ecx
    362 ; NOBMI-NEXT:    movl $-1, %eax
    363 ; NOBMI-NEXT:    cmovnel %ecx, %eax
    364 ; NOBMI-NEXT:    addl $6, %eax
    365 ; NOBMI-NEXT:    retq
    366 ;
    367 ; BMI-LABEL: cttz_32_ne_select:
    368 ; BMI:       # %bb.0:
    369 ; BMI-NEXT:    tzcntl %edi, %ecx
    370 ; BMI-NEXT:    movl $-1, %eax
    371 ; BMI-NEXT:    cmovael %ecx, %eax
    372 ; BMI-NEXT:    addl $6, %eax
    373 ; BMI-NEXT:    retq
    374 
    375   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    376   %tobool = icmp ne i32 %v, 0
    377   %.op = add nuw nsw i32 %cnt, 6
    378   %add = select i1 %tobool, i32 %.op, i32 5
    379   ret i32 %add
    380 }
    381