[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / lzcnt-tzcnt.ll
blobbced63e1cf85383fb5bb43841ff96568c4b24e88
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
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.
10 define 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
22 define 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
34 define 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
46 define 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
58 define 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
70 define 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
82 define i16 @test10_ctlz(ptr %ptr) {
83 ; CHECK-LABEL: test10_ctlz:
84 ; CHECK:       # %bb.0:
85 ; CHECK-NEXT:    lzcntw (%rdi), %ax
86 ; CHECK-NEXT:    retq
87   %v = load i16, ptr %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
95 define i32 @test11_ctlz(ptr %ptr) {
96 ; CHECK-LABEL: test11_ctlz:
97 ; CHECK:       # %bb.0:
98 ; CHECK-NEXT:    lzcntl (%rdi), %eax
99 ; CHECK-NEXT:    retq
100   %v = load i32, ptr %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
108 define i64 @test12_ctlz(ptr %ptr) {
109 ; CHECK-LABEL: test12_ctlz:
110 ; CHECK:       # %bb.0:
111 ; CHECK-NEXT:    lzcntq (%rdi), %rax
112 ; CHECK-NEXT:    retq
113   %v = load i64, ptr %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
121 define i16 @test13_ctlz(ptr %ptr) {
122 ; CHECK-LABEL: test13_ctlz:
123 ; CHECK:       # %bb.0:
124 ; CHECK-NEXT:    lzcntw (%rdi), %ax
125 ; CHECK-NEXT:    retq
126   %v = load i16, ptr %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
134 define i32 @test14_ctlz(ptr %ptr) {
135 ; CHECK-LABEL: test14_ctlz:
136 ; CHECK:       # %bb.0:
137 ; CHECK-NEXT:    lzcntl (%rdi), %eax
138 ; CHECK-NEXT:    retq
139   %v = load i32, ptr %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
147 define i64 @test15_ctlz(ptr %ptr) {
148 ; CHECK-LABEL: test15_ctlz:
149 ; CHECK:       # %bb.0:
150 ; CHECK-NEXT:    lzcntq (%rdi), %rax
151 ; CHECK-NEXT:    retq
152   %v = load i64, ptr %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
160 define i16 @test1_cttz(i16 %v) {
161 ; CHECK-LABEL: test1_cttz:
162 ; CHECK:       # %bb.0:
163 ; CHECK-NEXT:    orl $65536, %edi # imm = 0x10000
164 ; CHECK-NEXT:    tzcntl %edi, %eax
165 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
166 ; CHECK-NEXT:    retq
167   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
168   %tobool = icmp eq i16 %v, 0
169   %cond = select i1 %tobool, i16 16, i16 %cnt
170   ret i16 %cond
174 define i32 @test2_cttz(i32 %v) {
175 ; CHECK-LABEL: test2_cttz:
176 ; CHECK:       # %bb.0:
177 ; CHECK-NEXT:    tzcntl %edi, %eax
178 ; CHECK-NEXT:    retq
179   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
180   %tobool = icmp eq i32 %v, 0
181   %cond = select i1 %tobool, i32 32, i32 %cnt
182   ret i32 %cond
186 define i64 @test3_cttz(i64 %v) {
187 ; CHECK-LABEL: test3_cttz:
188 ; CHECK:       # %bb.0:
189 ; CHECK-NEXT:    tzcntq %rdi, %rax
190 ; CHECK-NEXT:    retq
191   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
192   %tobool = icmp eq i64 %v, 0
193   %cond = select i1 %tobool, i64 64, i64 %cnt
194   ret i64 %cond
198 define i16 @test4_cttz(i16 %v) {
199 ; CHECK-LABEL: test4_cttz:
200 ; CHECK:       # %bb.0:
201 ; CHECK-NEXT:    orl $65536, %edi # imm = 0x10000
202 ; CHECK-NEXT:    tzcntl %edi, %eax
203 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
204 ; CHECK-NEXT:    retq
205   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
206   %tobool = icmp eq i16 0, %v
207   %cond = select i1 %tobool, i16 16, i16 %cnt
208   ret i16 %cond
212 define i32 @test5_cttz(i32 %v) {
213 ; CHECK-LABEL: test5_cttz:
214 ; CHECK:       # %bb.0:
215 ; CHECK-NEXT:    tzcntl %edi, %eax
216 ; CHECK-NEXT:    retq
217   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
218   %tobool = icmp eq i32 0, %v
219   %cond = select i1 %tobool, i32 32, i32 %cnt
220   ret i32 %cond
224 define i64 @test6_cttz(i64 %v) {
225 ; CHECK-LABEL: test6_cttz:
226 ; CHECK:       # %bb.0:
227 ; CHECK-NEXT:    tzcntq %rdi, %rax
228 ; CHECK-NEXT:    retq
229   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
230   %tobool = icmp eq i64 0, %v
231   %cond = select i1 %tobool, i64 64, i64 %cnt
232   ret i64 %cond
236 define i16 @test10_cttz(ptr %ptr) {
237 ; CHECK-LABEL: test10_cttz:
238 ; CHECK:       # %bb.0:
239 ; CHECK-NEXT:    movzwl (%rdi), %eax
240 ; CHECK-NEXT:    orl $65536, %eax # imm = 0x10000
241 ; CHECK-NEXT:    tzcntl %eax, %eax
242 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
243 ; CHECK-NEXT:    retq
244   %v = load i16, ptr %ptr
245   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
246   %tobool = icmp eq i16 %v, 0
247   %cond = select i1 %tobool, i16 16, i16 %cnt
248   ret i16 %cond
252 define i32 @test11_cttz(ptr %ptr) {
253 ; CHECK-LABEL: test11_cttz:
254 ; CHECK:       # %bb.0:
255 ; CHECK-NEXT:    tzcntl (%rdi), %eax
256 ; CHECK-NEXT:    retq
257   %v = load i32, ptr %ptr
258   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
259   %tobool = icmp eq i32 %v, 0
260   %cond = select i1 %tobool, i32 32, i32 %cnt
261   ret i32 %cond
265 define i64 @test12_cttz(ptr %ptr) {
266 ; CHECK-LABEL: test12_cttz:
267 ; CHECK:       # %bb.0:
268 ; CHECK-NEXT:    tzcntq (%rdi), %rax
269 ; CHECK-NEXT:    retq
270   %v = load i64, ptr %ptr
271   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
272   %tobool = icmp eq i64 %v, 0
273   %cond = select i1 %tobool, i64 64, i64 %cnt
274   ret i64 %cond
278 define i16 @test13_cttz(ptr %ptr) {
279 ; CHECK-LABEL: test13_cttz:
280 ; CHECK:       # %bb.0:
281 ; CHECK-NEXT:    movzwl (%rdi), %eax
282 ; CHECK-NEXT:    orl $65536, %eax # imm = 0x10000
283 ; CHECK-NEXT:    tzcntl %eax, %eax
284 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
285 ; CHECK-NEXT:    retq
286   %v = load i16, ptr %ptr
287   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
288   %tobool = icmp eq i16 0, %v
289   %cond = select i1 %tobool, i16 16, i16 %cnt
290   ret i16 %cond
294 define i32 @test14_cttz(ptr %ptr) {
295 ; CHECK-LABEL: test14_cttz:
296 ; CHECK:       # %bb.0:
297 ; CHECK-NEXT:    tzcntl (%rdi), %eax
298 ; CHECK-NEXT:    retq
299   %v = load i32, ptr %ptr
300   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
301   %tobool = icmp eq i32 0, %v
302   %cond = select i1 %tobool, i32 32, i32 %cnt
303   ret i32 %cond
307 define i64 @test15_cttz(ptr %ptr) {
308 ; CHECK-LABEL: test15_cttz:
309 ; CHECK:       # %bb.0:
310 ; CHECK-NEXT:    tzcntq (%rdi), %rax
311 ; CHECK-NEXT:    retq
312   %v = load i64, ptr %ptr
313   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
314   %tobool = icmp eq i64 0, %v
315   %cond = select i1 %tobool, i64 64, i64 %cnt
316   ret i64 %cond
320 define i16 @test4b_ctlz(i16 %v) {
321 ; CHECK-LABEL: test4b_ctlz:
322 ; CHECK:       # %bb.0:
323 ; CHECK-NEXT:    lzcntw %di, %ax
324 ; CHECK-NEXT:    retq
325   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
326   %tobool = icmp ne i16 %v, 0
327   %cond = select i1 %tobool, i16 %cnt, i16 16
328   ret i16 %cond
332 define i32 @test5b_ctlz(i32 %v) {
333 ; CHECK-LABEL: test5b_ctlz:
334 ; CHECK:       # %bb.0:
335 ; CHECK-NEXT:    lzcntl %edi, %eax
336 ; CHECK-NEXT:    retq
337   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
338   %tobool = icmp ne i32 %v, 0
339   %cond = select i1 %tobool, i32 %cnt, i32 32
340   ret i32 %cond
344 define i64 @test6b_ctlz(i64 %v) {
345 ; CHECK-LABEL: test6b_ctlz:
346 ; CHECK:       # %bb.0:
347 ; CHECK-NEXT:    lzcntq %rdi, %rax
348 ; CHECK-NEXT:    retq
349   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
350   %tobool = icmp ne i64 %v, 0
351   %cond = select i1 %tobool, i64 %cnt, i64 64
352   ret i64 %cond
356 define i16 @test4b_cttz(i16 %v) {
357 ; CHECK-LABEL: test4b_cttz:
358 ; CHECK:       # %bb.0:
359 ; CHECK-NEXT:    orl $65536, %edi # imm = 0x10000
360 ; CHECK-NEXT:    tzcntl %edi, %eax
361 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
362 ; CHECK-NEXT:    retq
363   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
364   %tobool = icmp ne i16 %v, 0
365   %cond = select i1 %tobool, i16 %cnt, i16 16
366   ret i16 %cond
370 define i32 @test5b_cttz(i32 %v) {
371 ; CHECK-LABEL: test5b_cttz:
372 ; CHECK:       # %bb.0:
373 ; CHECK-NEXT:    tzcntl %edi, %eax
374 ; CHECK-NEXT:    retq
375   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
376   %tobool = icmp ne i32 %v, 0
377   %cond = select i1 %tobool, i32 %cnt, i32 32
378   ret i32 %cond
382 define i64 @test6b_cttz(i64 %v) {
383 ; CHECK-LABEL: test6b_cttz:
384 ; CHECK:       # %bb.0:
385 ; CHECK-NEXT:    tzcntq %rdi, %rax
386 ; CHECK-NEXT:    retq
387   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
388   %tobool = icmp ne i64 %v, 0
389   %cond = select i1 %tobool, i64 %cnt, i64 64
390   ret i64 %cond
394 declare i64 @llvm.cttz.i64(i64, i1)
395 declare i32 @llvm.cttz.i32(i32, i1)
396 declare i16 @llvm.cttz.i16(i16, i1)
397 declare i64 @llvm.ctlz.i64(i64, i1)
398 declare i32 @llvm.ctlz.i32(i32, i1)
399 declare i16 @llvm.ctlz.i16(i16, i1)