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