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
4 declare void @foo32(i32)
5 declare void @foo64(i64)
7 define void @neg(i32 %x) nounwind {
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
17 %cmp = icmp eq i32 %sub, 0
18 br i1 %cmp, label %return, label %bb
21 tail call void @foo(i32 %sub)
28 define void @sar(i32 %x) nounwind {
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
37 %ashr = ashr i32 %x, 1
38 %cmp = icmp eq i32 %ashr, 0
39 br i1 %cmp, label %return, label %bb
42 tail call void @foo(i32 %ashr)
49 define void @shr(i32 %x) nounwind {
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
58 %ashr = lshr i32 %x, 1
59 %cmp = icmp eq i32 %ashr, 0
60 br i1 %cmp, label %return, label %bb
63 tail call void @foo(i32 %ashr)
70 define void @shri(i32 %x) nounwind {
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
79 %ashr = lshr i32 %x, 3
80 %cmp = icmp eq i32 %ashr, 0
81 br i1 %cmp, label %return, label %bb
84 tail call void @foo(i32 %ashr)
91 define void @shl(i32 %x) nounwind {
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
101 %cmp = icmp eq i32 %shl, 0
102 br i1 %cmp, label %return, label %bb
105 tail call void @foo(i32 %shl)
112 define void @shli(i32 %x) nounwind {
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
122 %cmp = icmp eq i32 %shl, 0
123 br i1 %cmp, label %return, label %bb
126 tail call void @foo(i32 %shl)
133 define zeroext i1 @adc(i128 %x) nounwind {
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
141 %add = add i128 %x, 9223372036854775808
142 %cmp = icmp ult i128 %add, 18446744073709551616
146 define zeroext i1 @sbb(i128 %x, i128 %y) nounwind {
149 ; CHECK-NEXT: cmpq %rdx, %rdi
150 ; CHECK-NEXT: sbbq %rcx, %rsi
151 ; CHECK-NEXT: setns %al
153 %sub = sub i128 %x, %y
154 %cmp = icmp sge i128 %sub, 0
158 define void @andn(i32 %x, i32 %y) nounwind {
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
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
173 tail call void @foo(i32 %andn)
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:
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
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
195 tail call void @foo(i32 %bextr)
202 declare i32 @llvm.ctpop.i32(i32) nounwind readnone
203 define void @popcnt(i32 %x) nounwind {
204 ; CHECK-LABEL: popcnt:
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
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
216 tail call void @foo(i32 %popcnt)
222 declare i64 @llvm.cttz.i64(i64, i1)
223 define i64 @testCTZ(i64 %v) nounwind {
224 ; CHECK-LABEL: testCTZ:
226 ; CHECK-NEXT: tzcntq %rdi, %rcx
227 ; CHECK-NEXT: movl $255, %eax
228 ; CHECK-NEXT: cmovaeq %rcx, %rax
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
236 declare i32 @llvm.cttz.i32(i32, i1)
237 define void @testCTZ2(i32 %v) nounwind {
238 ; CHECK-LABEL: testCTZ2:
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
255 tail call void @foo(i32 %cnt)
259 tail call void @foo32(i32 %cnt)
263 define void @testCTZ3(i32 %v) nounwind {
264 ; CHECK-LABEL: testCTZ3:
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
281 tail call void @foo(i32 %cnt)
285 tail call void @foo32(i32 %cnt)
289 declare i64 @llvm.ctlz.i64(i64, i1)
290 define i64 @testCLZ(i64 %v) nounwind {
291 ; CHECK-LABEL: testCLZ:
293 ; CHECK-NEXT: lzcntq %rdi, %rcx
294 ; CHECK-NEXT: movl $255, %eax
295 ; CHECK-NEXT: cmovaeq %rcx, %rax
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
303 declare i64 @llvm.ctpop.i64(i64)
304 define i64 @testPOPCNT(i64 %v) nounwind {
305 ; CHECK-LABEL: testPOPCNT:
307 ; CHECK-NEXT: popcntq %rdi, %rcx
308 ; CHECK-NEXT: movl $255, %eax
309 ; CHECK-NEXT: cmovneq %rcx, %rax
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