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-pc-linux -mattr=+bmi,+bmi2,+popcnt,+lzcnt | FileCheck %s
      3 declare void @foo(i32)
      4 declare void @foo32(i32)
      5 declare void @foo64(i64)
      6 
      7 define void @neg(i32 %x) nounwind {
      8 ; CHECK-LABEL: neg:
      9 ; CHECK:       # %bb.0:
     10 ; CHECK-NEXT:    negl %edi
     11 ; CHECK-NEXT:    je .LBB0_1
     12 ; CHECK-NEXT:  # %bb.2: # %bb
     13 ; CHECK-NEXT:    jmp foo # TAILCALL
     14 ; CHECK-NEXT:  .LBB0_1: # %return
     15 ; CHECK-NEXT:    retq
     16   %sub = sub i32 0, %x
     17   %cmp = icmp eq i32 %sub, 0
     18   br i1 %cmp, label %return, label %bb
     19 
     20 bb:
     21   tail call void @foo(i32 %sub)
     22   br label %return
     23 
     24 return:
     25   ret void
     26 }
     27 
     28 define void @sar(i32 %x) nounwind {
     29 ; CHECK-LABEL: sar:
     30 ; CHECK:       # %bb.0:
     31 ; CHECK-NEXT:    sarl %edi
     32 ; CHECK-NEXT:    je .LBB1_1
     33 ; CHECK-NEXT:  # %bb.2: # %bb
     34 ; CHECK-NEXT:    jmp foo # TAILCALL
     35 ; CHECK-NEXT:  .LBB1_1: # %return
     36 ; CHECK-NEXT:    retq
     37   %ashr = ashr i32 %x, 1
     38   %cmp = icmp eq i32 %ashr, 0
     39   br i1 %cmp, label %return, label %bb
     40 
     41 bb:
     42   tail call void @foo(i32 %ashr)
     43   br label %return
     44 
     45 return:
     46   ret void
     47 }
     48 
     49 define void @shr(i32 %x) nounwind {
     50 ; CHECK-LABEL: shr:
     51 ; CHECK:       # %bb.0:
     52 ; CHECK-NEXT:    shrl %edi
     53 ; CHECK-NEXT:    je .LBB2_1
     54 ; CHECK-NEXT:  # %bb.2: # %bb
     55 ; CHECK-NEXT:    jmp foo # TAILCALL
     56 ; CHECK-NEXT:  .LBB2_1: # %return
     57 ; CHECK-NEXT:    retq
     58   %ashr = lshr i32 %x, 1
     59   %cmp = icmp eq i32 %ashr, 0
     60   br i1 %cmp, label %return, label %bb
     61 
     62 bb:
     63   tail call void @foo(i32 %ashr)
     64   br label %return
     65 
     66 return:
     67   ret void
     68 }
     69 
     70 define void @shri(i32 %x) nounwind {
     71 ; CHECK-LABEL: shri:
     72 ; CHECK:       # %bb.0:
     73 ; CHECK-NEXT:    shrl $3, %edi
     74 ; CHECK-NEXT:    je .LBB3_1
     75 ; CHECK-NEXT:  # %bb.2: # %bb
     76 ; CHECK-NEXT:    jmp foo # TAILCALL
     77 ; CHECK-NEXT:  .LBB3_1: # %return
     78 ; CHECK-NEXT:    retq
     79   %ashr = lshr i32 %x, 3
     80   %cmp = icmp eq i32 %ashr, 0
     81   br i1 %cmp, label %return, label %bb
     82 
     83 bb:
     84   tail call void @foo(i32 %ashr)
     85   br label %return
     86 
     87 return:
     88   ret void
     89 }
     90 
     91 define void @shl(i32 %x) nounwind {
     92 ; CHECK-LABEL: shl:
     93 ; CHECK:       # %bb.0:
     94 ; CHECK-NEXT:    addl %edi, %edi
     95 ; CHECK-NEXT:    je .LBB4_1
     96 ; CHECK-NEXT:  # %bb.2: # %bb
     97 ; CHECK-NEXT:    jmp foo # TAILCALL
     98 ; CHECK-NEXT:  .LBB4_1: # %return
     99 ; CHECK-NEXT:    retq
    100   %shl = shl i32 %x, 1
    101   %cmp = icmp eq i32 %shl, 0
    102   br i1 %cmp, label %return, label %bb
    103 
    104 bb:
    105   tail call void @foo(i32 %shl)
    106   br label %return
    107 
    108 return:
    109   ret void
    110 }
    111 
    112 define void @shli(i32 %x) nounwind {
    113 ; CHECK-LABEL: shli:
    114 ; CHECK:       # %bb.0:
    115 ; CHECK-NEXT:    shll $4, %edi
    116 ; CHECK-NEXT:    je .LBB5_1
    117 ; CHECK-NEXT:  # %bb.2: # %bb
    118 ; CHECK-NEXT:    jmp foo # TAILCALL
    119 ; CHECK-NEXT:  .LBB5_1: # %return
    120 ; CHECK-NEXT:    retq
    121   %shl = shl i32 %x, 4
    122   %cmp = icmp eq i32 %shl, 0
    123   br i1 %cmp, label %return, label %bb
    124 
    125 bb:
    126   tail call void @foo(i32 %shl)
    127   br label %return
    128 
    129 return:
    130   ret void
    131 }
    132 
    133 define zeroext i1 @adc(i128 %x) nounwind {
    134 ; CHECK-LABEL: adc:
    135 ; CHECK:       # %bb.0:
    136 ; CHECK-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
    137 ; CHECK-NEXT:    addq %rdi, %rax
    138 ; CHECK-NEXT:    adcq $0, %rsi
    139 ; CHECK-NEXT:    sete %al
    140 ; CHECK-NEXT:    retq
    141   %add = add i128 %x, 9223372036854775808
    142   %cmp = icmp ult i128 %add, 18446744073709551616
    143   ret i1 %cmp
    144 }
    145 
    146 define zeroext i1 @sbb(i128 %x, i128 %y) nounwind {
    147 ; CHECK-LABEL: sbb:
    148 ; CHECK:       # %bb.0:
    149 ; CHECK-NEXT:    cmpq %rdx, %rdi
    150 ; CHECK-NEXT:    sbbq %rcx, %rsi
    151 ; CHECK-NEXT:    setns %al
    152 ; CHECK-NEXT:    retq
    153   %sub = sub i128 %x, %y
    154   %cmp = icmp sge i128 %sub, 0
    155   ret i1 %cmp
    156 }
    157 
    158 define void @andn(i32 %x, i32 %y) nounwind {
    159 ; CHECK-LABEL: andn:
    160 ; CHECK:       # %bb.0:
    161 ; CHECK-NEXT:    andnl %esi, %edi, %edi
    162 ; CHECK-NEXT:    je .LBB8_1
    163 ; CHECK-NEXT:  # %bb.2: # %bb
    164 ; CHECK-NEXT:    jmp foo # TAILCALL
    165 ; CHECK-NEXT:  .LBB8_1: # %return
    166 ; CHECK-NEXT:    retq
    167   %not = xor i32 %x, -1
    168   %andn = and i32 %y, %not
    169   %cmp = icmp eq i32 %andn, 0
    170   br i1 %cmp, label %return, label %bb
    171 
    172 bb:
    173   tail call void @foo(i32 %andn)
    174   br label %return
    175 
    176 return:
    177   ret void
    178 }
    179 
    180 declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone
    181 define void @bextr(i32 %x, i32 %y) nounwind {
    182 ; CHECK-LABEL: bextr:
    183 ; CHECK:       # %bb.0:
    184 ; CHECK-NEXT:    bextrl %esi, %edi, %edi
    185 ; CHECK-NEXT:    je .LBB9_1
    186 ; CHECK-NEXT:  # %bb.2: # %bb
    187 ; CHECK-NEXT:    jmp foo # TAILCALL
    188 ; CHECK-NEXT:  .LBB9_1: # %return
    189 ; CHECK-NEXT:    retq
    190   %bextr = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
    191   %cmp = icmp eq i32 %bextr, 0
    192   br i1 %cmp, label %return, label %bb
    193 
    194 bb:
    195   tail call void @foo(i32 %bextr)
    196   br label %return
    197 
    198 return:
    199   ret void
    200 }
    201 
    202 declare i32 @llvm.ctpop.i32(i32) nounwind readnone
    203 define void @popcnt(i32 %x) nounwind {
    204 ; CHECK-LABEL: popcnt:
    205 ; CHECK:       # %bb.0:
    206 ; CHECK-NEXT:    popcntl %edi, %edi
    207 ; CHECK-NEXT:    je .LBB10_1
    208 ; CHECK-NEXT:  # %bb.2: # %bb
    209 ; CHECK-NEXT:    jmp foo # TAILCALL
    210 ; CHECK-NEXT:  .LBB10_1: # %return
    211 ; CHECK-NEXT:    retq
    212   %popcnt = tail call i32 @llvm.ctpop.i32(i32 %x)
    213   %cmp = icmp eq i32 %popcnt, 0
    214   br i1 %cmp, label %return, label %bb
    215 bb:
    216   tail call void @foo(i32 %popcnt)
    217   br label %return
    218 return:
    219   ret void
    220 }
    221 
    222 declare i64 @llvm.cttz.i64(i64, i1)
    223 define i64 @testCTZ(i64 %v) nounwind {
    224 ; CHECK-LABEL: testCTZ:
    225 ; CHECK:       # %bb.0:
    226 ; CHECK-NEXT:    tzcntq %rdi, %rcx
    227 ; CHECK-NEXT:    movl $255, %eax
    228 ; CHECK-NEXT:    cmovaeq %rcx, %rax
    229 ; CHECK-NEXT:    retq
    230   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    231   %tobool = icmp eq i64 %v, 0
    232   %cond = select i1 %tobool, i64 255, i64 %cnt
    233   ret i64 %cond
    234 }
    235 
    236 declare i32 @llvm.cttz.i32(i32, i1)
    237 define void @testCTZ2(i32 %v) nounwind {
    238 ; CHECK-LABEL: testCTZ2:
    239 ; CHECK:       # %bb.0:
    240 ; CHECK-NEXT:    pushq %rbx
    241 ; CHECK-NEXT:    tzcntl %edi, %ebx
    242 ; CHECK-NEXT:    jb .LBB12_2
    243 ; CHECK-NEXT:  # %bb.1: # %bb
    244 ; CHECK-NEXT:    movl %ebx, %edi
    245 ; CHECK-NEXT:    callq foo
    246 ; CHECK-NEXT:  .LBB12_2: # %return
    247 ; CHECK-NEXT:    movl %ebx, %edi
    248 ; CHECK-NEXT:    popq %rbx
    249 ; CHECK-NEXT:    jmp foo32 # TAILCALL
    250   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    251   %cmp = icmp eq i32 %v, 0
    252   br i1 %cmp, label %return, label %bb
    253 
    254 bb:
    255   tail call void @foo(i32 %cnt)
    256   br label %return
    257 
    258 return:
    259   tail call void @foo32(i32 %cnt)
    260   ret void
    261 }
    262 
    263 define void @testCTZ3(i32 %v) nounwind {
    264 ; CHECK-LABEL: testCTZ3:
    265 ; CHECK:       # %bb.0:
    266 ; CHECK-NEXT:    pushq %rbx
    267 ; CHECK-NEXT:    tzcntl %edi, %ebx
    268 ; CHECK-NEXT:    jae .LBB13_2
    269 ; CHECK-NEXT:  # %bb.1: # %bb
    270 ; CHECK-NEXT:    movl %ebx, %edi
    271 ; CHECK-NEXT:    callq foo
    272 ; CHECK-NEXT:  .LBB13_2: # %return
    273 ; CHECK-NEXT:    movl %ebx, %edi
    274 ; CHECK-NEXT:    popq %rbx
    275 ; CHECK-NEXT:    jmp foo32 # TAILCALL
    276   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    277   %cmp = icmp ne i32 %v, 0
    278   br i1 %cmp, label %return, label %bb
    279 
    280 bb:
    281   tail call void @foo(i32 %cnt)
    282   br label %return
    283 
    284 return:
    285   tail call void @foo32(i32 %cnt)
    286   ret void
    287 }
    288 
    289 declare i64 @llvm.ctlz.i64(i64, i1)
    290 define i64 @testCLZ(i64 %v) nounwind {
    291 ; CHECK-LABEL: testCLZ:
    292 ; CHECK:       # %bb.0:
    293 ; CHECK-NEXT:    lzcntq %rdi, %rcx
    294 ; CHECK-NEXT:    movl $255, %eax
    295 ; CHECK-NEXT:    cmovaeq %rcx, %rax
    296 ; CHECK-NEXT:    retq
    297   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    298   %tobool = icmp ne i64 %v, 0
    299   %cond = select i1 %tobool, i64 %cnt, i64 255
    300   ret i64 %cond
    301 }
    302 
    303 declare i64 @llvm.ctpop.i64(i64)
    304 define i64 @testPOPCNT(i64 %v) nounwind {
    305 ; CHECK-LABEL: testPOPCNT:
    306 ; CHECK:       # %bb.0:
    307 ; CHECK-NEXT:    popcntq %rdi, %rcx
    308 ; CHECK-NEXT:    movl $255, %eax
    309 ; CHECK-NEXT:    cmovneq %rcx, %rax
    310 ; CHECK-NEXT:    retq
    311   %cnt = tail call i64 @llvm.ctpop.i64(i64 %v)
    312   %tobool = icmp ne i64 %v, 0
    313   %cond = select i1 %tobool, i64 %cnt, i64 255
    314   ret i64 %cond
    315 }
    316