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