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:
13 ; CHECK-NEXT: lzcntw %di, %ax
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
22 define i32 @test2_ctlz(i32 %v) {
23 ; CHECK-LABEL: test2_ctlz:
25 ; CHECK-NEXT: lzcntl %edi, %eax
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
34 define i64 @test3_ctlz(i64 %v) {
35 ; CHECK-LABEL: test3_ctlz:
37 ; CHECK-NEXT: lzcntq %rdi, %rax
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
46 define i16 @test4_ctlz(i16 %v) {
47 ; CHECK-LABEL: test4_ctlz:
49 ; CHECK-NEXT: lzcntw %di, %ax
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
58 define i32 @test5_ctlz(i32 %v) {
59 ; CHECK-LABEL: test5_ctlz:
61 ; CHECK-NEXT: lzcntl %edi, %eax
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
70 define i64 @test6_ctlz(i64 %v) {
71 ; CHECK-LABEL: test6_ctlz:
73 ; CHECK-NEXT: lzcntq %rdi, %rax
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
82 define i16 @test10_ctlz(i16* %ptr) {
83 ; CHECK-LABEL: test10_ctlz:
85 ; CHECK-NEXT: lzcntw (%rdi), %ax
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
95 define i32 @test11_ctlz(i32* %ptr) {
96 ; CHECK-LABEL: test11_ctlz:
98 ; CHECK-NEXT: lzcntl (%rdi), %eax
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
108 define i64 @test12_ctlz(i64* %ptr) {
109 ; CHECK-LABEL: test12_ctlz:
111 ; CHECK-NEXT: lzcntq (%rdi), %rax
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
121 define i16 @test13_ctlz(i16* %ptr) {
122 ; CHECK-LABEL: test13_ctlz:
124 ; CHECK-NEXT: lzcntw (%rdi), %ax
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
134 define i32 @test14_ctlz(i32* %ptr) {
135 ; CHECK-LABEL: test14_ctlz:
137 ; CHECK-NEXT: lzcntl (%rdi), %eax
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
147 define i64 @test15_ctlz(i64* %ptr) {
148 ; CHECK-LABEL: test15_ctlz:
150 ; CHECK-NEXT: lzcntq (%rdi), %rax
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
160 define i16 @test1_cttz(i16 %v) {
161 ; CHECK-LABEL: test1_cttz:
163 ; CHECK-NEXT: tzcntw %di, %ax
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
172 define i32 @test2_cttz(i32 %v) {
173 ; CHECK-LABEL: test2_cttz:
175 ; CHECK-NEXT: tzcntl %edi, %eax
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
184 define i64 @test3_cttz(i64 %v) {
185 ; CHECK-LABEL: test3_cttz:
187 ; CHECK-NEXT: tzcntq %rdi, %rax
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
196 define i16 @test4_cttz(i16 %v) {
197 ; CHECK-LABEL: test4_cttz:
199 ; CHECK-NEXT: tzcntw %di, %ax
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
208 define i32 @test5_cttz(i32 %v) {
209 ; CHECK-LABEL: test5_cttz:
211 ; CHECK-NEXT: tzcntl %edi, %eax
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
220 define i64 @test6_cttz(i64 %v) {
221 ; CHECK-LABEL: test6_cttz:
223 ; CHECK-NEXT: tzcntq %rdi, %rax
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
232 define i16 @test10_cttz(i16* %ptr) {
233 ; CHECK-LABEL: test10_cttz:
235 ; CHECK-NEXT: tzcntw (%rdi), %ax
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
245 define i32 @test11_cttz(i32* %ptr) {
246 ; CHECK-LABEL: test11_cttz:
248 ; CHECK-NEXT: tzcntl (%rdi), %eax
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
258 define i64 @test12_cttz(i64* %ptr) {
259 ; CHECK-LABEL: test12_cttz:
261 ; CHECK-NEXT: tzcntq (%rdi), %rax
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
271 define i16 @test13_cttz(i16* %ptr) {
272 ; CHECK-LABEL: test13_cttz:
274 ; CHECK-NEXT: tzcntw (%rdi), %ax
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
284 define i32 @test14_cttz(i32* %ptr) {
285 ; CHECK-LABEL: test14_cttz:
287 ; CHECK-NEXT: tzcntl (%rdi), %eax
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
297 define i64 @test15_cttz(i64* %ptr) {
298 ; CHECK-LABEL: test15_cttz:
300 ; CHECK-NEXT: tzcntq (%rdi), %rax
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
310 define i16 @test4b_ctlz(i16 %v) {
311 ; CHECK-LABEL: test4b_ctlz:
313 ; CHECK-NEXT: lzcntw %di, %ax
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
322 define i32 @test5b_ctlz(i32 %v) {
323 ; CHECK-LABEL: test5b_ctlz:
325 ; CHECK-NEXT: lzcntl %edi, %eax
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
334 define i64 @test6b_ctlz(i64 %v) {
335 ; CHECK-LABEL: test6b_ctlz:
337 ; CHECK-NEXT: lzcntq %rdi, %rax
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
346 define i16 @test4b_cttz(i16 %v) {
347 ; CHECK-LABEL: test4b_cttz:
349 ; CHECK-NEXT: tzcntw %di, %ax
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
358 define i32 @test5b_cttz(i32 %v) {
359 ; CHECK-LABEL: test5b_cttz:
361 ; CHECK-NEXT: tzcntl %edi, %eax
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
370 define i64 @test6b_cttz(i64 %v) {
371 ; CHECK-LABEL: test6b_cttz:
373 ; CHECK-NEXT: tzcntq %rdi, %rax
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
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)