Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / ctlz.ll
blob87dca62d74168796e155ed59c97d5a91e01ce5a4
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86,X86-NOCMOV
3 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=X86,X86-CMOV
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
5 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86-CLZ
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64-CLZ
7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X64-FASTLZCNT
8 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X86-FASTLZCNT
10 declare i8 @llvm.ctlz.i8(i8, i1)
11 declare i16 @llvm.ctlz.i16(i16, i1)
12 declare i32 @llvm.ctlz.i32(i32, i1)
13 declare i64 @llvm.ctlz.i64(i64, i1)
15 define i8 @ctlz_i8(i8 %x) {
16 ; X86-LABEL: ctlz_i8:
17 ; X86:       # %bb.0:
18 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
19 ; X86-NEXT:    bsrl %eax, %eax
20 ; X86-NEXT:    xorl $7, %eax
21 ; X86-NEXT:    # kill: def $al killed $al killed $eax
22 ; X86-NEXT:    retl
24 ; X64-LABEL: ctlz_i8:
25 ; X64:       # %bb.0:
26 ; X64-NEXT:    movzbl %dil, %eax
27 ; X64-NEXT:    bsrl %eax, %eax
28 ; X64-NEXT:    xorl $7, %eax
29 ; X64-NEXT:    # kill: def $al killed $al killed $eax
30 ; X64-NEXT:    retq
32 ; X86-CLZ-LABEL: ctlz_i8:
33 ; X86-CLZ:       # %bb.0:
34 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
35 ; X86-CLZ-NEXT:    shll $24, %eax
36 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
37 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
38 ; X86-CLZ-NEXT:    retl
40 ; X64-CLZ-LABEL: ctlz_i8:
41 ; X64-CLZ:       # %bb.0:
42 ; X64-CLZ-NEXT:    shll $24, %edi
43 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
44 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
45 ; X64-CLZ-NEXT:    retq
47 ; X64-FASTLZCNT-LABEL: ctlz_i8:
48 ; X64-FASTLZCNT:       # %bb.0:
49 ; X64-FASTLZCNT-NEXT:    shll $24, %edi
50 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
51 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
52 ; X64-FASTLZCNT-NEXT:    retq
54 ; X86-FASTLZCNT-LABEL: ctlz_i8:
55 ; X86-FASTLZCNT:       # %bb.0:
56 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
57 ; X86-FASTLZCNT-NEXT:    shll $24, %eax
58 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
59 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
60 ; X86-FASTLZCNT-NEXT:    retl
61   %tmp2 = call i8 @llvm.ctlz.i8( i8 %x, i1 true )
62   ret i8 %tmp2
65 define i16 @ctlz_i16(i16 %x) {
66 ; X86-LABEL: ctlz_i16:
67 ; X86:       # %bb.0:
68 ; X86-NEXT:    bsrw {{[0-9]+}}(%esp), %ax
69 ; X86-NEXT:    xorl $15, %eax
70 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
71 ; X86-NEXT:    retl
73 ; X64-LABEL: ctlz_i16:
74 ; X64:       # %bb.0:
75 ; X64-NEXT:    bsrw %di, %ax
76 ; X64-NEXT:    xorl $15, %eax
77 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
78 ; X64-NEXT:    retq
80 ; X86-CLZ-LABEL: ctlz_i16:
81 ; X86-CLZ:       # %bb.0:
82 ; X86-CLZ-NEXT:    lzcntw {{[0-9]+}}(%esp), %ax
83 ; X86-CLZ-NEXT:    retl
85 ; X64-CLZ-LABEL: ctlz_i16:
86 ; X64-CLZ:       # %bb.0:
87 ; X64-CLZ-NEXT:    lzcntw %di, %ax
88 ; X64-CLZ-NEXT:    retq
90 ; X64-FASTLZCNT-LABEL: ctlz_i16:
91 ; X64-FASTLZCNT:       # %bb.0:
92 ; X64-FASTLZCNT-NEXT:    lzcntw %di, %ax
93 ; X64-FASTLZCNT-NEXT:    retq
95 ; X86-FASTLZCNT-LABEL: ctlz_i16:
96 ; X86-FASTLZCNT:       # %bb.0:
97 ; X86-FASTLZCNT-NEXT:    lzcntw {{[0-9]+}}(%esp), %ax
98 ; X86-FASTLZCNT-NEXT:    retl
99   %tmp2 = call i16 @llvm.ctlz.i16( i16 %x, i1 true )
100   ret i16 %tmp2
103 define i32 @ctlz_i32(i32 %x) {
104 ; X86-LABEL: ctlz_i32:
105 ; X86:       # %bb.0:
106 ; X86-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
107 ; X86-NEXT:    xorl $31, %eax
108 ; X86-NEXT:    retl
110 ; X64-LABEL: ctlz_i32:
111 ; X64:       # %bb.0:
112 ; X64-NEXT:    bsrl %edi, %eax
113 ; X64-NEXT:    xorl $31, %eax
114 ; X64-NEXT:    retq
116 ; X86-CLZ-LABEL: ctlz_i32:
117 ; X86-CLZ:       # %bb.0:
118 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
119 ; X86-CLZ-NEXT:    retl
121 ; X64-CLZ-LABEL: ctlz_i32:
122 ; X64-CLZ:       # %bb.0:
123 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
124 ; X64-CLZ-NEXT:    retq
126 ; X64-FASTLZCNT-LABEL: ctlz_i32:
127 ; X64-FASTLZCNT:       # %bb.0:
128 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
129 ; X64-FASTLZCNT-NEXT:    retq
131 ; X86-FASTLZCNT-LABEL: ctlz_i32:
132 ; X86-FASTLZCNT:       # %bb.0:
133 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
134 ; X86-FASTLZCNT-NEXT:    retl
135   %tmp = call i32 @llvm.ctlz.i32( i32 %x, i1 true )
136   ret i32 %tmp
139 define i64 @ctlz_i64(i64 %x) {
140 ; X86-NOCMOV-LABEL: ctlz_i64:
141 ; X86-NOCMOV:       # %bb.0:
142 ; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
143 ; X86-NOCMOV-NEXT:    testl %eax, %eax
144 ; X86-NOCMOV-NEXT:    jne .LBB3_1
145 ; X86-NOCMOV-NEXT:  # %bb.2:
146 ; X86-NOCMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
147 ; X86-NOCMOV-NEXT:    xorl $31, %eax
148 ; X86-NOCMOV-NEXT:    addl $32, %eax
149 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
150 ; X86-NOCMOV-NEXT:    retl
151 ; X86-NOCMOV-NEXT:  .LBB3_1:
152 ; X86-NOCMOV-NEXT:    bsrl %eax, %eax
153 ; X86-NOCMOV-NEXT:    xorl $31, %eax
154 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
155 ; X86-NOCMOV-NEXT:    retl
157 ; X86-CMOV-LABEL: ctlz_i64:
158 ; X86-CMOV:       # %bb.0:
159 ; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
160 ; X86-CMOV-NEXT:    bsrl %ecx, %edx
161 ; X86-CMOV-NEXT:    xorl $31, %edx
162 ; X86-CMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
163 ; X86-CMOV-NEXT:    xorl $31, %eax
164 ; X86-CMOV-NEXT:    addl $32, %eax
165 ; X86-CMOV-NEXT:    testl %ecx, %ecx
166 ; X86-CMOV-NEXT:    cmovnel %edx, %eax
167 ; X86-CMOV-NEXT:    xorl %edx, %edx
168 ; X86-CMOV-NEXT:    retl
170 ; X64-LABEL: ctlz_i64:
171 ; X64:       # %bb.0:
172 ; X64-NEXT:    bsrq %rdi, %rax
173 ; X64-NEXT:    xorq $63, %rax
174 ; X64-NEXT:    retq
176 ; X86-CLZ-LABEL: ctlz_i64:
177 ; X86-CLZ:       # %bb.0:
178 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
179 ; X86-CLZ-NEXT:    testl %eax, %eax
180 ; X86-CLZ-NEXT:    jne .LBB3_1
181 ; X86-CLZ-NEXT:  # %bb.2:
182 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
183 ; X86-CLZ-NEXT:    addl $32, %eax
184 ; X86-CLZ-NEXT:    xorl %edx, %edx
185 ; X86-CLZ-NEXT:    retl
186 ; X86-CLZ-NEXT:  .LBB3_1:
187 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
188 ; X86-CLZ-NEXT:    xorl %edx, %edx
189 ; X86-CLZ-NEXT:    retl
191 ; X64-CLZ-LABEL: ctlz_i64:
192 ; X64-CLZ:       # %bb.0:
193 ; X64-CLZ-NEXT:    lzcntq %rdi, %rax
194 ; X64-CLZ-NEXT:    retq
196 ; X64-FASTLZCNT-LABEL: ctlz_i64:
197 ; X64-FASTLZCNT:       # %bb.0:
198 ; X64-FASTLZCNT-NEXT:    lzcntq %rdi, %rax
199 ; X64-FASTLZCNT-NEXT:    retq
201 ; X86-FASTLZCNT-LABEL: ctlz_i64:
202 ; X86-FASTLZCNT:       # %bb.0:
203 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
204 ; X86-FASTLZCNT-NEXT:    testl %eax, %eax
205 ; X86-FASTLZCNT-NEXT:    jne .LBB3_1
206 ; X86-FASTLZCNT-NEXT:  # %bb.2:
207 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
208 ; X86-FASTLZCNT-NEXT:    addl $32, %eax
209 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
210 ; X86-FASTLZCNT-NEXT:    retl
211 ; X86-FASTLZCNT-NEXT:  .LBB3_1:
212 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
213 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
214 ; X86-FASTLZCNT-NEXT:    retl
215   %tmp = call i64 @llvm.ctlz.i64( i64 %x, i1 true )
216   ret i64 %tmp
219 ; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.
220 define i8 @ctlz_i8_zero_test(i8 %n) {
221 ; X86-LABEL: ctlz_i8_zero_test:
222 ; X86:       # %bb.0:
223 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
224 ; X86-NEXT:    testb %al, %al
225 ; X86-NEXT:    je .LBB4_1
226 ; X86-NEXT:  # %bb.2: # %cond.false
227 ; X86-NEXT:    movzbl %al, %eax
228 ; X86-NEXT:    bsrl %eax, %eax
229 ; X86-NEXT:    xorl $7, %eax
230 ; X86-NEXT:    # kill: def $al killed $al killed $eax
231 ; X86-NEXT:    retl
232 ; X86-NEXT:  .LBB4_1:
233 ; X86-NEXT:    movb $8, %al
234 ; X86-NEXT:    # kill: def $al killed $al killed $eax
235 ; X86-NEXT:    retl
237 ; X64-LABEL: ctlz_i8_zero_test:
238 ; X64:       # %bb.0:
239 ; X64-NEXT:    testb %dil, %dil
240 ; X64-NEXT:    je .LBB4_1
241 ; X64-NEXT:  # %bb.2: # %cond.false
242 ; X64-NEXT:    movzbl %dil, %eax
243 ; X64-NEXT:    bsrl %eax, %eax
244 ; X64-NEXT:    xorl $7, %eax
245 ; X64-NEXT:    # kill: def $al killed $al killed $eax
246 ; X64-NEXT:    retq
247 ; X64-NEXT:  .LBB4_1:
248 ; X64-NEXT:    movb $8, %al
249 ; X64-NEXT:    # kill: def $al killed $al killed $eax
250 ; X64-NEXT:    retq
252 ; X86-CLZ-LABEL: ctlz_i8_zero_test:
253 ; X86-CLZ:       # %bb.0:
254 ; X86-CLZ-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
255 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
256 ; X86-CLZ-NEXT:    addl $-24, %eax
257 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
258 ; X86-CLZ-NEXT:    retl
260 ; X64-CLZ-LABEL: ctlz_i8_zero_test:
261 ; X64-CLZ:       # %bb.0:
262 ; X64-CLZ-NEXT:    movzbl %dil, %eax
263 ; X64-CLZ-NEXT:    lzcntl %eax, %eax
264 ; X64-CLZ-NEXT:    addl $-24, %eax
265 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
266 ; X64-CLZ-NEXT:    retq
268 ; X64-FASTLZCNT-LABEL: ctlz_i8_zero_test:
269 ; X64-FASTLZCNT:       # %bb.0:
270 ; X64-FASTLZCNT-NEXT:    movzbl %dil, %eax
271 ; X64-FASTLZCNT-NEXT:    lzcntl %eax, %eax
272 ; X64-FASTLZCNT-NEXT:    addl $-24, %eax
273 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
274 ; X64-FASTLZCNT-NEXT:    retq
276 ; X86-FASTLZCNT-LABEL: ctlz_i8_zero_test:
277 ; X86-FASTLZCNT:       # %bb.0:
278 ; X86-FASTLZCNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
279 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
280 ; X86-FASTLZCNT-NEXT:    addl $-24, %eax
281 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
282 ; X86-FASTLZCNT-NEXT:    retl
283   %tmp1 = call i8 @llvm.ctlz.i8(i8 %n, i1 false)
284   ret i8 %tmp1
287 ; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.
288 define i16 @ctlz_i16_zero_test(i16 %n) {
289 ; X86-LABEL: ctlz_i16_zero_test:
290 ; X86:       # %bb.0:
291 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
292 ; X86-NEXT:    testw %ax, %ax
293 ; X86-NEXT:    je .LBB5_1
294 ; X86-NEXT:  # %bb.2: # %cond.false
295 ; X86-NEXT:    bsrw %ax, %ax
296 ; X86-NEXT:    xorl $15, %eax
297 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
298 ; X86-NEXT:    retl
299 ; X86-NEXT:  .LBB5_1:
300 ; X86-NEXT:    movw $16, %ax
301 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
302 ; X86-NEXT:    retl
304 ; X64-LABEL: ctlz_i16_zero_test:
305 ; X64:       # %bb.0:
306 ; X64-NEXT:    testw %di, %di
307 ; X64-NEXT:    je .LBB5_1
308 ; X64-NEXT:  # %bb.2: # %cond.false
309 ; X64-NEXT:    bsrw %di, %ax
310 ; X64-NEXT:    xorl $15, %eax
311 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
312 ; X64-NEXT:    retq
313 ; X64-NEXT:  .LBB5_1:
314 ; X64-NEXT:    movw $16, %ax
315 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
316 ; X64-NEXT:    retq
318 ; X86-CLZ-LABEL: ctlz_i16_zero_test:
319 ; X86-CLZ:       # %bb.0:
320 ; X86-CLZ-NEXT:    lzcntw {{[0-9]+}}(%esp), %ax
321 ; X86-CLZ-NEXT:    retl
323 ; X64-CLZ-LABEL: ctlz_i16_zero_test:
324 ; X64-CLZ:       # %bb.0:
325 ; X64-CLZ-NEXT:    lzcntw %di, %ax
326 ; X64-CLZ-NEXT:    retq
328 ; X64-FASTLZCNT-LABEL: ctlz_i16_zero_test:
329 ; X64-FASTLZCNT:       # %bb.0:
330 ; X64-FASTLZCNT-NEXT:    lzcntw %di, %ax
331 ; X64-FASTLZCNT-NEXT:    retq
333 ; X86-FASTLZCNT-LABEL: ctlz_i16_zero_test:
334 ; X86-FASTLZCNT:       # %bb.0:
335 ; X86-FASTLZCNT-NEXT:    lzcntw {{[0-9]+}}(%esp), %ax
336 ; X86-FASTLZCNT-NEXT:    retl
337   %tmp1 = call i16 @llvm.ctlz.i16(i16 %n, i1 false)
338   ret i16 %tmp1
341 ; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.
342 define i32 @ctlz_i32_zero_test(i32 %n) {
343 ; X86-LABEL: ctlz_i32_zero_test:
344 ; X86:       # %bb.0:
345 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
346 ; X86-NEXT:    testl %eax, %eax
347 ; X86-NEXT:    je .LBB6_1
348 ; X86-NEXT:  # %bb.2: # %cond.false
349 ; X86-NEXT:    bsrl %eax, %eax
350 ; X86-NEXT:    xorl $31, %eax
351 ; X86-NEXT:    retl
352 ; X86-NEXT:  .LBB6_1:
353 ; X86-NEXT:    movl $32, %eax
354 ; X86-NEXT:    retl
356 ; X64-LABEL: ctlz_i32_zero_test:
357 ; X64:       # %bb.0:
358 ; X64-NEXT:    testl %edi, %edi
359 ; X64-NEXT:    je .LBB6_1
360 ; X64-NEXT:  # %bb.2: # %cond.false
361 ; X64-NEXT:    bsrl %edi, %eax
362 ; X64-NEXT:    xorl $31, %eax
363 ; X64-NEXT:    retq
364 ; X64-NEXT:  .LBB6_1:
365 ; X64-NEXT:    movl $32, %eax
366 ; X64-NEXT:    retq
368 ; X86-CLZ-LABEL: ctlz_i32_zero_test:
369 ; X86-CLZ:       # %bb.0:
370 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
371 ; X86-CLZ-NEXT:    retl
373 ; X64-CLZ-LABEL: ctlz_i32_zero_test:
374 ; X64-CLZ:       # %bb.0:
375 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
376 ; X64-CLZ-NEXT:    retq
378 ; X64-FASTLZCNT-LABEL: ctlz_i32_zero_test:
379 ; X64-FASTLZCNT:       # %bb.0:
380 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
381 ; X64-FASTLZCNT-NEXT:    retq
383 ; X86-FASTLZCNT-LABEL: ctlz_i32_zero_test:
384 ; X86-FASTLZCNT:       # %bb.0:
385 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
386 ; X86-FASTLZCNT-NEXT:    retl
387   %tmp1 = call i32 @llvm.ctlz.i32(i32 %n, i1 false)
388   ret i32 %tmp1
391 ; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.
392 define i64 @ctlz_i64_zero_test(i64 %n) {
393 ; X86-NOCMOV-LABEL: ctlz_i64_zero_test:
394 ; X86-NOCMOV:       # %bb.0:
395 ; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
396 ; X86-NOCMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %edx
397 ; X86-NOCMOV-NEXT:    movl $63, %eax
398 ; X86-NOCMOV-NEXT:    je .LBB7_2
399 ; X86-NOCMOV-NEXT:  # %bb.1:
400 ; X86-NOCMOV-NEXT:    movl %edx, %eax
401 ; X86-NOCMOV-NEXT:  .LBB7_2:
402 ; X86-NOCMOV-NEXT:    testl %ecx, %ecx
403 ; X86-NOCMOV-NEXT:    jne .LBB7_3
404 ; X86-NOCMOV-NEXT:  # %bb.4:
405 ; X86-NOCMOV-NEXT:    xorl $31, %eax
406 ; X86-NOCMOV-NEXT:    addl $32, %eax
407 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
408 ; X86-NOCMOV-NEXT:    retl
409 ; X86-NOCMOV-NEXT:  .LBB7_3:
410 ; X86-NOCMOV-NEXT:    bsrl %ecx, %eax
411 ; X86-NOCMOV-NEXT:    xorl $31, %eax
412 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
413 ; X86-NOCMOV-NEXT:    retl
415 ; X86-CMOV-LABEL: ctlz_i64_zero_test:
416 ; X86-CMOV:       # %bb.0:
417 ; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
418 ; X86-CMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
419 ; X86-CMOV-NEXT:    movl $63, %edx
420 ; X86-CMOV-NEXT:    cmovnel %eax, %edx
421 ; X86-CMOV-NEXT:    xorl $31, %edx
422 ; X86-CMOV-NEXT:    addl $32, %edx
423 ; X86-CMOV-NEXT:    bsrl %ecx, %eax
424 ; X86-CMOV-NEXT:    xorl $31, %eax
425 ; X86-CMOV-NEXT:    testl %ecx, %ecx
426 ; X86-CMOV-NEXT:    cmovel %edx, %eax
427 ; X86-CMOV-NEXT:    xorl %edx, %edx
428 ; X86-CMOV-NEXT:    retl
430 ; X64-LABEL: ctlz_i64_zero_test:
431 ; X64:       # %bb.0:
432 ; X64-NEXT:    testq %rdi, %rdi
433 ; X64-NEXT:    je .LBB7_1
434 ; X64-NEXT:  # %bb.2: # %cond.false
435 ; X64-NEXT:    bsrq %rdi, %rax
436 ; X64-NEXT:    xorq $63, %rax
437 ; X64-NEXT:    retq
438 ; X64-NEXT:  .LBB7_1:
439 ; X64-NEXT:    movl $64, %eax
440 ; X64-NEXT:    retq
442 ; X86-CLZ-LABEL: ctlz_i64_zero_test:
443 ; X86-CLZ:       # %bb.0:
444 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
445 ; X86-CLZ-NEXT:    testl %eax, %eax
446 ; X86-CLZ-NEXT:    jne .LBB7_1
447 ; X86-CLZ-NEXT:  # %bb.2:
448 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
449 ; X86-CLZ-NEXT:    addl $32, %eax
450 ; X86-CLZ-NEXT:    xorl %edx, %edx
451 ; X86-CLZ-NEXT:    retl
452 ; X86-CLZ-NEXT:  .LBB7_1:
453 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
454 ; X86-CLZ-NEXT:    xorl %edx, %edx
455 ; X86-CLZ-NEXT:    retl
457 ; X64-CLZ-LABEL: ctlz_i64_zero_test:
458 ; X64-CLZ:       # %bb.0:
459 ; X64-CLZ-NEXT:    lzcntq %rdi, %rax
460 ; X64-CLZ-NEXT:    retq
462 ; X64-FASTLZCNT-LABEL: ctlz_i64_zero_test:
463 ; X64-FASTLZCNT:       # %bb.0:
464 ; X64-FASTLZCNT-NEXT:    lzcntq %rdi, %rax
465 ; X64-FASTLZCNT-NEXT:    retq
467 ; X86-FASTLZCNT-LABEL: ctlz_i64_zero_test:
468 ; X86-FASTLZCNT:       # %bb.0:
469 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
470 ; X86-FASTLZCNT-NEXT:    testl %eax, %eax
471 ; X86-FASTLZCNT-NEXT:    jne .LBB7_1
472 ; X86-FASTLZCNT-NEXT:  # %bb.2:
473 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
474 ; X86-FASTLZCNT-NEXT:    addl $32, %eax
475 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
476 ; X86-FASTLZCNT-NEXT:    retl
477 ; X86-FASTLZCNT-NEXT:  .LBB7_1:
478 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
479 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
480 ; X86-FASTLZCNT-NEXT:    retl
481   %tmp1 = call i64 @llvm.ctlz.i64(i64 %n, i1 false)
482   ret i64 %tmp1
485 ; Don't generate the cmovne when the source is known non-zero (and bsr would
486 ; not set ZF).
487 ; rdar://9490949
488 define i32 @ctlz_i32_fold_cmov(i32 %n) {
489 ; X86-LABEL: ctlz_i32_fold_cmov:
490 ; X86:       # %bb.0:
491 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
492 ; X86-NEXT:    orl $1, %eax
493 ; X86-NEXT:    bsrl %eax, %eax
494 ; X86-NEXT:    xorl $31, %eax
495 ; X86-NEXT:    retl
497 ; X64-LABEL: ctlz_i32_fold_cmov:
498 ; X64:       # %bb.0:
499 ; X64-NEXT:    orl $1, %edi
500 ; X64-NEXT:    bsrl %edi, %eax
501 ; X64-NEXT:    xorl $31, %eax
502 ; X64-NEXT:    retq
504 ; X86-CLZ-LABEL: ctlz_i32_fold_cmov:
505 ; X86-CLZ:       # %bb.0:
506 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
507 ; X86-CLZ-NEXT:    orl $1, %eax
508 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
509 ; X86-CLZ-NEXT:    retl
511 ; X64-CLZ-LABEL: ctlz_i32_fold_cmov:
512 ; X64-CLZ:       # %bb.0:
513 ; X64-CLZ-NEXT:    orl $1, %edi
514 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
515 ; X64-CLZ-NEXT:    retq
517 ; X64-FASTLZCNT-LABEL: ctlz_i32_fold_cmov:
518 ; X64-FASTLZCNT:       # %bb.0:
519 ; X64-FASTLZCNT-NEXT:    orl $1, %edi
520 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
521 ; X64-FASTLZCNT-NEXT:    retq
523 ; X86-FASTLZCNT-LABEL: ctlz_i32_fold_cmov:
524 ; X86-FASTLZCNT:       # %bb.0:
525 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
526 ; X86-FASTLZCNT-NEXT:    orl $1, %eax
527 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
528 ; X86-FASTLZCNT-NEXT:    retl
529   %or = or i32 %n, 1
530   %tmp1 = call i32 @llvm.ctlz.i32(i32 %or, i1 false)
531   ret i32 %tmp1
534 ; Don't generate any xors when a 'ctlz' intrinsic is actually used to compute
535 ; the most significant bit, which is what 'bsr' does natively.
536 ; NOTE: We intentionally don't select `bsr` when `fast-lzcnt` is
537 ; available. This is 1) because `bsr` has some drawbacks including a
538 ; dependency on dst, 2) very poor performance on some of the
539 ; `fast-lzcnt` processors, and 3) `lzcnt` runs at ALU latency/throughput
540 ; so `lzcnt` + `xor` has better throughput than even the 1-uop
541 ; (1c latency, 1c throughput) `bsr`.
542 define i32 @ctlz_bsr(i32 %n) {
543 ; X86-LABEL: ctlz_bsr:
544 ; X86:       # %bb.0:
545 ; X86-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
546 ; X86-NEXT:    retl
548 ; X64-LABEL: ctlz_bsr:
549 ; X64:       # %bb.0:
550 ; X64-NEXT:    bsrl %edi, %eax
551 ; X64-NEXT:    retq
553 ; X86-CLZ-LABEL: ctlz_bsr:
554 ; X86-CLZ:       # %bb.0:
555 ; X86-CLZ-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
556 ; X86-CLZ-NEXT:    retl
558 ; X64-CLZ-LABEL: ctlz_bsr:
559 ; X64-CLZ:       # %bb.0:
560 ; X64-CLZ-NEXT:    bsrl %edi, %eax
561 ; X64-CLZ-NEXT:    retq
563 ; X64-FASTLZCNT-LABEL: ctlz_bsr:
564 ; X64-FASTLZCNT:       # %bb.0:
565 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
566 ; X64-FASTLZCNT-NEXT:    xorl $31, %eax
567 ; X64-FASTLZCNT-NEXT:    retq
569 ; X86-FASTLZCNT-LABEL: ctlz_bsr:
570 ; X86-FASTLZCNT:       # %bb.0:
571 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
572 ; X86-FASTLZCNT-NEXT:    xorl $31, %eax
573 ; X86-FASTLZCNT-NEXT:    retl
574   %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 true)
575   %bsr = xor i32 %ctlz, 31
576   ret i32 %bsr
579 ; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.
580 ; FIXME: The compare and branch are produced late in IR (by CodeGenPrepare), and
581 ;        codegen doesn't know how to combine the $32 and $31 into $63.
582 define i32 @ctlz_bsr_zero_test(i32 %n) {
583 ; X86-LABEL: ctlz_bsr_zero_test:
584 ; X86:       # %bb.0:
585 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
586 ; X86-NEXT:    testl %eax, %eax
587 ; X86-NEXT:    je .LBB10_1
588 ; X86-NEXT:  # %bb.2: # %cond.false
589 ; X86-NEXT:    bsrl %eax, %eax
590 ; X86-NEXT:    xorl $31, %eax
591 ; X86-NEXT:    xorl $31, %eax
592 ; X86-NEXT:    retl
593 ; X86-NEXT:  .LBB10_1:
594 ; X86-NEXT:    movl $32, %eax
595 ; X86-NEXT:    xorl $31, %eax
596 ; X86-NEXT:    retl
598 ; X64-LABEL: ctlz_bsr_zero_test:
599 ; X64:       # %bb.0:
600 ; X64-NEXT:    testl %edi, %edi
601 ; X64-NEXT:    je .LBB10_1
602 ; X64-NEXT:  # %bb.2: # %cond.false
603 ; X64-NEXT:    bsrl %edi, %eax
604 ; X64-NEXT:    xorl $31, %eax
605 ; X64-NEXT:    xorl $31, %eax
606 ; X64-NEXT:    retq
607 ; X64-NEXT:  .LBB10_1:
608 ; X64-NEXT:    movl $32, %eax
609 ; X64-NEXT:    xorl $31, %eax
610 ; X64-NEXT:    retq
612 ; X86-CLZ-LABEL: ctlz_bsr_zero_test:
613 ; X86-CLZ:       # %bb.0:
614 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
615 ; X86-CLZ-NEXT:    xorl $31, %eax
616 ; X86-CLZ-NEXT:    retl
618 ; X64-CLZ-LABEL: ctlz_bsr_zero_test:
619 ; X64-CLZ:       # %bb.0:
620 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
621 ; X64-CLZ-NEXT:    xorl $31, %eax
622 ; X64-CLZ-NEXT:    retq
624 ; X64-FASTLZCNT-LABEL: ctlz_bsr_zero_test:
625 ; X64-FASTLZCNT:       # %bb.0:
626 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
627 ; X64-FASTLZCNT-NEXT:    xorl $31, %eax
628 ; X64-FASTLZCNT-NEXT:    retq
630 ; X86-FASTLZCNT-LABEL: ctlz_bsr_zero_test:
631 ; X86-FASTLZCNT:       # %bb.0:
632 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
633 ; X86-FASTLZCNT-NEXT:    xorl $31, %eax
634 ; X86-FASTLZCNT-NEXT:    retl
635   %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 false)
636   %bsr = xor i32 %ctlz, 31
637   ret i32 %bsr
640 define i8 @ctlz_i8_knownbits(i8 %x)  {
641 ; X86-LABEL: ctlz_i8_knownbits:
642 ; X86:       # %bb.0:
643 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
644 ; X86-NEXT:    orb $64, %al
645 ; X86-NEXT:    movzbl %al, %eax
646 ; X86-NEXT:    bsrl %eax, %eax
647 ; X86-NEXT:    xorl $7, %eax
648 ; X86-NEXT:    # kill: def $al killed $al killed $eax
649 ; X86-NEXT:    retl
651 ; X64-LABEL: ctlz_i8_knownbits:
652 ; X64:       # %bb.0:
653 ; X64-NEXT:    orb $64, %dil
654 ; X64-NEXT:    movzbl %dil, %eax
655 ; X64-NEXT:    bsrl %eax, %eax
656 ; X64-NEXT:    xorl $7, %eax
657 ; X64-NEXT:    # kill: def $al killed $al killed $eax
658 ; X64-NEXT:    retq
660 ; X86-CLZ-LABEL: ctlz_i8_knownbits:
661 ; X86-CLZ:       # %bb.0:
662 ; X86-CLZ-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
663 ; X86-CLZ-NEXT:    orb $64, %al
664 ; X86-CLZ-NEXT:    movzbl %al, %eax
665 ; X86-CLZ-NEXT:    shll $24, %eax
666 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
667 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
668 ; X86-CLZ-NEXT:    retl
670 ; X64-CLZ-LABEL: ctlz_i8_knownbits:
671 ; X64-CLZ:       # %bb.0:
672 ; X64-CLZ-NEXT:    orb $64, %dil
673 ; X64-CLZ-NEXT:    movzbl %dil, %eax
674 ; X64-CLZ-NEXT:    shll $24, %eax
675 ; X64-CLZ-NEXT:    lzcntl %eax, %eax
676 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
677 ; X64-CLZ-NEXT:    retq
679 ; X64-FASTLZCNT-LABEL: ctlz_i8_knownbits:
680 ; X64-FASTLZCNT:       # %bb.0:
681 ; X64-FASTLZCNT-NEXT:    orb $64, %dil
682 ; X64-FASTLZCNT-NEXT:    movzbl %dil, %eax
683 ; X64-FASTLZCNT-NEXT:    shll $24, %eax
684 ; X64-FASTLZCNT-NEXT:    lzcntl %eax, %eax
685 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
686 ; X64-FASTLZCNT-NEXT:    retq
688 ; X86-FASTLZCNT-LABEL: ctlz_i8_knownbits:
689 ; X86-FASTLZCNT:       # %bb.0:
690 ; X86-FASTLZCNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
691 ; X86-FASTLZCNT-NEXT:    orb $64, %al
692 ; X86-FASTLZCNT-NEXT:    movzbl %al, %eax
693 ; X86-FASTLZCNT-NEXT:    shll $24, %eax
694 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
695 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
696 ; X86-FASTLZCNT-NEXT:    retl
698   %x2 = or i8 %x, 64
699   %tmp = call i8 @llvm.ctlz.i8(i8 %x2, i1 true )
700   %tmp2 = and i8 %tmp, 1
701   ret i8 %tmp2
704 ; Make sure we can detect that the input is non-zero and avoid cmov after BSR
705 ; This is relevant for 32-bit mode without lzcnt
706 define i64 @ctlz_i64_zero_test_knownneverzero(i64 %n) {
707 ; X86-NOCMOV-LABEL: ctlz_i64_zero_test_knownneverzero:
708 ; X86-NOCMOV:       # %bb.0:
709 ; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
710 ; X86-NOCMOV-NEXT:    testl %eax, %eax
711 ; X86-NOCMOV-NEXT:    jne .LBB12_1
712 ; X86-NOCMOV-NEXT:  # %bb.2:
713 ; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
714 ; X86-NOCMOV-NEXT:    orl $1, %eax
715 ; X86-NOCMOV-NEXT:    bsrl %eax, %eax
716 ; X86-NOCMOV-NEXT:    xorl $31, %eax
717 ; X86-NOCMOV-NEXT:    orl $32, %eax
718 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
719 ; X86-NOCMOV-NEXT:    retl
720 ; X86-NOCMOV-NEXT:  .LBB12_1:
721 ; X86-NOCMOV-NEXT:    bsrl %eax, %eax
722 ; X86-NOCMOV-NEXT:    xorl $31, %eax
723 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
724 ; X86-NOCMOV-NEXT:    retl
726 ; X86-CMOV-LABEL: ctlz_i64_zero_test_knownneverzero:
727 ; X86-CMOV:       # %bb.0:
728 ; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
729 ; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
730 ; X86-CMOV-NEXT:    orl $1, %eax
731 ; X86-CMOV-NEXT:    bsrl %ecx, %edx
732 ; X86-CMOV-NEXT:    xorl $31, %edx
733 ; X86-CMOV-NEXT:    bsrl %eax, %eax
734 ; X86-CMOV-NEXT:    xorl $31, %eax
735 ; X86-CMOV-NEXT:    orl $32, %eax
736 ; X86-CMOV-NEXT:    testl %ecx, %ecx
737 ; X86-CMOV-NEXT:    cmovnel %edx, %eax
738 ; X86-CMOV-NEXT:    xorl %edx, %edx
739 ; X86-CMOV-NEXT:    retl
741 ; X64-LABEL: ctlz_i64_zero_test_knownneverzero:
742 ; X64:       # %bb.0:
743 ; X64-NEXT:    orq $1, %rdi
744 ; X64-NEXT:    bsrq %rdi, %rax
745 ; X64-NEXT:    xorq $63, %rax
746 ; X64-NEXT:    retq
748 ; X86-CLZ-LABEL: ctlz_i64_zero_test_knownneverzero:
749 ; X86-CLZ:       # %bb.0:
750 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
751 ; X86-CLZ-NEXT:    testl %eax, %eax
752 ; X86-CLZ-NEXT:    jne .LBB12_1
753 ; X86-CLZ-NEXT:  # %bb.2:
754 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
755 ; X86-CLZ-NEXT:    orl $1, %eax
756 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
757 ; X86-CLZ-NEXT:    orl $32, %eax
758 ; X86-CLZ-NEXT:    xorl %edx, %edx
759 ; X86-CLZ-NEXT:    retl
760 ; X86-CLZ-NEXT:  .LBB12_1:
761 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
762 ; X86-CLZ-NEXT:    xorl %edx, %edx
763 ; X86-CLZ-NEXT:    retl
765 ; X64-CLZ-LABEL: ctlz_i64_zero_test_knownneverzero:
766 ; X64-CLZ:       # %bb.0:
767 ; X64-CLZ-NEXT:    orq $1, %rdi
768 ; X64-CLZ-NEXT:    lzcntq %rdi, %rax
769 ; X64-CLZ-NEXT:    retq
771 ; X64-FASTLZCNT-LABEL: ctlz_i64_zero_test_knownneverzero:
772 ; X64-FASTLZCNT:       # %bb.0:
773 ; X64-FASTLZCNT-NEXT:    orq $1, %rdi
774 ; X64-FASTLZCNT-NEXT:    lzcntq %rdi, %rax
775 ; X64-FASTLZCNT-NEXT:    retq
777 ; X86-FASTLZCNT-LABEL: ctlz_i64_zero_test_knownneverzero:
778 ; X86-FASTLZCNT:       # %bb.0:
779 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
780 ; X86-FASTLZCNT-NEXT:    testl %eax, %eax
781 ; X86-FASTLZCNT-NEXT:    jne .LBB12_1
782 ; X86-FASTLZCNT-NEXT:  # %bb.2:
783 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
784 ; X86-FASTLZCNT-NEXT:    orl $1, %eax
785 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
786 ; X86-FASTLZCNT-NEXT:    orl $32, %eax
787 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
788 ; X86-FASTLZCNT-NEXT:    retl
789 ; X86-FASTLZCNT-NEXT:  .LBB12_1:
790 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
791 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
792 ; X86-FASTLZCNT-NEXT:    retl
793   %o = or i64 %n, 1
794   %tmp1 = call i64 @llvm.ctlz.i64(i64 %o, i1 false)
795   ret i64 %tmp1
798 ; Ensure we fold away the XOR(TRUNC(XOR(BSR(X),31)),31).
799 define i8 @PR47603_trunc(i32 %0) {
800 ; X86-LABEL: PR47603_trunc:
801 ; X86:       # %bb.0:
802 ; X86-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
803 ; X86-NEXT:    # kill: def $al killed $al killed $eax
804 ; X86-NEXT:    retl
806 ; X64-LABEL: PR47603_trunc:
807 ; X64:       # %bb.0:
808 ; X64-NEXT:    bsrl %edi, %eax
809 ; X64-NEXT:    # kill: def $al killed $al killed $eax
810 ; X64-NEXT:    retq
812 ; X86-CLZ-LABEL: PR47603_trunc:
813 ; X86-CLZ:       # %bb.0:
814 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
815 ; X86-CLZ-NEXT:    xorb $31, %al
816 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
817 ; X86-CLZ-NEXT:    retl
819 ; X64-CLZ-LABEL: PR47603_trunc:
820 ; X64-CLZ:       # %bb.0:
821 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
822 ; X64-CLZ-NEXT:    xorb $31, %al
823 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
824 ; X64-CLZ-NEXT:    retq
826 ; X64-FASTLZCNT-LABEL: PR47603_trunc:
827 ; X64-FASTLZCNT:       # %bb.0:
828 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
829 ; X64-FASTLZCNT-NEXT:    xorb $31, %al
830 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
831 ; X64-FASTLZCNT-NEXT:    retq
833 ; X86-FASTLZCNT-LABEL: PR47603_trunc:
834 ; X86-FASTLZCNT:       # %bb.0:
835 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
836 ; X86-FASTLZCNT-NEXT:    xorb $31, %al
837 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
838 ; X86-FASTLZCNT-NEXT:    retl
839   %2 = call i32 @llvm.ctlz.i32(i32 %0, i1 true)
840   %3 = xor i32 %2, 31
841   %4 = trunc i32 %3 to i8
842   ret i8 %4
845 ; Ensure we fold away the XOR(ZEXT(XOR(BSR(X),31)),31).
846 define i32 @PR47603_zext(i32 %a0, ptr %a1) {
847 ; X86-LABEL: PR47603_zext:
848 ; X86:       # %bb.0:
849 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
850 ; X86-NEXT:    bsrl {{[0-9]+}}(%esp), %ecx
851 ; X86-NEXT:    movsbl (%eax,%ecx), %eax
852 ; X86-NEXT:    retl
854 ; X64-LABEL: PR47603_zext:
855 ; X64:       # %bb.0:
856 ; X64-NEXT:    bsrl %edi, %eax
857 ; X64-NEXT:    movsbl (%rsi,%rax), %eax
858 ; X64-NEXT:    retq
860 ; X86-CLZ-LABEL: PR47603_zext:
861 ; X86-CLZ:       # %bb.0:
862 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
863 ; X86-CLZ-NEXT:    bsrl {{[0-9]+}}(%esp), %ecx
864 ; X86-CLZ-NEXT:    movsbl (%eax,%ecx), %eax
865 ; X86-CLZ-NEXT:    retl
867 ; X64-CLZ-LABEL: PR47603_zext:
868 ; X64-CLZ:       # %bb.0:
869 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
870 ; X64-CLZ-NEXT:    xorq $31, %rax
871 ; X64-CLZ-NEXT:    movsbl (%rsi,%rax), %eax
872 ; X64-CLZ-NEXT:    retq
874 ; X64-FASTLZCNT-LABEL: PR47603_zext:
875 ; X64-FASTLZCNT:       # %bb.0:
876 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
877 ; X64-FASTLZCNT-NEXT:    xorq $31, %rax
878 ; X64-FASTLZCNT-NEXT:    movsbl (%rsi,%rax), %eax
879 ; X64-FASTLZCNT-NEXT:    retq
881 ; X86-FASTLZCNT-LABEL: PR47603_zext:
882 ; X86-FASTLZCNT:       # %bb.0:
883 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
884 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %ecx
885 ; X86-FASTLZCNT-NEXT:    xorl $31, %ecx
886 ; X86-FASTLZCNT-NEXT:    movsbl (%eax,%ecx), %eax
887 ; X86-FASTLZCNT-NEXT:    retl
888   %ctlz = tail call i32 @llvm.ctlz.i32(i32 %a0, i1 true)
889   %xor = xor i32 %ctlz, 31
890   %zext = zext i32 %xor to i64
891   %gep = getelementptr inbounds [32 x i8], ptr %a1, i64 0, i64 %zext
892   %load = load i8, ptr %gep, align 1
893   %sext = sext i8 %load to i32
894   ret i32 %sext
897 define i8 @ctlz_xor7_i8_true(i8 %x) {
898 ; X86-LABEL: ctlz_xor7_i8_true:
899 ; X86:       # %bb.0:
900 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
901 ; X86-NEXT:    bsrl %eax, %eax
902 ; X86-NEXT:    # kill: def $al killed $al killed $eax
903 ; X86-NEXT:    retl
905 ; X64-LABEL: ctlz_xor7_i8_true:
906 ; X64:       # %bb.0:
907 ; X64-NEXT:    movzbl %dil, %eax
908 ; X64-NEXT:    bsrl %eax, %eax
909 ; X64-NEXT:    # kill: def $al killed $al killed $eax
910 ; X64-NEXT:    retq
912 ; X86-CLZ-LABEL: ctlz_xor7_i8_true:
913 ; X86-CLZ:       # %bb.0:
914 ; X86-CLZ-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
915 ; X86-CLZ-NEXT:    bsrl %eax, %eax
916 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
917 ; X86-CLZ-NEXT:    retl
919 ; X64-CLZ-LABEL: ctlz_xor7_i8_true:
920 ; X64-CLZ:       # %bb.0:
921 ; X64-CLZ-NEXT:    movzbl %dil, %eax
922 ; X64-CLZ-NEXT:    bsrl %eax, %eax
923 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
924 ; X64-CLZ-NEXT:    retq
926 ; X64-FASTLZCNT-LABEL: ctlz_xor7_i8_true:
927 ; X64-FASTLZCNT:       # %bb.0:
928 ; X64-FASTLZCNT-NEXT:    shll $24, %edi
929 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
930 ; X64-FASTLZCNT-NEXT:    xorb $7, %al
931 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
932 ; X64-FASTLZCNT-NEXT:    retq
934 ; X86-FASTLZCNT-LABEL: ctlz_xor7_i8_true:
935 ; X86-FASTLZCNT:       # %bb.0:
936 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
937 ; X86-FASTLZCNT-NEXT:    shll $24, %eax
938 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
939 ; X86-FASTLZCNT-NEXT:    xorb $7, %al
940 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
941 ; X86-FASTLZCNT-NEXT:    retl
942     %clz = call i8 @llvm.ctlz.i8(i8 %x, i1 true)
943     %res = xor i8 %clz, 7
944     ret i8 %res
947 define i8 @ctlz_xor7_i8_false(i8 %x) {
948 ; X86-LABEL: ctlz_xor7_i8_false:
949 ; X86:       # %bb.0:
950 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
951 ; X86-NEXT:    testb %al, %al
952 ; X86-NEXT:    je .LBB16_1
953 ; X86-NEXT:  # %bb.2: # %cond.false
954 ; X86-NEXT:    movzbl %al, %eax
955 ; X86-NEXT:    bsrl %eax, %eax
956 ; X86-NEXT:    xorl $7, %eax
957 ; X86-NEXT:    xorb $7, %al
958 ; X86-NEXT:    # kill: def $al killed $al killed $eax
959 ; X86-NEXT:    retl
960 ; X86-NEXT:  .LBB16_1:
961 ; X86-NEXT:    movb $8, %al
962 ; X86-NEXT:    xorb $7, %al
963 ; X86-NEXT:    # kill: def $al killed $al killed $eax
964 ; X86-NEXT:    retl
966 ; X64-LABEL: ctlz_xor7_i8_false:
967 ; X64:       # %bb.0:
968 ; X64-NEXT:    testb %dil, %dil
969 ; X64-NEXT:    je .LBB16_1
970 ; X64-NEXT:  # %bb.2: # %cond.false
971 ; X64-NEXT:    movzbl %dil, %eax
972 ; X64-NEXT:    bsrl %eax, %eax
973 ; X64-NEXT:    xorl $7, %eax
974 ; X64-NEXT:    xorb $7, %al
975 ; X64-NEXT:    # kill: def $al killed $al killed $eax
976 ; X64-NEXT:    retq
977 ; X64-NEXT:  .LBB16_1:
978 ; X64-NEXT:    movb $8, %al
979 ; X64-NEXT:    xorb $7, %al
980 ; X64-NEXT:    # kill: def $al killed $al killed $eax
981 ; X64-NEXT:    retq
983 ; X86-CLZ-LABEL: ctlz_xor7_i8_false:
984 ; X86-CLZ:       # %bb.0:
985 ; X86-CLZ-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
986 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
987 ; X86-CLZ-NEXT:    addl $-24, %eax
988 ; X86-CLZ-NEXT:    xorb $7, %al
989 ; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax
990 ; X86-CLZ-NEXT:    retl
992 ; X64-CLZ-LABEL: ctlz_xor7_i8_false:
993 ; X64-CLZ:       # %bb.0:
994 ; X64-CLZ-NEXT:    movzbl %dil, %eax
995 ; X64-CLZ-NEXT:    lzcntl %eax, %eax
996 ; X64-CLZ-NEXT:    addl $-24, %eax
997 ; X64-CLZ-NEXT:    xorb $7, %al
998 ; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax
999 ; X64-CLZ-NEXT:    retq
1001 ; X64-FASTLZCNT-LABEL: ctlz_xor7_i8_false:
1002 ; X64-FASTLZCNT:       # %bb.0:
1003 ; X64-FASTLZCNT-NEXT:    movzbl %dil, %eax
1004 ; X64-FASTLZCNT-NEXT:    lzcntl %eax, %eax
1005 ; X64-FASTLZCNT-NEXT:    addl $-24, %eax
1006 ; X64-FASTLZCNT-NEXT:    xorb $7, %al
1007 ; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
1008 ; X64-FASTLZCNT-NEXT:    retq
1010 ; X86-FASTLZCNT-LABEL: ctlz_xor7_i8_false:
1011 ; X86-FASTLZCNT:       # %bb.0:
1012 ; X86-FASTLZCNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
1013 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
1014 ; X86-FASTLZCNT-NEXT:    addl $-24, %eax
1015 ; X86-FASTLZCNT-NEXT:    xorb $7, %al
1016 ; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax
1017 ; X86-FASTLZCNT-NEXT:    retl
1018     %clz = call i8 @llvm.ctlz.i8(i8 %x, i1 false)
1019     %res = xor i8 %clz, 7
1020     ret i8 %res
1023 define i16 @ctlz_xor15_i16_true(i16 %x) {
1024 ; X86-LABEL: ctlz_xor15_i16_true:
1025 ; X86:       # %bb.0:
1026 ; X86-NEXT:    bsrw {{[0-9]+}}(%esp), %ax
1027 ; X86-NEXT:    retl
1029 ; X64-LABEL: ctlz_xor15_i16_true:
1030 ; X64:       # %bb.0:
1031 ; X64-NEXT:    bsrw %di, %ax
1032 ; X64-NEXT:    retq
1034 ; X86-CLZ-LABEL: ctlz_xor15_i16_true:
1035 ; X86-CLZ:       # %bb.0:
1036 ; X86-CLZ-NEXT:    bsrw {{[0-9]+}}(%esp), %ax
1037 ; X86-CLZ-NEXT:    retl
1039 ; X64-CLZ-LABEL: ctlz_xor15_i16_true:
1040 ; X64-CLZ:       # %bb.0:
1041 ; X64-CLZ-NEXT:    bsrw %di, %ax
1042 ; X64-CLZ-NEXT:    retq
1044 ; X64-FASTLZCNT-LABEL: ctlz_xor15_i16_true:
1045 ; X64-FASTLZCNT:       # %bb.0:
1046 ; X64-FASTLZCNT-NEXT:    lzcntw %di, %ax
1047 ; X64-FASTLZCNT-NEXT:    xorl $15, %eax
1048 ; X64-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax
1049 ; X64-FASTLZCNT-NEXT:    retq
1051 ; X86-FASTLZCNT-LABEL: ctlz_xor15_i16_true:
1052 ; X86-FASTLZCNT:       # %bb.0:
1053 ; X86-FASTLZCNT-NEXT:    lzcntw {{[0-9]+}}(%esp), %ax
1054 ; X86-FASTLZCNT-NEXT:    xorl $15, %eax
1055 ; X86-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax
1056 ; X86-FASTLZCNT-NEXT:    retl
1057     %clz = call i16 @llvm.ctlz.i16(i16 %x, i1 true)
1058     %res = xor i16 %clz, 15
1059     ret i16 %res
1062 define i32 @ctlz_xor31_i32_false(i32 %x) {
1063 ; X86-LABEL: ctlz_xor31_i32_false:
1064 ; X86:       # %bb.0:
1065 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1066 ; X86-NEXT:    testl %eax, %eax
1067 ; X86-NEXT:    je .LBB18_1
1068 ; X86-NEXT:  # %bb.2: # %cond.false
1069 ; X86-NEXT:    bsrl %eax, %eax
1070 ; X86-NEXT:    xorl $31, %eax
1071 ; X86-NEXT:    xorl $31, %eax
1072 ; X86-NEXT:    retl
1073 ; X86-NEXT:  .LBB18_1:
1074 ; X86-NEXT:    movl $32, %eax
1075 ; X86-NEXT:    xorl $31, %eax
1076 ; X86-NEXT:    retl
1078 ; X64-LABEL: ctlz_xor31_i32_false:
1079 ; X64:       # %bb.0:
1080 ; X64-NEXT:    testl %edi, %edi
1081 ; X64-NEXT:    je .LBB18_1
1082 ; X64-NEXT:  # %bb.2: # %cond.false
1083 ; X64-NEXT:    bsrl %edi, %eax
1084 ; X64-NEXT:    xorl $31, %eax
1085 ; X64-NEXT:    xorl $31, %eax
1086 ; X64-NEXT:    retq
1087 ; X64-NEXT:  .LBB18_1:
1088 ; X64-NEXT:    movl $32, %eax
1089 ; X64-NEXT:    xorl $31, %eax
1090 ; X64-NEXT:    retq
1092 ; X86-CLZ-LABEL: ctlz_xor31_i32_false:
1093 ; X86-CLZ:       # %bb.0:
1094 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
1095 ; X86-CLZ-NEXT:    xorl $31, %eax
1096 ; X86-CLZ-NEXT:    retl
1098 ; X64-CLZ-LABEL: ctlz_xor31_i32_false:
1099 ; X64-CLZ:       # %bb.0:
1100 ; X64-CLZ-NEXT:    lzcntl %edi, %eax
1101 ; X64-CLZ-NEXT:    xorl $31, %eax
1102 ; X64-CLZ-NEXT:    retq
1104 ; X64-FASTLZCNT-LABEL: ctlz_xor31_i32_false:
1105 ; X64-FASTLZCNT:       # %bb.0:
1106 ; X64-FASTLZCNT-NEXT:    lzcntl %edi, %eax
1107 ; X64-FASTLZCNT-NEXT:    xorl $31, %eax
1108 ; X64-FASTLZCNT-NEXT:    retq
1110 ; X86-FASTLZCNT-LABEL: ctlz_xor31_i32_false:
1111 ; X86-FASTLZCNT:       # %bb.0:
1112 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
1113 ; X86-FASTLZCNT-NEXT:    xorl $31, %eax
1114 ; X86-FASTLZCNT-NEXT:    retl
1115     %clz = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
1116     %res = xor i32 %clz, 31
1117     ret i32 %res
1120 define i64 @ctlz_xor63_i64_true(i64 %x) {
1121 ; X86-NOCMOV-LABEL: ctlz_xor63_i64_true:
1122 ; X86-NOCMOV:       # %bb.0:
1123 ; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
1124 ; X86-NOCMOV-NEXT:    testl %eax, %eax
1125 ; X86-NOCMOV-NEXT:    jne .LBB19_1
1126 ; X86-NOCMOV-NEXT:  # %bb.2:
1127 ; X86-NOCMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
1128 ; X86-NOCMOV-NEXT:    xorl $31, %eax
1129 ; X86-NOCMOV-NEXT:    addl $32, %eax
1130 ; X86-NOCMOV-NEXT:    jmp .LBB19_3
1131 ; X86-NOCMOV-NEXT:  .LBB19_1:
1132 ; X86-NOCMOV-NEXT:    bsrl %eax, %eax
1133 ; X86-NOCMOV-NEXT:    xorl $31, %eax
1134 ; X86-NOCMOV-NEXT:  .LBB19_3:
1135 ; X86-NOCMOV-NEXT:    xorl $63, %eax
1136 ; X86-NOCMOV-NEXT:    xorl %edx, %edx
1137 ; X86-NOCMOV-NEXT:    retl
1139 ; X86-CMOV-LABEL: ctlz_xor63_i64_true:
1140 ; X86-CMOV:       # %bb.0:
1141 ; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1142 ; X86-CMOV-NEXT:    bsrl %ecx, %edx
1143 ; X86-CMOV-NEXT:    xorl $31, %edx
1144 ; X86-CMOV-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
1145 ; X86-CMOV-NEXT:    xorl $31, %eax
1146 ; X86-CMOV-NEXT:    addl $32, %eax
1147 ; X86-CMOV-NEXT:    testl %ecx, %ecx
1148 ; X86-CMOV-NEXT:    cmovnel %edx, %eax
1149 ; X86-CMOV-NEXT:    xorl $63, %eax
1150 ; X86-CMOV-NEXT:    xorl %edx, %edx
1151 ; X86-CMOV-NEXT:    retl
1153 ; X64-LABEL: ctlz_xor63_i64_true:
1154 ; X64:       # %bb.0:
1155 ; X64-NEXT:    bsrq %rdi, %rax
1156 ; X64-NEXT:    retq
1158 ; X86-CLZ-LABEL: ctlz_xor63_i64_true:
1159 ; X86-CLZ:       # %bb.0:
1160 ; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax
1161 ; X86-CLZ-NEXT:    testl %eax, %eax
1162 ; X86-CLZ-NEXT:    jne .LBB19_1
1163 ; X86-CLZ-NEXT:  # %bb.2:
1164 ; X86-CLZ-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
1165 ; X86-CLZ-NEXT:    addl $32, %eax
1166 ; X86-CLZ-NEXT:    jmp .LBB19_3
1167 ; X86-CLZ-NEXT:  .LBB19_1:
1168 ; X86-CLZ-NEXT:    lzcntl %eax, %eax
1169 ; X86-CLZ-NEXT:  .LBB19_3:
1170 ; X86-CLZ-NEXT:    xorl $63, %eax
1171 ; X86-CLZ-NEXT:    xorl %edx, %edx
1172 ; X86-CLZ-NEXT:    retl
1174 ; X64-CLZ-LABEL: ctlz_xor63_i64_true:
1175 ; X64-CLZ:       # %bb.0:
1176 ; X64-CLZ-NEXT:    bsrq %rdi, %rax
1177 ; X64-CLZ-NEXT:    retq
1179 ; X64-FASTLZCNT-LABEL: ctlz_xor63_i64_true:
1180 ; X64-FASTLZCNT:       # %bb.0:
1181 ; X64-FASTLZCNT-NEXT:    lzcntq %rdi, %rax
1182 ; X64-FASTLZCNT-NEXT:    xorq $63, %rax
1183 ; X64-FASTLZCNT-NEXT:    retq
1185 ; X86-FASTLZCNT-LABEL: ctlz_xor63_i64_true:
1186 ; X86-FASTLZCNT:       # %bb.0:
1187 ; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
1188 ; X86-FASTLZCNT-NEXT:    testl %eax, %eax
1189 ; X86-FASTLZCNT-NEXT:    jne .LBB19_1
1190 ; X86-FASTLZCNT-NEXT:  # %bb.2:
1191 ; X86-FASTLZCNT-NEXT:    lzcntl {{[0-9]+}}(%esp), %eax
1192 ; X86-FASTLZCNT-NEXT:    addl $32, %eax
1193 ; X86-FASTLZCNT-NEXT:    jmp .LBB19_3
1194 ; X86-FASTLZCNT-NEXT:  .LBB19_1:
1195 ; X86-FASTLZCNT-NEXT:    lzcntl %eax, %eax
1196 ; X86-FASTLZCNT-NEXT:  .LBB19_3:
1197 ; X86-FASTLZCNT-NEXT:    xorl $63, %eax
1198 ; X86-FASTLZCNT-NEXT:    xorl %edx, %edx
1199 ; X86-FASTLZCNT-NEXT:    retl
1200     %clz = call i64 @llvm.ctlz.i64(i64 %x, i1 true)
1201     %res = xor i64 %clz, 63
1202     ret i64 %res