[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / lzcnt-tzcnt.ll
blobabf7e93294cc57f7846936920bfcfb8fa908bde1
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(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
95 define 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
108 define 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
121 define 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
134 define 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
147 define 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
160 define 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
172 define 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
184 define 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
196 define 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
208 define 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
220 define 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
232 define 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
245 define 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
258 define 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
271 define 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
284 define 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
297 define 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
310 define 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
322 define 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
334 define 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
346 define 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
358 define 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
370 define 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
382 declare i64 @llvm.cttz.i64(i64, i1)
383 declare i32 @llvm.cttz.i32(i32, i1)
384 declare i16 @llvm.cttz.i16(i16, i1)
385 declare i64 @llvm.ctlz.i64(i64, i1)
386 declare i32 @llvm.ctlz.i32(i32, i1)
387 declare i16 @llvm.ctlz.i16(i16, i1)