• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+lzcnt | FileCheck %s
3
4; LZCNT and TZCNT will always produce the operand size when the input operand
5; is zero. This test is to verify that we efficiently select LZCNT/TZCNT
6; based on the fact that the 'icmp+select' sequence is always redundant
7; in every function defined below.
8
9
10define i16 @test1_ctlz(i16 %v) {
11; CHECK-LABEL: test1_ctlz:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    lzcntw %di, %ax
14; CHECK-NEXT:    retq
15  %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
16  %tobool = icmp eq i16 %v, 0
17  %cond = select i1 %tobool, i16 16, i16 %cnt
18  ret i16 %cond
19}
20
21
22define i32 @test2_ctlz(i32 %v) {
23; CHECK-LABEL: test2_ctlz:
24; CHECK:       # %bb.0:
25; CHECK-NEXT:    lzcntl %edi, %eax
26; CHECK-NEXT:    retq
27  %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
28  %tobool = icmp eq i32 %v, 0
29  %cond = select i1 %tobool, i32 32, i32 %cnt
30  ret i32 %cond
31}
32
33
34define i64 @test3_ctlz(i64 %v) {
35; CHECK-LABEL: test3_ctlz:
36; CHECK:       # %bb.0:
37; CHECK-NEXT:    lzcntq %rdi, %rax
38; CHECK-NEXT:    retq
39  %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
40  %tobool = icmp eq i64 %v, 0
41  %cond = select i1 %tobool, i64 64, i64 %cnt
42  ret i64 %cond
43}
44
45
46define i16 @test4_ctlz(i16 %v) {
47; CHECK-LABEL: test4_ctlz:
48; CHECK:       # %bb.0:
49; CHECK-NEXT:    lzcntw %di, %ax
50; CHECK-NEXT:    retq
51  %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
52  %tobool = icmp eq i16 0, %v
53  %cond = select i1 %tobool, i16 16, i16 %cnt
54  ret i16 %cond
55}
56
57
58define i32 @test5_ctlz(i32 %v) {
59; CHECK-LABEL: test5_ctlz:
60; CHECK:       # %bb.0:
61; CHECK-NEXT:    lzcntl %edi, %eax
62; CHECK-NEXT:    retq
63  %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
64  %tobool = icmp eq i32 0, %v
65  %cond = select i1 %tobool, i32 32, i32 %cnt
66  ret i32 %cond
67}
68
69
70define i64 @test6_ctlz(i64 %v) {
71; CHECK-LABEL: test6_ctlz:
72; CHECK:       # %bb.0:
73; CHECK-NEXT:    lzcntq %rdi, %rax
74; CHECK-NEXT:    retq
75  %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
76  %tobool = icmp eq i64 0, %v
77  %cond = select i1 %tobool, i64 64, i64 %cnt
78  ret i64 %cond
79}
80
81
82define i16 @test10_ctlz(i16* %ptr) {
83; CHECK-LABEL: test10_ctlz:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    lzcntw (%rdi), %ax
86; CHECK-NEXT:    retq
87  %v = load i16, i16* %ptr
88  %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
89  %tobool = icmp eq i16 %v, 0
90  %cond = select i1 %tobool, i16 16, i16 %cnt
91  ret i16 %cond
92}
93
94
95define i32 @test11_ctlz(i32* %ptr) {
96; CHECK-LABEL: test11_ctlz:
97; CHECK:       # %bb.0:
98; CHECK-NEXT:    lzcntl (%rdi), %eax
99; CHECK-NEXT:    retq
100  %v = load i32, i32* %ptr
101  %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
102  %tobool = icmp eq i32 %v, 0
103  %cond = select i1 %tobool, i32 32, i32 %cnt
104  ret i32 %cond
105}
106
107
108define i64 @test12_ctlz(i64* %ptr) {
109; CHECK-LABEL: test12_ctlz:
110; CHECK:       # %bb.0:
111; CHECK-NEXT:    lzcntq (%rdi), %rax
112; CHECK-NEXT:    retq
113  %v = load i64, i64* %ptr
114  %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
115  %tobool = icmp eq i64 %v, 0
116  %cond = select i1 %tobool, i64 64, i64 %cnt
117  ret i64 %cond
118}
119
120
121define i16 @test13_ctlz(i16* %ptr) {
122; CHECK-LABEL: test13_ctlz:
123; CHECK:       # %bb.0:
124; CHECK-NEXT:    lzcntw (%rdi), %ax
125; CHECK-NEXT:    retq
126  %v = load i16, i16* %ptr
127  %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
128  %tobool = icmp eq i16 0, %v
129  %cond = select i1 %tobool, i16 16, i16 %cnt
130  ret i16 %cond
131}
132
133
134define i32 @test14_ctlz(i32* %ptr) {
135; CHECK-LABEL: test14_ctlz:
136; CHECK:       # %bb.0:
137; CHECK-NEXT:    lzcntl (%rdi), %eax
138; CHECK-NEXT:    retq
139  %v = load i32, i32* %ptr
140  %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
141  %tobool = icmp eq i32 0, %v
142  %cond = select i1 %tobool, i32 32, i32 %cnt
143  ret i32 %cond
144}
145
146
147define i64 @test15_ctlz(i64* %ptr) {
148; CHECK-LABEL: test15_ctlz:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    lzcntq (%rdi), %rax
151; CHECK-NEXT:    retq
152  %v = load i64, i64* %ptr
153  %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
154  %tobool = icmp eq i64 0, %v
155  %cond = select i1 %tobool, i64 64, i64 %cnt
156  ret i64 %cond
157}
158
159
160define i16 @test1_cttz(i16 %v) {
161; CHECK-LABEL: test1_cttz:
162; CHECK:       # %bb.0:
163; CHECK-NEXT:    tzcntw %di, %ax
164; CHECK-NEXT:    retq
165  %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
166  %tobool = icmp eq i16 %v, 0
167  %cond = select i1 %tobool, i16 16, i16 %cnt
168  ret i16 %cond
169}
170
171
172define i32 @test2_cttz(i32 %v) {
173; CHECK-LABEL: test2_cttz:
174; CHECK:       # %bb.0:
175; CHECK-NEXT:    tzcntl %edi, %eax
176; CHECK-NEXT:    retq
177  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
178  %tobool = icmp eq i32 %v, 0
179  %cond = select i1 %tobool, i32 32, i32 %cnt
180  ret i32 %cond
181}
182
183
184define i64 @test3_cttz(i64 %v) {
185; CHECK-LABEL: test3_cttz:
186; CHECK:       # %bb.0:
187; CHECK-NEXT:    tzcntq %rdi, %rax
188; CHECK-NEXT:    retq
189  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
190  %tobool = icmp eq i64 %v, 0
191  %cond = select i1 %tobool, i64 64, i64 %cnt
192  ret i64 %cond
193}
194
195
196define i16 @test4_cttz(i16 %v) {
197; CHECK-LABEL: test4_cttz:
198; CHECK:       # %bb.0:
199; CHECK-NEXT:    tzcntw %di, %ax
200; CHECK-NEXT:    retq
201  %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
202  %tobool = icmp eq i16 0, %v
203  %cond = select i1 %tobool, i16 16, i16 %cnt
204  ret i16 %cond
205}
206
207
208define i32 @test5_cttz(i32 %v) {
209; CHECK-LABEL: test5_cttz:
210; CHECK:       # %bb.0:
211; CHECK-NEXT:    tzcntl %edi, %eax
212; CHECK-NEXT:    retq
213  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
214  %tobool = icmp eq i32 0, %v
215  %cond = select i1 %tobool, i32 32, i32 %cnt
216  ret i32 %cond
217}
218
219
220define i64 @test6_cttz(i64 %v) {
221; CHECK-LABEL: test6_cttz:
222; CHECK:       # %bb.0:
223; CHECK-NEXT:    tzcntq %rdi, %rax
224; CHECK-NEXT:    retq
225  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
226  %tobool = icmp eq i64 0, %v
227  %cond = select i1 %tobool, i64 64, i64 %cnt
228  ret i64 %cond
229}
230
231
232define i16 @test10_cttz(i16* %ptr) {
233; CHECK-LABEL: test10_cttz:
234; CHECK:       # %bb.0:
235; CHECK-NEXT:    tzcntw (%rdi), %ax
236; CHECK-NEXT:    retq
237  %v = load i16, i16* %ptr
238  %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
239  %tobool = icmp eq i16 %v, 0
240  %cond = select i1 %tobool, i16 16, i16 %cnt
241  ret i16 %cond
242}
243
244
245define i32 @test11_cttz(i32* %ptr) {
246; CHECK-LABEL: test11_cttz:
247; CHECK:       # %bb.0:
248; CHECK-NEXT:    tzcntl (%rdi), %eax
249; CHECK-NEXT:    retq
250  %v = load i32, i32* %ptr
251  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
252  %tobool = icmp eq i32 %v, 0
253  %cond = select i1 %tobool, i32 32, i32 %cnt
254  ret i32 %cond
255}
256
257
258define i64 @test12_cttz(i64* %ptr) {
259; CHECK-LABEL: test12_cttz:
260; CHECK:       # %bb.0:
261; CHECK-NEXT:    tzcntq (%rdi), %rax
262; CHECK-NEXT:    retq
263  %v = load i64, i64* %ptr
264  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
265  %tobool = icmp eq i64 %v, 0
266  %cond = select i1 %tobool, i64 64, i64 %cnt
267  ret i64 %cond
268}
269
270
271define i16 @test13_cttz(i16* %ptr) {
272; CHECK-LABEL: test13_cttz:
273; CHECK:       # %bb.0:
274; CHECK-NEXT:    tzcntw (%rdi), %ax
275; CHECK-NEXT:    retq
276  %v = load i16, i16* %ptr
277  %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
278  %tobool = icmp eq i16 0, %v
279  %cond = select i1 %tobool, i16 16, i16 %cnt
280  ret i16 %cond
281}
282
283
284define i32 @test14_cttz(i32* %ptr) {
285; CHECK-LABEL: test14_cttz:
286; CHECK:       # %bb.0:
287; CHECK-NEXT:    tzcntl (%rdi), %eax
288; CHECK-NEXT:    retq
289  %v = load i32, i32* %ptr
290  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
291  %tobool = icmp eq i32 0, %v
292  %cond = select i1 %tobool, i32 32, i32 %cnt
293  ret i32 %cond
294}
295
296
297define i64 @test15_cttz(i64* %ptr) {
298; CHECK-LABEL: test15_cttz:
299; CHECK:       # %bb.0:
300; CHECK-NEXT:    tzcntq (%rdi), %rax
301; CHECK-NEXT:    retq
302  %v = load i64, i64* %ptr
303  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
304  %tobool = icmp eq i64 0, %v
305  %cond = select i1 %tobool, i64 64, i64 %cnt
306  ret i64 %cond
307}
308
309
310define i16 @test4b_ctlz(i16 %v) {
311; CHECK-LABEL: test4b_ctlz:
312; CHECK:       # %bb.0:
313; CHECK-NEXT:    lzcntw %di, %ax
314; CHECK-NEXT:    retq
315  %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
316  %tobool = icmp ne i16 %v, 0
317  %cond = select i1 %tobool, i16 %cnt, i16 16
318  ret i16 %cond
319}
320
321
322define i32 @test5b_ctlz(i32 %v) {
323; CHECK-LABEL: test5b_ctlz:
324; CHECK:       # %bb.0:
325; CHECK-NEXT:    lzcntl %edi, %eax
326; CHECK-NEXT:    retq
327  %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
328  %tobool = icmp ne i32 %v, 0
329  %cond = select i1 %tobool, i32 %cnt, i32 32
330  ret i32 %cond
331}
332
333
334define i64 @test6b_ctlz(i64 %v) {
335; CHECK-LABEL: test6b_ctlz:
336; CHECK:       # %bb.0:
337; CHECK-NEXT:    lzcntq %rdi, %rax
338; CHECK-NEXT:    retq
339  %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
340  %tobool = icmp ne i64 %v, 0
341  %cond = select i1 %tobool, i64 %cnt, i64 64
342  ret i64 %cond
343}
344
345
346define i16 @test4b_cttz(i16 %v) {
347; CHECK-LABEL: test4b_cttz:
348; CHECK:       # %bb.0:
349; CHECK-NEXT:    tzcntw %di, %ax
350; CHECK-NEXT:    retq
351  %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
352  %tobool = icmp ne i16 %v, 0
353  %cond = select i1 %tobool, i16 %cnt, i16 16
354  ret i16 %cond
355}
356
357
358define i32 @test5b_cttz(i32 %v) {
359; CHECK-LABEL: test5b_cttz:
360; CHECK:       # %bb.0:
361; CHECK-NEXT:    tzcntl %edi, %eax
362; CHECK-NEXT:    retq
363  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
364  %tobool = icmp ne i32 %v, 0
365  %cond = select i1 %tobool, i32 %cnt, i32 32
366  ret i32 %cond
367}
368
369
370define i64 @test6b_cttz(i64 %v) {
371; CHECK-LABEL: test6b_cttz:
372; CHECK:       # %bb.0:
373; CHECK-NEXT:    tzcntq %rdi, %rax
374; CHECK-NEXT:    retq
375  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
376  %tobool = icmp ne i64 %v, 0
377  %cond = select i1 %tobool, i64 %cnt, i64 64
378  ret i64 %cond
379}
380
381
382declare i64 @llvm.cttz.i64(i64, i1)
383declare i32 @llvm.cttz.i32(i32, i1)
384declare i16 @llvm.cttz.i16(i16, i1)
385declare i64 @llvm.ctlz.i64(i64, i1)
386declare i32 @llvm.ctlz.i32(i32, i1)
387declare i16 @llvm.ctlz.i16(i16, i1)
388
389