[PowerPC] Recommit r314244 with refactoring and off by default
[llvm-core.git] / test / CodeGen / X86 / lzcnt-tzcnt.ll
blob76e7429ab8da35e7fc972621d557befe842c43f0
1 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+lzcnt | FileCheck %s
3 ; LZCNT and TZCNT will always produce the operand size when the input operand
4 ; is zero. This test is to verify that we efficiently select LZCNT/TZCNT
5 ; based on the fact that the 'icmp+select' sequence is always redundant
6 ; in every function defined below.
9 define i16 @test1_ctlz(i16 %v) {
10   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
11   %tobool = icmp eq i16 %v, 0
12   %cond = select i1 %tobool, i16 16, i16 %cnt
13   ret i16 %cond
15 ; CHECK-LABEL: test1_ctlz
16 ; CHECK: lzcnt
17 ; CHECK-NEXT: ret
20 define i32 @test2_ctlz(i32 %v) {
21   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
22   %tobool = icmp eq i32 %v, 0
23   %cond = select i1 %tobool, i32 32, i32 %cnt
24   ret i32 %cond
26 ; CHECK-LABEL: test2_ctlz
27 ; CHECK: lzcnt
28 ; CHECK-NEXT: ret
31 define i64 @test3_ctlz(i64 %v) {
32   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
33   %tobool = icmp eq i64 %v, 0
34   %cond = select i1 %tobool, i64 64, i64 %cnt
35   ret i64 %cond
37 ; CHECK-LABEL: test3_ctlz
38 ; CHECK: lzcnt
39 ; CHECK-NEXT: ret
42 define i16 @test4_ctlz(i16 %v) {
43   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
44   %tobool = icmp eq i16 0, %v
45   %cond = select i1 %tobool, i16 16, i16 %cnt
46   ret i16 %cond
48 ; CHECK-LABEL: test4_ctlz
49 ; CHECK: lzcnt
50 ; CHECK-NEXT: ret
53 define i32 @test5_ctlz(i32 %v) {
54   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
55   %tobool = icmp eq i32 0, %v
56   %cond = select i1 %tobool, i32 32, i32 %cnt
57   ret i32 %cond
59 ; CHECK-LABEL: test5_ctlz
60 ; CHECK: lzcnt
61 ; CHECK-NEXT: ret
64 define i64 @test6_ctlz(i64 %v) {
65   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
66   %tobool = icmp eq i64 0, %v
67   %cond = select i1 %tobool, i64 64, i64 %cnt
68   ret i64 %cond
70 ; CHECK-LABEL: test6_ctlz
71 ; CHECK: lzcnt
72 ; CHECK-NEXT: ret
75 define i16 @test10_ctlz(i16* %ptr) {
76   %v = load i16, i16* %ptr
77   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
78   %tobool = icmp eq i16 %v, 0
79   %cond = select i1 %tobool, i16 16, i16 %cnt
80   ret i16 %cond
82 ; CHECK-LABEL: test10_ctlz
83 ; CHECK-NOT: movw
84 ; CHECK: lzcnt
85 ; CHECK-NEXT: ret
88 define i32 @test11_ctlz(i32* %ptr) {
89   %v = load i32, i32* %ptr
90   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
91   %tobool = icmp eq i32 %v, 0
92   %cond = select i1 %tobool, i32 32, i32 %cnt
93   ret i32 %cond
95 ; CHECK-LABEL: test11_ctlz
96 ; CHECK-NOT: movd
97 ; CHECK: lzcnt
98 ; CHECK-NEXT: ret
101 define i64 @test12_ctlz(i64* %ptr) {
102   %v = load i64, i64* %ptr
103   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
104   %tobool = icmp eq i64 %v, 0
105   %cond = select i1 %tobool, i64 64, i64 %cnt
106   ret i64 %cond
108 ; CHECK-LABEL: test12_ctlz
109 ; CHECK-NOT: movq
110 ; CHECK: lzcnt
111 ; CHECK-NEXT: ret
114 define i16 @test13_ctlz(i16* %ptr) {
115   %v = load i16, i16* %ptr
116   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
117   %tobool = icmp eq i16 0, %v
118   %cond = select i1 %tobool, i16 16, i16 %cnt
119   ret i16 %cond
121 ; CHECK-LABEL: test13_ctlz
122 ; CHECK-NOT: movw
123 ; CHECK: lzcnt
124 ; CHECK-NEXT: ret
127 define i32 @test14_ctlz(i32* %ptr) {
128   %v = load i32, i32* %ptr
129   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
130   %tobool = icmp eq i32 0, %v
131   %cond = select i1 %tobool, i32 32, i32 %cnt
132   ret i32 %cond
134 ; CHECK-LABEL: test14_ctlz
135 ; CHECK-NOT: movd
136 ; CHECK: lzcnt
137 ; CHECK-NEXT: ret
140 define i64 @test15_ctlz(i64* %ptr) {
141   %v = load i64, i64* %ptr
142   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
143   %tobool = icmp eq i64 0, %v
144   %cond = select i1 %tobool, i64 64, i64 %cnt
145   ret i64 %cond
147 ; CHECK-LABEL: test15_ctlz
148 ; CHECK-NOT: movq
149 ; CHECK: lzcnt
150 ; CHECK-NEXT: ret
153 define i16 @test1_cttz(i16 %v) {
154   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
155   %tobool = icmp eq i16 %v, 0
156   %cond = select i1 %tobool, i16 16, i16 %cnt
157   ret i16 %cond
159 ; CHECK-LABEL: test1_cttz
160 ; CHECK: tzcnt
161 ; CHECK-NEXT: ret
164 define i32 @test2_cttz(i32 %v) {
165   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
166   %tobool = icmp eq i32 %v, 0
167   %cond = select i1 %tobool, i32 32, i32 %cnt
168   ret i32 %cond
170 ; CHECK-LABEL: test2_cttz
171 ; CHECK: tzcnt
172 ; CHECK-NEXT: ret
175 define i64 @test3_cttz(i64 %v) {
176   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
177   %tobool = icmp eq i64 %v, 0
178   %cond = select i1 %tobool, i64 64, i64 %cnt
179   ret i64 %cond
181 ; CHECK-LABEL: test3_cttz
182 ; CHECK: tzcnt
183 ; CHECK-NEXT: ret
186 define i16 @test4_cttz(i16 %v) {
187   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
188   %tobool = icmp eq i16 0, %v
189   %cond = select i1 %tobool, i16 16, i16 %cnt
190   ret i16 %cond
192 ; CHECK-LABEL: test4_cttz
193 ; CHECK: tzcnt
194 ; CHECK-NEXT: ret
197 define i32 @test5_cttz(i32 %v) {
198   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
199   %tobool = icmp eq i32 0, %v
200   %cond = select i1 %tobool, i32 32, i32 %cnt
201   ret i32 %cond
203 ; CHECK-LABEL: test5_cttz
204 ; CHECK: tzcnt
205 ; CHECK-NEXT: ret
208 define i64 @test6_cttz(i64 %v) {
209   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
210   %tobool = icmp eq i64 0, %v
211   %cond = select i1 %tobool, i64 64, i64 %cnt
212   ret i64 %cond
214 ; CHECK-LABEL: test6_cttz
215 ; CHECK: tzcnt
216 ; CHECK-NEXT: ret
219 define i16 @test10_cttz(i16* %ptr) {
220   %v = load i16, i16* %ptr
221   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
222   %tobool = icmp eq i16 %v, 0
223   %cond = select i1 %tobool, i16 16, i16 %cnt
224   ret i16 %cond
226 ; CHECK-LABEL: test10_cttz
227 ; CHECK-NOT: movw
228 ; CHECK: tzcnt
229 ; CHECK-NEXT: ret
232 define i32 @test11_cttz(i32* %ptr) {
233   %v = load i32, i32* %ptr
234   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
235   %tobool = icmp eq i32 %v, 0
236   %cond = select i1 %tobool, i32 32, i32 %cnt
237   ret i32 %cond
239 ; CHECK-LABEL: test11_cttz
240 ; CHECK-NOT: movd
241 ; CHECK: tzcnt
242 ; CHECK-NEXT: ret
245 define i64 @test12_cttz(i64* %ptr) {
246   %v = load i64, i64* %ptr
247   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
248   %tobool = icmp eq i64 %v, 0
249   %cond = select i1 %tobool, i64 64, i64 %cnt
250   ret i64 %cond
252 ; CHECK-LABEL: test12_cttz
253 ; CHECK-NOT: movq
254 ; CHECK: tzcnt
255 ; CHECK-NEXT: ret
258 define i16 @test13_cttz(i16* %ptr) {
259   %v = load i16, i16* %ptr
260   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
261   %tobool = icmp eq i16 0, %v
262   %cond = select i1 %tobool, i16 16, i16 %cnt
263   ret i16 %cond
265 ; CHECK-LABEL: test13_cttz
266 ; CHECK-NOT: movw
267 ; CHECK: tzcnt
268 ; CHECK-NEXT: ret
271 define i32 @test14_cttz(i32* %ptr) {
272   %v = load i32, i32* %ptr
273   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
274   %tobool = icmp eq i32 0, %v
275   %cond = select i1 %tobool, i32 32, i32 %cnt
276   ret i32 %cond
278 ; CHECK-LABEL: test14_cttz
279 ; CHECK-NOT: movd
280 ; CHECK: tzcnt
281 ; CHECK-NEXT: ret
284 define i64 @test15_cttz(i64* %ptr) {
285   %v = load i64, i64* %ptr
286   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
287   %tobool = icmp eq i64 0, %v
288   %cond = select i1 %tobool, i64 64, i64 %cnt
289   ret i64 %cond
291 ; CHECK-LABEL: test15_cttz
292 ; CHECK-NOT: movq
293 ; CHECK: tzcnt
294 ; CHECK-NEXT: ret
297 define i16 @test4b_ctlz(i16 %v) {
298   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
299   %tobool = icmp ne i16 %v, 0
300   %cond = select i1 %tobool, i16 %cnt, i16 16
301   ret i16 %cond
303 ; CHECK-LABEL: test4b_ctlz
304 ; CHECK: lzcnt
305 ; CHECK-NEXT: ret
308 define i32 @test5b_ctlz(i32 %v) {
309   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
310   %tobool = icmp ne i32 %v, 0
311   %cond = select i1 %tobool, i32 %cnt, i32 32
312   ret i32 %cond
314 ; CHECK-LABEL: test5b_ctlz
315 ; CHECK: lzcnt
316 ; CHECK-NEXT: ret
319 define i64 @test6b_ctlz(i64 %v) {
320   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
321   %tobool = icmp ne i64 %v, 0
322   %cond = select i1 %tobool, i64 %cnt, i64 64
323   ret i64 %cond
325 ; CHECK-LABEL: test6b_ctlz
326 ; CHECK: lzcnt
327 ; CHECK-NEXT: ret
330 define i16 @test4b_cttz(i16 %v) {
331   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
332   %tobool = icmp ne i16 %v, 0
333   %cond = select i1 %tobool, i16 %cnt, i16 16
334   ret i16 %cond
336 ; CHECK-LABEL: test4b_cttz
337 ; CHECK: tzcnt
338 ; CHECK-NEXT: ret
341 define i32 @test5b_cttz(i32 %v) {
342   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
343   %tobool = icmp ne i32 %v, 0
344   %cond = select i1 %tobool, i32 %cnt, i32 32
345   ret i32 %cond
347 ; CHECK-LABEL: test5b_cttz
348 ; CHECK: tzcnt
349 ; CHECK-NEXT: ret
352 define i64 @test6b_cttz(i64 %v) {
353   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
354   %tobool = icmp ne i64 %v, 0
355   %cond = select i1 %tobool, i64 %cnt, i64 64
356   ret i64 %cond
358 ; CHECK-LABEL: test6b_cttz
359 ; CHECK: tzcnt
360 ; CHECK-NEXT: ret
363 declare i64 @llvm.cttz.i64(i64, i1)
364 declare i32 @llvm.cttz.i32(i32, i1)
365 declare i16 @llvm.cttz.i16(i16, i1)
366 declare i64 @llvm.ctlz.i64(i64, i1)
367 declare i32 @llvm.ctlz.i32(i32, i1)
368 declare i16 @llvm.ctlz.i16(i16, i1)