[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / known-never-zero.ll
blob6c0aaeb451e14a84fbe013a2ab5cf99dc4c105bc
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=X64
5 ;; Use cttz to test if we properly prove never-zero. There is a very
6 ;; simple transform from cttz -> cttz_zero_undef if its operand is
7 ;; known never zero.
8 declare i32 @llvm.cttz.i32(i32, i1)
9 declare i32 @llvm.uadd.sat.i32(i32, i32)
10 declare i32 @llvm.umax.i32(i32, i32)
11 declare i32 @llvm.umin.i32(i32, i32)
12 declare i32 @llvm.smin.i32(i32, i32)
13 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
14 declare i32 @llvm.smax.i32(i32, i32)
15 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
16 declare i32 @llvm.bswap.i32(i32)
17 declare i32 @llvm.bitreverse.i32(i32)
18 declare i32 @llvm.ctpop.i32(i32)
19 declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)
20 declare i32 @llvm.abs.i32(i32, i1)
21 declare i32 @llvm.fshl.i32(i32, i32, i32)
22 declare i32 @llvm.fshr.i32(i32, i32, i32)
24 define i32 @or_known_nonzero(i32 %x) {
25 ; X86-LABEL: or_known_nonzero:
26 ; X86:       # %bb.0:
27 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
28 ; X86-NEXT:    orl $1, %eax
29 ; X86-NEXT:    rep bsfl %eax, %eax
30 ; X86-NEXT:    retl
32 ; X64-LABEL: or_known_nonzero:
33 ; X64:       # %bb.0:
34 ; X64-NEXT:    orl $1, %edi
35 ; X64-NEXT:    rep bsfl %edi, %eax
36 ; X64-NEXT:    retq
37   %z = or i32 %x, 1
38   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
39   ret i32 %r
42 define i32 @or_maybe_zero(i32 %x, i32 %y) {
43 ; X86-LABEL: or_maybe_zero:
44 ; X86:       # %bb.0:
45 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
46 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
47 ; X86-NEXT:    bsfl %eax, %ecx
48 ; X86-NEXT:    movl $32, %eax
49 ; X86-NEXT:    cmovnel %ecx, %eax
50 ; X86-NEXT:    retl
52 ; X64-LABEL: or_maybe_zero:
53 ; X64:       # %bb.0:
54 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
55 ; X64-NEXT:    orl %esi, %edi
56 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
57 ; X64-NEXT:    orq %rdi, %rax
58 ; X64-NEXT:    rep bsfq %rax, %rax
59 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
60 ; X64-NEXT:    retq
61   %z = or i32 %x, %y
62   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
63   ret i32 %r
66 define i32 @select_known_nonzero(i1 %c, i32 %x) {
67 ; X86-LABEL: select_known_nonzero:
68 ; X86:       # %bb.0:
69 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
70 ; X86-NEXT:    orl $1, %eax
71 ; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
72 ; X86-NEXT:    movl $122, %ecx
73 ; X86-NEXT:    cmovnel %eax, %ecx
74 ; X86-NEXT:    rep bsfl %ecx, %eax
75 ; X86-NEXT:    retl
77 ; X64-LABEL: select_known_nonzero:
78 ; X64:       # %bb.0:
79 ; X64-NEXT:    orl $1, %esi
80 ; X64-NEXT:    testb $1, %dil
81 ; X64-NEXT:    movl $122, %eax
82 ; X64-NEXT:    cmovnel %esi, %eax
83 ; X64-NEXT:    rep bsfl %eax, %eax
84 ; X64-NEXT:    retq
85   %y = or i32 %x, 1
86   %z = select i1 %c, i32 %y, i32 122
87   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
88   ret i32 %r
91 define i32 @select_maybe_zero(i1 %c, i32 %x) {
92 ; X86-LABEL: select_maybe_zero:
93 ; X86:       # %bb.0:
94 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
95 ; X86-NEXT:    orl $1, %eax
96 ; X86-NEXT:    xorl %ecx, %ecx
97 ; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
98 ; X86-NEXT:    cmovnel %eax, %ecx
99 ; X86-NEXT:    bsfl %ecx, %ecx
100 ; X86-NEXT:    movl $32, %eax
101 ; X86-NEXT:    cmovnel %ecx, %eax
102 ; X86-NEXT:    retl
104 ; X64-LABEL: select_maybe_zero:
105 ; X64:       # %bb.0:
106 ; X64-NEXT:    orl $1, %esi
107 ; X64-NEXT:    xorl %eax, %eax
108 ; X64-NEXT:    testb $1, %dil
109 ; X64-NEXT:    cmovnel %esi, %eax
110 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
111 ; X64-NEXT:    orq %rax, %rcx
112 ; X64-NEXT:    rep bsfq %rcx, %rax
113 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
114 ; X64-NEXT:    retq
115   %y = or i32 %x, 1
116   %z = select i1 %c, i32 %y, i32 0
117   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
118   ret i32 %r
121 define i32 @shl_known_nonzero_1s_bit_set(i32 %x) {
122 ; X86-LABEL: shl_known_nonzero_1s_bit_set:
123 ; X86:       # %bb.0:
124 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
125 ; X86-NEXT:    movl $123, %eax
126 ; X86-NEXT:    shll %cl, %eax
127 ; X86-NEXT:    rep bsfl %eax, %eax
128 ; X86-NEXT:    retl
130 ; X64-LABEL: shl_known_nonzero_1s_bit_set:
131 ; X64:       # %bb.0:
132 ; X64-NEXT:    movl %edi, %ecx
133 ; X64-NEXT:    movl $123, %eax
134 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
135 ; X64-NEXT:    shll %cl, %eax
136 ; X64-NEXT:    rep bsfl %eax, %eax
137 ; X64-NEXT:    retq
138   %z = shl i32 123, %x
139   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
140   ret i32 %r
143 define i32 @shl_known_nonzero_nsw(i32 %x, i32 %yy) {
144 ; X86-LABEL: shl_known_nonzero_nsw:
145 ; X86:       # %bb.0:
146 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
147 ; X86-NEXT:    movl $256, %eax # imm = 0x100
148 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
149 ; X86-NEXT:    shll %cl, %eax
150 ; X86-NEXT:    rep bsfl %eax, %eax
151 ; X86-NEXT:    retl
153 ; X64-LABEL: shl_known_nonzero_nsw:
154 ; X64:       # %bb.0:
155 ; X64-NEXT:    movl %edi, %ecx
156 ; X64-NEXT:    orl $256, %esi # imm = 0x100
157 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
158 ; X64-NEXT:    shll %cl, %esi
159 ; X64-NEXT:    rep bsfl %esi, %eax
160 ; X64-NEXT:    retq
161   %y = or i32 %yy, 256
162   %z = shl nsw i32 %y, %x
163   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
164   ret i32 %r
167 define i32 @shl_known_nonzero_nuw(i32 %x, i32 %yy) {
168 ; X86-LABEL: shl_known_nonzero_nuw:
169 ; X86:       # %bb.0:
170 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
171 ; X86-NEXT:    movl $256, %eax # imm = 0x100
172 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
173 ; X86-NEXT:    shll %cl, %eax
174 ; X86-NEXT:    rep bsfl %eax, %eax
175 ; X86-NEXT:    retl
177 ; X64-LABEL: shl_known_nonzero_nuw:
178 ; X64:       # %bb.0:
179 ; X64-NEXT:    movl %edi, %ecx
180 ; X64-NEXT:    orl $256, %esi # imm = 0x100
181 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
182 ; X64-NEXT:    shll %cl, %esi
183 ; X64-NEXT:    rep bsfl %esi, %eax
184 ; X64-NEXT:    retq
185   %y = or i32 %yy, 256
186   %z = shl nuw i32 %y, %x
187   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
188   ret i32 %r
191 define i32 @shl_maybe_zero(i32 %x, i32 %y) {
192 ; X86-LABEL: shl_maybe_zero:
193 ; X86:       # %bb.0:
194 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
195 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
196 ; X86-NEXT:    shll %cl, %eax
197 ; X86-NEXT:    bsfl %eax, %ecx
198 ; X86-NEXT:    movl $32, %eax
199 ; X86-NEXT:    cmovnel %ecx, %eax
200 ; X86-NEXT:    retl
202 ; X64-LABEL: shl_maybe_zero:
203 ; X64:       # %bb.0:
204 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
205 ; X64-NEXT:    movl %edi, %ecx
206 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
207 ; X64-NEXT:    shll %cl, %esi
208 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
209 ; X64-NEXT:    orq %rsi, %rax
210 ; X64-NEXT:    rep bsfq %rax, %rax
211 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
212 ; X64-NEXT:    retq
213   %z = shl nuw nsw i32 %y, %x
214   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
215   ret i32 %r
218 define i32 @uaddsat_known_nonzero(i32 %x) {
219 ; X86-LABEL: uaddsat_known_nonzero:
220 ; X86:       # %bb.0:
221 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
222 ; X86-NEXT:    incl %eax
223 ; X86-NEXT:    movl $-1, %ecx
224 ; X86-NEXT:    cmovnel %eax, %ecx
225 ; X86-NEXT:    rep bsfl %ecx, %eax
226 ; X86-NEXT:    retl
228 ; X64-LABEL: uaddsat_known_nonzero:
229 ; X64:       # %bb.0:
230 ; X64-NEXT:    incl %edi
231 ; X64-NEXT:    movl $-1, %eax
232 ; X64-NEXT:    cmovnel %edi, %eax
233 ; X64-NEXT:    rep bsfl %eax, %eax
234 ; X64-NEXT:    retq
235   %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 1)
236   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
237   ret i32 %r
240 define i32 @uaddsat_maybe_zero(i32 %x, i32 %y) {
241 ; X86-LABEL: uaddsat_maybe_zero:
242 ; X86:       # %bb.0:
243 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
244 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
245 ; X86-NEXT:    movl $-1, %ecx
246 ; X86-NEXT:    cmovael %eax, %ecx
247 ; X86-NEXT:    bsfl %ecx, %ecx
248 ; X86-NEXT:    movl $32, %eax
249 ; X86-NEXT:    cmovnel %ecx, %eax
250 ; X86-NEXT:    retl
252 ; X64-LABEL: uaddsat_maybe_zero:
253 ; X64:       # %bb.0:
254 ; X64-NEXT:    addl %esi, %edi
255 ; X64-NEXT:    movl $-1, %eax
256 ; X64-NEXT:    cmovael %edi, %eax
257 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
258 ; X64-NEXT:    orq %rax, %rcx
259 ; X64-NEXT:    rep bsfq %rcx, %rax
260 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
261 ; X64-NEXT:    retq
262   %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 %y)
263   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
264   ret i32 %r
267 define i32 @umax_known_nonzero(i32 %x, i32 %y) {
268 ; X86-LABEL: umax_known_nonzero:
269 ; X86:       # %bb.0:
270 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
271 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
272 ; X86-NEXT:    movl $4, %edx
273 ; X86-NEXT:    shll %cl, %edx
274 ; X86-NEXT:    cmpl %edx, %eax
275 ; X86-NEXT:    cmoval %eax, %edx
276 ; X86-NEXT:    rep bsfl %edx, %eax
277 ; X86-NEXT:    retl
279 ; X64-LABEL: umax_known_nonzero:
280 ; X64:       # %bb.0:
281 ; X64-NEXT:    movl %esi, %ecx
282 ; X64-NEXT:    movl $4, %eax
283 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
284 ; X64-NEXT:    shll %cl, %eax
285 ; X64-NEXT:    cmpl %eax, %edi
286 ; X64-NEXT:    cmoval %edi, %eax
287 ; X64-NEXT:    rep bsfl %eax, %eax
288 ; X64-NEXT:    retq
289   %yy = shl nuw i32 4, %y
290   %z = call i32 @llvm.umax.i32(i32 %x, i32 %yy)
291   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
292   ret i32 %r
295 define i32 @umax_maybe_zero(i32 %x, i32 %y) {
296 ; X86-LABEL: umax_maybe_zero:
297 ; X86:       # %bb.0:
298 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
299 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
300 ; X86-NEXT:    cmpl %eax, %ecx
301 ; X86-NEXT:    cmoval %ecx, %eax
302 ; X86-NEXT:    bsfl %eax, %ecx
303 ; X86-NEXT:    movl $32, %eax
304 ; X86-NEXT:    cmovnel %ecx, %eax
305 ; X86-NEXT:    retl
307 ; X64-LABEL: umax_maybe_zero:
308 ; X64:       # %bb.0:
309 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
310 ; X64-NEXT:    cmpl %esi, %edi
311 ; X64-NEXT:    cmoval %edi, %esi
312 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
313 ; X64-NEXT:    orq %rsi, %rax
314 ; X64-NEXT:    rep bsfq %rax, %rax
315 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
316 ; X64-NEXT:    retq
317   %z = call i32 @llvm.umax.i32(i32 %x, i32 %y)
318   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
319   ret i32 %r
322 define i32 @umin_known_nonzero(i32 %xx, i32 %yy) {
323 ; X86-LABEL: umin_known_nonzero:
324 ; X86:       # %bb.0:
325 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
326 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
327 ; X86-NEXT:    movl $4, %edx
328 ; X86-NEXT:    shll %cl, %edx
329 ; X86-NEXT:    addl $4, %eax
330 ; X86-NEXT:    cmpl %eax, %edx
331 ; X86-NEXT:    cmovbl %edx, %eax
332 ; X86-NEXT:    rep bsfl %eax, %eax
333 ; X86-NEXT:    retl
335 ; X64-LABEL: umin_known_nonzero:
336 ; X64:       # %bb.0:
337 ; X64-NEXT:    movl %edi, %ecx
338 ; X64-NEXT:    movl $4, %eax
339 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
340 ; X64-NEXT:    shll %cl, %eax
341 ; X64-NEXT:    addl $4, %esi
342 ; X64-NEXT:    cmpl %esi, %eax
343 ; X64-NEXT:    cmovbl %eax, %esi
344 ; X64-NEXT:    rep bsfl %esi, %eax
345 ; X64-NEXT:    retq
346   %x = shl nuw i32 4, %xx
347   %y = add nuw nsw i32 %yy, 4
348   %z = call i32 @llvm.umin.i32(i32 %x, i32 %y)
349   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
350   ret i32 %r
353 define i32 @umin_maybe_zero(i32 %x, i32 %y) {
354 ; X86-LABEL: umin_maybe_zero:
355 ; X86:       # %bb.0:
356 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
357 ; X86-NEXT:    cmpl $54, %eax
358 ; X86-NEXT:    movl $54, %ecx
359 ; X86-NEXT:    cmovbl %eax, %ecx
360 ; X86-NEXT:    bsfl %ecx, %ecx
361 ; X86-NEXT:    movl $32, %eax
362 ; X86-NEXT:    cmovnel %ecx, %eax
363 ; X86-NEXT:    retl
365 ; X64-LABEL: umin_maybe_zero:
366 ; X64:       # %bb.0:
367 ; X64-NEXT:    cmpl $54, %edi
368 ; X64-NEXT:    movl $54, %eax
369 ; X64-NEXT:    cmovbl %edi, %eax
370 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
371 ; X64-NEXT:    orq %rax, %rcx
372 ; X64-NEXT:    rep bsfq %rcx, %rax
373 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
374 ; X64-NEXT:    retq
375   %z = call i32 @llvm.umin.i32(i32 %x, i32 54)
376   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
377   ret i32 %r
380 define i32 @smin_known_nonzero(i32 %xx, i32 %yy) {
381 ; X86-LABEL: smin_known_nonzero:
382 ; X86:       # %bb.0:
383 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
384 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
385 ; X86-NEXT:    movl $4, %edx
386 ; X86-NEXT:    shll %cl, %edx
387 ; X86-NEXT:    addl $4, %eax
388 ; X86-NEXT:    cmpl %eax, %edx
389 ; X86-NEXT:    cmovll %edx, %eax
390 ; X86-NEXT:    rep bsfl %eax, %eax
391 ; X86-NEXT:    retl
393 ; X64-LABEL: smin_known_nonzero:
394 ; X64:       # %bb.0:
395 ; X64-NEXT:    movl %edi, %ecx
396 ; X64-NEXT:    movl $4, %eax
397 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
398 ; X64-NEXT:    shll %cl, %eax
399 ; X64-NEXT:    addl $4, %esi
400 ; X64-NEXT:    cmpl %esi, %eax
401 ; X64-NEXT:    cmovll %eax, %esi
402 ; X64-NEXT:    rep bsfl %esi, %eax
403 ; X64-NEXT:    retq
404   %x = shl nuw i32 4, %xx
405   %y = add nuw nsw i32 %yy, 4
406   %z = call i32 @llvm.smin.i32(i32 %x, i32 %y)
407   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
408   ret i32 %r
411 define i32 @smin_known_zero(i32 %x, i32 %y) {
412 ; X86-LABEL: smin_known_zero:
413 ; X86:       # %bb.0:
414 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
415 ; X86-NEXT:    cmpl $-54, %eax
416 ; X86-NEXT:    movl $-54, %ecx
417 ; X86-NEXT:    cmovll %eax, %ecx
418 ; X86-NEXT:    rep bsfl %ecx, %eax
419 ; X86-NEXT:    retl
421 ; X64-LABEL: smin_known_zero:
422 ; X64:       # %bb.0:
423 ; X64-NEXT:    cmpl $-54, %edi
424 ; X64-NEXT:    movl $-54, %eax
425 ; X64-NEXT:    cmovll %edi, %eax
426 ; X64-NEXT:    rep bsfl %eax, %eax
427 ; X64-NEXT:    retq
428   %z = call i32 @llvm.smin.i32(i32 %x, i32 -54)
429   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
430   ret i32 %r
433 define <4 x i32> @smin_known_zero_vec(<4 x i32> %x, <4 x i32> %y) {
434 ; X86-LABEL: smin_known_zero_vec:
435 ; X86:       # %bb.0:
436 ; X86-NEXT:    movdqa {{.*#+}} xmm1 = [4294967242,4294967273,4294967284,4294967295]
437 ; X86-NEXT:    movdqa %xmm1, %xmm2
438 ; X86-NEXT:    pcmpgtd %xmm0, %xmm2
439 ; X86-NEXT:    pand %xmm2, %xmm0
440 ; X86-NEXT:    pandn %xmm1, %xmm2
441 ; X86-NEXT:    por %xmm2, %xmm0
442 ; X86-NEXT:    pcmpeqd %xmm1, %xmm1
443 ; X86-NEXT:    paddd %xmm0, %xmm1
444 ; X86-NEXT:    pand %xmm1, %xmm0
445 ; X86-NEXT:    pxor %xmm1, %xmm1
446 ; X86-NEXT:    pcmpeqd %xmm1, %xmm0
447 ; X86-NEXT:    psrld $31, %xmm0
448 ; X86-NEXT:    retl
450 ; X64-LABEL: smin_known_zero_vec:
451 ; X64:       # %bb.0:
452 ; X64-NEXT:    vpminsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
453 ; X64-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
454 ; X64-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
455 ; X64-NEXT:    vpand %xmm1, %xmm0, %xmm0
456 ; X64-NEXT:    vpxor %xmm1, %xmm1, %xmm1
457 ; X64-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
458 ; X64-NEXT:    vpsrld $31, %xmm0, %xmm0
459 ; X64-NEXT:    retq
460   %z = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %x, <4 x i32> <i32 -54, i32 -23, i32 -12, i32 -1>)
461   %r = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %z)
462   %3 = icmp eq <4 x i32> %r, <i32 1, i32 1, i32 1, i32 1>
463   %ret = zext <4 x i1> %3 to <4 x i32>
464   ret <4 x i32> %ret
467 define i32 @smin_maybe_zero(i32 %x, i32 %y) {
468 ; X86-LABEL: smin_maybe_zero:
469 ; X86:       # %bb.0:
470 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
471 ; X86-NEXT:    cmpl $54, %eax
472 ; X86-NEXT:    movl $54, %ecx
473 ; X86-NEXT:    cmovll %eax, %ecx
474 ; X86-NEXT:    bsfl %ecx, %ecx
475 ; X86-NEXT:    movl $32, %eax
476 ; X86-NEXT:    cmovnel %ecx, %eax
477 ; X86-NEXT:    retl
479 ; X64-LABEL: smin_maybe_zero:
480 ; X64:       # %bb.0:
481 ; X64-NEXT:    cmpl $54, %edi
482 ; X64-NEXT:    movl $54, %eax
483 ; X64-NEXT:    cmovll %edi, %eax
484 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
485 ; X64-NEXT:    orq %rax, %rcx
486 ; X64-NEXT:    rep bsfq %rcx, %rax
487 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
488 ; X64-NEXT:    retq
489   %z = call i32 @llvm.smin.i32(i32 %x, i32 54)
490   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
491   ret i32 %r
494 define i32 @smax_known_nonzero(i32 %xx, i32 %yy) {
495 ; X86-LABEL: smax_known_nonzero:
496 ; X86:       # %bb.0:
497 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
498 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
499 ; X86-NEXT:    movl $4, %edx
500 ; X86-NEXT:    shll %cl, %edx
501 ; X86-NEXT:    addl $4, %eax
502 ; X86-NEXT:    cmpl %eax, %edx
503 ; X86-NEXT:    cmovgl %edx, %eax
504 ; X86-NEXT:    rep bsfl %eax, %eax
505 ; X86-NEXT:    retl
507 ; X64-LABEL: smax_known_nonzero:
508 ; X64:       # %bb.0:
509 ; X64-NEXT:    movl %edi, %ecx
510 ; X64-NEXT:    movl $4, %eax
511 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
512 ; X64-NEXT:    shll %cl, %eax
513 ; X64-NEXT:    addl $4, %esi
514 ; X64-NEXT:    cmpl %esi, %eax
515 ; X64-NEXT:    cmovgl %eax, %esi
516 ; X64-NEXT:    rep bsfl %esi, %eax
517 ; X64-NEXT:    retq
518   %x = shl nuw i32 4, %xx
519   %y = add nuw nsw i32 %yy, 4
520   %z = call i32 @llvm.smax.i32(i32 %x, i32 %y)
521   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
522   ret i32 %r
525 define i32 @smax_maybe_zero(i32 %x, i32 %y) {
526 ; X86-LABEL: smax_maybe_zero:
527 ; X86:       # %bb.0:
528 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
529 ; X86-NEXT:    cmpl $55, %eax
530 ; X86-NEXT:    movl $54, %ecx
531 ; X86-NEXT:    cmovgel %eax, %ecx
532 ; X86-NEXT:    rep bsfl %ecx, %eax
533 ; X86-NEXT:    retl
535 ; X64-LABEL: smax_maybe_zero:
536 ; X64:       # %bb.0:
537 ; X64-NEXT:    cmpl $55, %edi
538 ; X64-NEXT:    movl $54, %eax
539 ; X64-NEXT:    cmovgel %edi, %eax
540 ; X64-NEXT:    rep bsfl %eax, %eax
541 ; X64-NEXT:    retq
542   %z = call i32 @llvm.smax.i32(i32 %x, i32 54)
543   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
544   ret i32 %r
547 define <4 x i32> @smax_known_zero_vec(<4 x i32> %x, <4 x i32> %y) {
548 ; X86-LABEL: smax_known_zero_vec:
549 ; X86:       # %bb.0:
550 ; X86-NEXT:    movdqa {{.*#+}} xmm1 = [54,23,12,1]
551 ; X86-NEXT:    movdqa %xmm0, %xmm2
552 ; X86-NEXT:    pcmpgtd %xmm1, %xmm2
553 ; X86-NEXT:    pand %xmm2, %xmm0
554 ; X86-NEXT:    pandn %xmm1, %xmm2
555 ; X86-NEXT:    por %xmm2, %xmm0
556 ; X86-NEXT:    pcmpeqd %xmm1, %xmm1
557 ; X86-NEXT:    paddd %xmm0, %xmm1
558 ; X86-NEXT:    pand %xmm1, %xmm0
559 ; X86-NEXT:    pxor %xmm1, %xmm1
560 ; X86-NEXT:    pcmpeqd %xmm1, %xmm0
561 ; X86-NEXT:    psrld $31, %xmm0
562 ; X86-NEXT:    retl
564 ; X64-LABEL: smax_known_zero_vec:
565 ; X64:       # %bb.0:
566 ; X64-NEXT:    vpmaxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
567 ; X64-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
568 ; X64-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
569 ; X64-NEXT:    vpand %xmm1, %xmm0, %xmm0
570 ; X64-NEXT:    vpxor %xmm1, %xmm1, %xmm1
571 ; X64-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
572 ; X64-NEXT:    vpsrld $31, %xmm0, %xmm0
573 ; X64-NEXT:    retq
574   %z = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %x, <4 x i32> <i32 54, i32 23, i32 12, i32 1>)
575   %r = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %z)
576   %3 = icmp eq <4 x i32> %r, <i32 1, i32 1, i32 1, i32 1>
577   %ret = zext <4 x i1> %3 to <4 x i32>
578   ret <4 x i32> %ret
581 define i32 @smax_known_zero(i32 %x, i32 %y) {
582 ; X86-LABEL: smax_known_zero:
583 ; X86:       # %bb.0:
584 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
585 ; X86-NEXT:    testl %eax, %eax
586 ; X86-NEXT:    movl $-1, %ecx
587 ; X86-NEXT:    cmovnsl %eax, %ecx
588 ; X86-NEXT:    bsfl %ecx, %ecx
589 ; X86-NEXT:    movl $32, %eax
590 ; X86-NEXT:    cmovnel %ecx, %eax
591 ; X86-NEXT:    retl
593 ; X64-LABEL: smax_known_zero:
594 ; X64:       # %bb.0:
595 ; X64-NEXT:    testl %edi, %edi
596 ; X64-NEXT:    movl $-1, %eax
597 ; X64-NEXT:    cmovnsl %edi, %eax
598 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
599 ; X64-NEXT:    orq %rax, %rcx
600 ; X64-NEXT:    rep bsfq %rcx, %rax
601 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
602 ; X64-NEXT:    retq
603   %z = call i32 @llvm.smax.i32(i32 %x, i32 -1)
604   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
605   ret i32 %r
608 define i32 @rotr_known_nonzero(i32 %xx, i32 %y) {
609 ; X86-LABEL: rotr_known_nonzero:
610 ; X86:       # %bb.0:
611 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
612 ; X86-NEXT:    movl $256, %eax # imm = 0x100
613 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
614 ; X86-NEXT:    rorl %cl, %eax
615 ; X86-NEXT:    rep bsfl %eax, %eax
616 ; X86-NEXT:    retl
618 ; X64-LABEL: rotr_known_nonzero:
619 ; X64:       # %bb.0:
620 ; X64-NEXT:    movl %esi, %ecx
621 ; X64-NEXT:    orl $256, %edi # imm = 0x100
622 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
623 ; X64-NEXT:    rorl %cl, %edi
624 ; X64-NEXT:    rep bsfl %edi, %eax
625 ; X64-NEXT:    retq
626   %x = or i32 %xx, 256
627   %shr = lshr i32 %x, %y
628   %sub = sub i32 32, %y
629   %shl = shl i32 %x, %sub
630   %z = or i32 %shl, %shr
631   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
632   ret i32 %r
635 define i32 @rotr_maybe_zero(i32 %x, i32 %y) {
636 ; X86-LABEL: rotr_maybe_zero:
637 ; X86:       # %bb.0:
638 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
639 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
640 ; X86-NEXT:    rorl %cl, %eax
641 ; X86-NEXT:    bsfl %eax, %ecx
642 ; X86-NEXT:    movl $32, %eax
643 ; X86-NEXT:    cmovnel %ecx, %eax
644 ; X86-NEXT:    retl
646 ; X64-LABEL: rotr_maybe_zero:
647 ; X64:       # %bb.0:
648 ; X64-NEXT:    movl %esi, %ecx
649 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
650 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
651 ; X64-NEXT:    rorl %cl, %edi
652 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
653 ; X64-NEXT:    orq %rdi, %rax
654 ; X64-NEXT:    rep bsfq %rax, %rax
655 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
656 ; X64-NEXT:    retq
657   %shr = lshr i32 %x, %y
658   %sub = sub i32 32, %y
659   %shl = shl i32 %x, %sub
660   %z = or i32 %shl, %shr
661   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
662   ret i32 %r
665 define i32 @rotr_with_fshr_known_nonzero(i32 %xx, i32 %y) {
666 ; X86-LABEL: rotr_with_fshr_known_nonzero:
667 ; X86:       # %bb.0:
668 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
669 ; X86-NEXT:    movl $256, %eax # imm = 0x100
670 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
671 ; X86-NEXT:    rorl %cl, %eax
672 ; X86-NEXT:    rep bsfl %eax, %eax
673 ; X86-NEXT:    retl
675 ; X64-LABEL: rotr_with_fshr_known_nonzero:
676 ; X64:       # %bb.0:
677 ; X64-NEXT:    movl %esi, %ecx
678 ; X64-NEXT:    orl $256, %edi # imm = 0x100
679 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
680 ; X64-NEXT:    rorl %cl, %edi
681 ; X64-NEXT:    rep bsfl %edi, %eax
682 ; X64-NEXT:    retq
683   %x = or i32 %xx, 256
684   %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
685   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
686   ret i32 %r
689 define i32 @rotr_with_fshr_maybe_zero(i32 %x, i32 %y) {
690 ; X86-LABEL: rotr_with_fshr_maybe_zero:
691 ; X86:       # %bb.0:
692 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
693 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
694 ; X86-NEXT:    rorl %cl, %eax
695 ; X86-NEXT:    bsfl %eax, %ecx
696 ; X86-NEXT:    movl $32, %eax
697 ; X86-NEXT:    cmovnel %ecx, %eax
698 ; X86-NEXT:    retl
700 ; X64-LABEL: rotr_with_fshr_maybe_zero:
701 ; X64:       # %bb.0:
702 ; X64-NEXT:    movl %esi, %ecx
703 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
704 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
705 ; X64-NEXT:    rorl %cl, %edi
706 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
707 ; X64-NEXT:    orq %rdi, %rax
708 ; X64-NEXT:    rep bsfq %rax, %rax
709 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
710 ; X64-NEXT:    retq
711   %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
712   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
713   ret i32 %r
716 define i32 @rotl_known_nonzero(i32 %xx, i32 %y) {
717 ; X86-LABEL: rotl_known_nonzero:
718 ; X86:       # %bb.0:
719 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
720 ; X86-NEXT:    movl $256, %eax # imm = 0x100
721 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
722 ; X86-NEXT:    roll %cl, %eax
723 ; X86-NEXT:    rep bsfl %eax, %eax
724 ; X86-NEXT:    retl
726 ; X64-LABEL: rotl_known_nonzero:
727 ; X64:       # %bb.0:
728 ; X64-NEXT:    movl %esi, %ecx
729 ; X64-NEXT:    orl $256, %edi # imm = 0x100
730 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
731 ; X64-NEXT:    roll %cl, %edi
732 ; X64-NEXT:    rep bsfl %edi, %eax
733 ; X64-NEXT:    retq
734   %x = or i32 %xx, 256
735   %shl = shl i32 %x, %y
736   %sub = sub i32 32, %y
737   %shr = lshr i32 %x, %sub
738   %z = or i32 %shr, %shl
739   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
740   ret i32 %r
743 define i32 @rotl_maybe_zero(i32 %x, i32 %y) {
744 ; X86-LABEL: rotl_maybe_zero:
745 ; X86:       # %bb.0:
746 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
747 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
748 ; X86-NEXT:    roll %cl, %eax
749 ; X86-NEXT:    bsfl %eax, %ecx
750 ; X86-NEXT:    movl $32, %eax
751 ; X86-NEXT:    cmovnel %ecx, %eax
752 ; X86-NEXT:    retl
754 ; X64-LABEL: rotl_maybe_zero:
755 ; X64:       # %bb.0:
756 ; X64-NEXT:    movl %esi, %ecx
757 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
758 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
759 ; X64-NEXT:    roll %cl, %edi
760 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
761 ; X64-NEXT:    orq %rdi, %rax
762 ; X64-NEXT:    rep bsfq %rax, %rax
763 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
764 ; X64-NEXT:    retq
765   %shl = shl i32 %x, %y
766   %sub = sub i32 32, %y
767   %shr = lshr i32 %x, %sub
768   %z = or i32 %shr, %shl
769   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
770   ret i32 %r
773 define i32 @rotl_with_fshl_known_nonzero(i32 %xx, i32 %y) {
774 ; X86-LABEL: rotl_with_fshl_known_nonzero:
775 ; X86:       # %bb.0:
776 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
777 ; X86-NEXT:    movl $256, %eax # imm = 0x100
778 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
779 ; X86-NEXT:    roll %cl, %eax
780 ; X86-NEXT:    rep bsfl %eax, %eax
781 ; X86-NEXT:    retl
783 ; X64-LABEL: rotl_with_fshl_known_nonzero:
784 ; X64:       # %bb.0:
785 ; X64-NEXT:    movl %esi, %ecx
786 ; X64-NEXT:    orl $256, %edi # imm = 0x100
787 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
788 ; X64-NEXT:    roll %cl, %edi
789 ; X64-NEXT:    rep bsfl %edi, %eax
790 ; X64-NEXT:    retq
791   %x = or i32 %xx, 256
792   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)
793   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
794   ret i32 %r
797 define i32 @rotl_with_fshl_maybe_zero(i32 %x, i32 %y) {
798 ; X86-LABEL: rotl_with_fshl_maybe_zero:
799 ; X86:       # %bb.0:
800 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
801 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
802 ; X86-NEXT:    roll %cl, %eax
803 ; X86-NEXT:    bsfl %eax, %ecx
804 ; X86-NEXT:    movl $32, %eax
805 ; X86-NEXT:    cmovnel %ecx, %eax
806 ; X86-NEXT:    retl
808 ; X64-LABEL: rotl_with_fshl_maybe_zero:
809 ; X64:       # %bb.0:
810 ; X64-NEXT:    movl %esi, %ecx
811 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
812 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
813 ; X64-NEXT:    roll %cl, %edi
814 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
815 ; X64-NEXT:    orq %rdi, %rax
816 ; X64-NEXT:    rep bsfq %rax, %rax
817 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
818 ; X64-NEXT:    retq
819   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)
820   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
821   ret i32 %r
824 define i32 @sra_known_nonzero_sign_bit_set(i32 %x) {
825 ; X86-LABEL: sra_known_nonzero_sign_bit_set:
826 ; X86:       # %bb.0:
827 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
828 ; X86-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
829 ; X86-NEXT:    sarl %cl, %eax
830 ; X86-NEXT:    rep bsfl %eax, %eax
831 ; X86-NEXT:    retl
833 ; X64-LABEL: sra_known_nonzero_sign_bit_set:
834 ; X64:       # %bb.0:
835 ; X64-NEXT:    movl %edi, %ecx
836 ; X64-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
837 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
838 ; X64-NEXT:    sarl %cl, %eax
839 ; X64-NEXT:    rep bsfl %eax, %eax
840 ; X64-NEXT:    retq
841   %z = ashr i32 2147606891, %x
842   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
843   ret i32 %r
846 define i32 @sra_known_nonzero_exact(i32 %x, i32 %yy) {
847 ; X86-LABEL: sra_known_nonzero_exact:
848 ; X86:       # %bb.0:
849 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
850 ; X86-NEXT:    movl $256, %eax # imm = 0x100
851 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
852 ; X86-NEXT:    sarl %cl, %eax
853 ; X86-NEXT:    rep bsfl %eax, %eax
854 ; X86-NEXT:    retl
856 ; X64-LABEL: sra_known_nonzero_exact:
857 ; X64:       # %bb.0:
858 ; X64-NEXT:    movl %edi, %ecx
859 ; X64-NEXT:    orl $256, %esi # imm = 0x100
860 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
861 ; X64-NEXT:    sarl %cl, %esi
862 ; X64-NEXT:    rep bsfl %esi, %eax
863 ; X64-NEXT:    retq
864   %y = or i32 %yy, 256
865   %z = ashr exact i32 %y, %x
866   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
867   ret i32 %r
870 define i32 @sra_maybe_zero(i32 %x, i32 %y) {
871 ; X86-LABEL: sra_maybe_zero:
872 ; X86:       # %bb.0:
873 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
874 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
875 ; X86-NEXT:    sarl %cl, %eax
876 ; X86-NEXT:    bsfl %eax, %ecx
877 ; X86-NEXT:    movl $32, %eax
878 ; X86-NEXT:    cmovnel %ecx, %eax
879 ; X86-NEXT:    retl
881 ; X64-LABEL: sra_maybe_zero:
882 ; X64:       # %bb.0:
883 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
884 ; X64-NEXT:    movl %edi, %ecx
885 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
886 ; X64-NEXT:    sarl %cl, %esi
887 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
888 ; X64-NEXT:    orq %rsi, %rax
889 ; X64-NEXT:    rep bsfq %rax, %rax
890 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
891 ; X64-NEXT:    retq
892   %z = ashr exact i32 %y, %x
893   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
894   ret i32 %r
897 define i32 @srl_known_nonzero_sign_bit_set(i32 %x) {
898 ; X86-LABEL: srl_known_nonzero_sign_bit_set:
899 ; X86:       # %bb.0:
900 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
901 ; X86-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
902 ; X86-NEXT:    shrl %cl, %eax
903 ; X86-NEXT:    rep bsfl %eax, %eax
904 ; X86-NEXT:    retl
906 ; X64-LABEL: srl_known_nonzero_sign_bit_set:
907 ; X64:       # %bb.0:
908 ; X64-NEXT:    movl %edi, %ecx
909 ; X64-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
910 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
911 ; X64-NEXT:    shrl %cl, %eax
912 ; X64-NEXT:    rep bsfl %eax, %eax
913 ; X64-NEXT:    retq
914   %z = lshr i32 2147606891, %x
915   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
916   ret i32 %r
919 define i32 @srl_known_nonzero_exact(i32 %x, i32 %yy) {
920 ; X86-LABEL: srl_known_nonzero_exact:
921 ; X86:       # %bb.0:
922 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
923 ; X86-NEXT:    movl $256, %eax # imm = 0x100
924 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
925 ; X86-NEXT:    shrl %cl, %eax
926 ; X86-NEXT:    rep bsfl %eax, %eax
927 ; X86-NEXT:    retl
929 ; X64-LABEL: srl_known_nonzero_exact:
930 ; X64:       # %bb.0:
931 ; X64-NEXT:    movl %edi, %ecx
932 ; X64-NEXT:    orl $256, %esi # imm = 0x100
933 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
934 ; X64-NEXT:    shrl %cl, %esi
935 ; X64-NEXT:    rep bsfl %esi, %eax
936 ; X64-NEXT:    retq
937   %y = or i32 %yy, 256
938   %z = lshr exact i32 %y, %x
939   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
940   ret i32 %r
943 define i32 @srl_maybe_zero(i32 %x, i32 %y) {
944 ; X86-LABEL: srl_maybe_zero:
945 ; X86:       # %bb.0:
946 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
947 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
948 ; X86-NEXT:    shrl %cl, %eax
949 ; X86-NEXT:    bsfl %eax, %ecx
950 ; X86-NEXT:    movl $32, %eax
951 ; X86-NEXT:    cmovnel %ecx, %eax
952 ; X86-NEXT:    retl
954 ; X64-LABEL: srl_maybe_zero:
955 ; X64:       # %bb.0:
956 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
957 ; X64-NEXT:    movl %edi, %ecx
958 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
959 ; X64-NEXT:    shrl %cl, %esi
960 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
961 ; X64-NEXT:    orq %rsi, %rax
962 ; X64-NEXT:    rep bsfq %rax, %rax
963 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
964 ; X64-NEXT:    retq
965   %z = lshr exact i32 %y, %x
966   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
967   ret i32 %r
970 define i32 @udiv_known_nonzero(i32 %xx, i32 %y) {
971 ; X86-LABEL: udiv_known_nonzero:
972 ; X86:       # %bb.0:
973 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
974 ; X86-NEXT:    orl $64, %eax
975 ; X86-NEXT:    xorl %edx, %edx
976 ; X86-NEXT:    divl {{[0-9]+}}(%esp)
977 ; X86-NEXT:    rep bsfl %eax, %eax
978 ; X86-NEXT:    retl
980 ; X64-LABEL: udiv_known_nonzero:
981 ; X64:       # %bb.0:
982 ; X64-NEXT:    movl %edi, %eax
983 ; X64-NEXT:    orl $64, %eax
984 ; X64-NEXT:    xorl %edx, %edx
985 ; X64-NEXT:    divl %esi
986 ; X64-NEXT:    rep bsfl %eax, %eax
987 ; X64-NEXT:    retq
988   %x = or i32 %xx, 64
989   %z = udiv exact i32 %x, %y
990   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
991   ret i32 %r
994 define i32 @udiv_maybe_zero(i32 %x, i32 %y) {
995 ; X86-LABEL: udiv_maybe_zero:
996 ; X86:       # %bb.0:
997 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
998 ; X86-NEXT:    xorl %edx, %edx
999 ; X86-NEXT:    divl {{[0-9]+}}(%esp)
1000 ; X86-NEXT:    bsfl %eax, %ecx
1001 ; X86-NEXT:    movl $32, %eax
1002 ; X86-NEXT:    cmovnel %ecx, %eax
1003 ; X86-NEXT:    retl
1005 ; X64-LABEL: udiv_maybe_zero:
1006 ; X64:       # %bb.0:
1007 ; X64-NEXT:    movl %edi, %eax
1008 ; X64-NEXT:    xorl %edx, %edx
1009 ; X64-NEXT:    divl %esi
1010 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
1011 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1012 ; X64-NEXT:    orq %rax, %rcx
1013 ; X64-NEXT:    rep bsfq %rcx, %rax
1014 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1015 ; X64-NEXT:    retq
1016   %z = udiv exact i32 %x, %y
1017   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1018   ret i32 %r
1021 define i32 @sdiv_known_nonzero(i32 %xx, i32 %y) {
1022 ; X86-LABEL: sdiv_known_nonzero:
1023 ; X86:       # %bb.0:
1024 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1025 ; X86-NEXT:    orl $64, %eax
1026 ; X86-NEXT:    cltd
1027 ; X86-NEXT:    idivl {{[0-9]+}}(%esp)
1028 ; X86-NEXT:    rep bsfl %eax, %eax
1029 ; X86-NEXT:    retl
1031 ; X64-LABEL: sdiv_known_nonzero:
1032 ; X64:       # %bb.0:
1033 ; X64-NEXT:    movl %edi, %eax
1034 ; X64-NEXT:    orl $64, %eax
1035 ; X64-NEXT:    cltd
1036 ; X64-NEXT:    idivl %esi
1037 ; X64-NEXT:    rep bsfl %eax, %eax
1038 ; X64-NEXT:    retq
1039   %x = or i32 %xx, 64
1040   %z = sdiv exact i32 %x, %y
1041   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1042   ret i32 %r
1045 define i32 @sdiv_maybe_zero(i32 %x, i32 %y) {
1046 ; X86-LABEL: sdiv_maybe_zero:
1047 ; X86:       # %bb.0:
1048 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1049 ; X86-NEXT:    cltd
1050 ; X86-NEXT:    idivl {{[0-9]+}}(%esp)
1051 ; X86-NEXT:    bsfl %eax, %ecx
1052 ; X86-NEXT:    movl $32, %eax
1053 ; X86-NEXT:    cmovnel %ecx, %eax
1054 ; X86-NEXT:    retl
1056 ; X64-LABEL: sdiv_maybe_zero:
1057 ; X64:       # %bb.0:
1058 ; X64-NEXT:    movl %edi, %eax
1059 ; X64-NEXT:    cltd
1060 ; X64-NEXT:    idivl %esi
1061 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
1062 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1063 ; X64-NEXT:    orq %rax, %rcx
1064 ; X64-NEXT:    rep bsfq %rcx, %rax
1065 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1066 ; X64-NEXT:    retq
1067   %z = sdiv exact i32 %x, %y
1068   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1069   ret i32 %r
1072 define i32 @add_known_nonzero(i32 %xx, i32 %y) {
1073 ; X86-LABEL: add_known_nonzero:
1074 ; X86:       # %bb.0:
1075 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1076 ; X86-NEXT:    orl $1, %eax
1077 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
1078 ; X86-NEXT:    rep bsfl %eax, %eax
1079 ; X86-NEXT:    retl
1081 ; X64-LABEL: add_known_nonzero:
1082 ; X64:       # %bb.0:
1083 ; X64-NEXT:    orl $1, %edi
1084 ; X64-NEXT:    addl %esi, %edi
1085 ; X64-NEXT:    rep bsfl %edi, %eax
1086 ; X64-NEXT:    retq
1087   %x = or i32 %xx, 1
1088   %z = add nuw i32 %x, %y
1089   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1090   ret i32 %r
1093 define i32 @add_maybe_zero(i32 %xx, i32 %y) {
1094 ; X86-LABEL: add_maybe_zero:
1095 ; X86:       # %bb.0:
1096 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1097 ; X86-NEXT:    orl $1, %eax
1098 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
1099 ; X86-NEXT:    bsfl %eax, %ecx
1100 ; X86-NEXT:    movl $32, %eax
1101 ; X86-NEXT:    cmovnel %ecx, %eax
1102 ; X86-NEXT:    retl
1104 ; X64-LABEL: add_maybe_zero:
1105 ; X64:       # %bb.0:
1106 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1107 ; X64-NEXT:    orl $1, %edi
1108 ; X64-NEXT:    addl %esi, %edi
1109 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
1110 ; X64-NEXT:    orq %rdi, %rax
1111 ; X64-NEXT:    rep bsfq %rax, %rax
1112 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1113 ; X64-NEXT:    retq
1114   %x = or i32 %xx, 1
1115   %z = add nsw i32 %x, %y
1116   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1117   ret i32 %r
1120 define i32 @sub_known_nonzero_neg_case(i32 %xx) {
1121 ; X86-LABEL: sub_known_nonzero_neg_case:
1122 ; X86:       # %bb.0:
1123 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1124 ; X86-NEXT:    movl $256, %eax # imm = 0x100
1125 ; X86-NEXT:    shll %cl, %eax
1126 ; X86-NEXT:    negl %eax
1127 ; X86-NEXT:    rep bsfl %eax, %eax
1128 ; X86-NEXT:    retl
1130 ; X64-LABEL: sub_known_nonzero_neg_case:
1131 ; X64:       # %bb.0:
1132 ; X64-NEXT:    movl %edi, %ecx
1133 ; X64-NEXT:    movl $256, %eax # imm = 0x100
1134 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1135 ; X64-NEXT:    shll %cl, %eax
1136 ; X64-NEXT:    negl %eax
1137 ; X64-NEXT:    rep bsfl %eax, %eax
1138 ; X64-NEXT:    retq
1139   %x = shl nuw nsw i32 256, %xx
1140   %z = sub i32 0, %x
1141   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1142   ret i32 %r
1145 define i32 @sub_known_nonzero_ne_case(i32 %xx, i32 %yy) {
1146 ; X86-LABEL: sub_known_nonzero_ne_case:
1147 ; X86:       # %bb.0:
1148 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1149 ; X86-NEXT:    movl %eax, %ecx
1150 ; X86-NEXT:    orl $64, %ecx
1151 ; X86-NEXT:    andl $-65, %eax
1152 ; X86-NEXT:    subl %ecx, %eax
1153 ; X86-NEXT:    rep bsfl %eax, %eax
1154 ; X86-NEXT:    retl
1156 ; X64-LABEL: sub_known_nonzero_ne_case:
1157 ; X64:       # %bb.0:
1158 ; X64-NEXT:    movl %edi, %eax
1159 ; X64-NEXT:    orl $64, %eax
1160 ; X64-NEXT:    andl $-65, %edi
1161 ; X64-NEXT:    subl %eax, %edi
1162 ; X64-NEXT:    rep bsfl %edi, %eax
1163 ; X64-NEXT:    retq
1164   %x = or i32 %xx, 64
1165   %y = and i32 %xx, -65
1166   %z = sub i32 %y, %x
1167   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1168   ret i32 %r
1171 define i32 @sub_maybe_zero(i32 %x) {
1172 ; X86-LABEL: sub_maybe_zero:
1173 ; X86:       # %bb.0:
1174 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1175 ; X86-NEXT:    movl %eax, %ecx
1176 ; X86-NEXT:    orl $64, %ecx
1177 ; X86-NEXT:    subl %eax, %ecx
1178 ; X86-NEXT:    bsfl %ecx, %ecx
1179 ; X86-NEXT:    movl $32, %eax
1180 ; X86-NEXT:    cmovnel %ecx, %eax
1181 ; X86-NEXT:    retl
1183 ; X64-LABEL: sub_maybe_zero:
1184 ; X64:       # %bb.0:
1185 ; X64-NEXT:    movl %edi, %eax
1186 ; X64-NEXT:    orl $64, %eax
1187 ; X64-NEXT:    subl %edi, %eax
1188 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1189 ; X64-NEXT:    orq %rax, %rcx
1190 ; X64-NEXT:    rep bsfq %rcx, %rax
1191 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1192 ; X64-NEXT:    retq
1193   %y = or i32 %x, 64
1194   %z = sub i32 %y, %x
1195   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1196   ret i32 %r
1199 define i32 @sub_maybe_zero2(i32 %x) {
1200 ; X86-LABEL: sub_maybe_zero2:
1201 ; X86:       # %bb.0:
1202 ; X86-NEXT:    xorl %eax, %eax
1203 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
1204 ; X86-NEXT:    bsfl %eax, %ecx
1205 ; X86-NEXT:    movl $32, %eax
1206 ; X86-NEXT:    cmovnel %ecx, %eax
1207 ; X86-NEXT:    retl
1209 ; X64-LABEL: sub_maybe_zero2:
1210 ; X64:       # %bb.0:
1211 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1212 ; X64-NEXT:    negl %edi
1213 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
1214 ; X64-NEXT:    orq %rdi, %rax
1215 ; X64-NEXT:    rep bsfq %rax, %rax
1216 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1217 ; X64-NEXT:    retq
1218   %z = sub i32 0, %x
1219   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1220   ret i32 %r
1223 define i32 @mul_known_nonzero_nsw(i32 %x, i32 %yy) {
1224 ; X86-LABEL: mul_known_nonzero_nsw:
1225 ; X86:       # %bb.0:
1226 ; X86-NEXT:    movl $256, %eax # imm = 0x100
1227 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
1228 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %eax
1229 ; X86-NEXT:    bsfl %eax, %ecx
1230 ; X86-NEXT:    movl $32, %eax
1231 ; X86-NEXT:    cmovnel %ecx, %eax
1232 ; X86-NEXT:    retl
1234 ; X64-LABEL: mul_known_nonzero_nsw:
1235 ; X64:       # %bb.0:
1236 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
1237 ; X64-NEXT:    orl $256, %esi # imm = 0x100
1238 ; X64-NEXT:    imull %edi, %esi
1239 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
1240 ; X64-NEXT:    orq %rsi, %rax
1241 ; X64-NEXT:    rep bsfq %rax, %rax
1242 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1243 ; X64-NEXT:    retq
1244   %y = or i32 %yy, 256
1245   %z = mul nsw i32 %y, %x
1246   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1247   ret i32 %r
1250 define i32 @mul_known_nonzero_nuw(i32 %x, i32 %yy) {
1251 ; X86-LABEL: mul_known_nonzero_nuw:
1252 ; X86:       # %bb.0:
1253 ; X86-NEXT:    movl $256, %eax # imm = 0x100
1254 ; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax
1255 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %eax
1256 ; X86-NEXT:    bsfl %eax, %ecx
1257 ; X86-NEXT:    movl $32, %eax
1258 ; X86-NEXT:    cmovnel %ecx, %eax
1259 ; X86-NEXT:    retl
1261 ; X64-LABEL: mul_known_nonzero_nuw:
1262 ; X64:       # %bb.0:
1263 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
1264 ; X64-NEXT:    orl $256, %esi # imm = 0x100
1265 ; X64-NEXT:    imull %edi, %esi
1266 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
1267 ; X64-NEXT:    orq %rsi, %rax
1268 ; X64-NEXT:    rep bsfq %rax, %rax
1269 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1270 ; X64-NEXT:    retq
1271   %y = or i32 %yy, 256
1272   %z = mul nuw i32 %y, %x
1273   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1274   ret i32 %r
1277 define i32 @mul_maybe_zero(i32 %x, i32 %y) {
1278 ; X86-LABEL: mul_maybe_zero:
1279 ; X86:       # %bb.0:
1280 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1281 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %eax
1282 ; X86-NEXT:    bsfl %eax, %ecx
1283 ; X86-NEXT:    movl $32, %eax
1284 ; X86-NEXT:    cmovnel %ecx, %eax
1285 ; X86-NEXT:    retl
1287 ; X64-LABEL: mul_maybe_zero:
1288 ; X64:       # %bb.0:
1289 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1290 ; X64-NEXT:    imull %esi, %edi
1291 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
1292 ; X64-NEXT:    orq %rdi, %rax
1293 ; X64-NEXT:    rep bsfq %rax, %rax
1294 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1295 ; X64-NEXT:    retq
1296   %z = mul nuw nsw i32 %y, %x
1297   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1298   ret i32 %r
1301 define i32 @bitcast_known_nonzero(<2 x i16> %xx) {
1302 ; X86-LABEL: bitcast_known_nonzero:
1303 ; X86:       # %bb.0:
1304 ; X86-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1305 ; X86-NEXT:    pslld $23, %xmm0
1306 ; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
1307 ; X86-NEXT:    cvttps2dq %xmm0, %xmm0
1308 ; X86-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
1309 ; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 # [256,256,u,u,u,u,u,u]
1310 ; X86-NEXT:    movd %xmm0, %eax
1311 ; X86-NEXT:    bsfl %eax, %ecx
1312 ; X86-NEXT:    movl $32, %eax
1313 ; X86-NEXT:    cmovnel %ecx, %eax
1314 ; X86-NEXT:    retl
1316 ; X64-LABEL: bitcast_known_nonzero:
1317 ; X64:       # %bb.0:
1318 ; X64-NEXT:    vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
1319 ; X64-NEXT:    vpslld $23, %xmm0, %xmm0
1320 ; X64-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
1321 ; X64-NEXT:    vcvttps2dq %xmm0, %xmm0
1322 ; X64-NEXT:    vpackusdw %xmm0, %xmm0, %xmm0
1323 ; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [256,256,u,u,u,u,u,u]
1324 ; X64-NEXT:    vmovd %xmm0, %eax
1325 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1326 ; X64-NEXT:    orq %rax, %rcx
1327 ; X64-NEXT:    rep bsfq %rcx, %rax
1328 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1329 ; X64-NEXT:    retq
1330   %x = shl nuw nsw <2 x i16> <i16 256, i16 256>, %xx
1331   %z = bitcast <2 x i16> %x to i32
1332   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1333   ret i32 %r
1336 define i32 @bitcast_maybe_zero(<2 x i16> %x) {
1337 ; X86-LABEL: bitcast_maybe_zero:
1338 ; X86:       # %bb.0:
1339 ; X86-NEXT:    movd %xmm0, %eax
1340 ; X86-NEXT:    bsfl %eax, %ecx
1341 ; X86-NEXT:    movl $32, %eax
1342 ; X86-NEXT:    cmovnel %ecx, %eax
1343 ; X86-NEXT:    retl
1345 ; X64-LABEL: bitcast_maybe_zero:
1346 ; X64:       # %bb.0:
1347 ; X64-NEXT:    vmovd %xmm0, %eax
1348 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1349 ; X64-NEXT:    orq %rax, %rcx
1350 ; X64-NEXT:    rep bsfq %rcx, %rax
1351 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1352 ; X64-NEXT:    retq
1353   %z = bitcast <2 x i16> %x to i32
1354   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1355   ret i32 %r
1358 define i32 @bitcast_from_float(float %x) {
1359 ; X86-LABEL: bitcast_from_float:
1360 ; X86:       # %bb.0:
1361 ; X86-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx
1362 ; X86-NEXT:    movl $32, %eax
1363 ; X86-NEXT:    cmovnel %ecx, %eax
1364 ; X86-NEXT:    retl
1366 ; X64-LABEL: bitcast_from_float:
1367 ; X64:       # %bb.0:
1368 ; X64-NEXT:    vmovd %xmm0, %eax
1369 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1370 ; X64-NEXT:    orq %rax, %rcx
1371 ; X64-NEXT:    rep bsfq %rcx, %rax
1372 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1373 ; X64-NEXT:    retq
1374   %z = bitcast float %x to i32
1375   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1376   ret i32 %r
1379 define i32 @zext_known_nonzero(i16 %xx) {
1380 ; X86-LABEL: zext_known_nonzero:
1381 ; X86:       # %bb.0:
1382 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1383 ; X86-NEXT:    movl $256, %eax # imm = 0x100
1384 ; X86-NEXT:    shll %cl, %eax
1385 ; X86-NEXT:    movzwl %ax, %eax
1386 ; X86-NEXT:    rep bsfl %eax, %eax
1387 ; X86-NEXT:    retl
1389 ; X64-LABEL: zext_known_nonzero:
1390 ; X64:       # %bb.0:
1391 ; X64-NEXT:    movl %edi, %ecx
1392 ; X64-NEXT:    movl $256, %eax # imm = 0x100
1393 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1394 ; X64-NEXT:    shll %cl, %eax
1395 ; X64-NEXT:    movzwl %ax, %eax
1396 ; X64-NEXT:    rep bsfl %eax, %eax
1397 ; X64-NEXT:    retq
1398   %x = shl nuw nsw i16 256, %xx
1399   %z = zext i16 %x to i32
1400   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1401   ret i32 %r
1404 define i32 @zext_maybe_zero(i16 %x) {
1405 ; X86-LABEL: zext_maybe_zero:
1406 ; X86:       # %bb.0:
1407 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1408 ; X86-NEXT:    bsfl %eax, %ecx
1409 ; X86-NEXT:    movl $32, %eax
1410 ; X86-NEXT:    cmovnel %ecx, %eax
1411 ; X86-NEXT:    retl
1413 ; X64-LABEL: zext_maybe_zero:
1414 ; X64:       # %bb.0:
1415 ; X64-NEXT:    movzwl %di, %eax
1416 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1417 ; X64-NEXT:    orq %rax, %rcx
1418 ; X64-NEXT:    rep bsfq %rcx, %rax
1419 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1420 ; X64-NEXT:    retq
1421   %z = zext i16 %x to i32
1422   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1423   ret i32 %r
1426 define i32 @sext_known_nonzero(i16 %xx) {
1427 ; X86-LABEL: sext_known_nonzero:
1428 ; X86:       # %bb.0:
1429 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1430 ; X86-NEXT:    movl $256, %eax # imm = 0x100
1431 ; X86-NEXT:    shll %cl, %eax
1432 ; X86-NEXT:    movzwl %ax, %eax
1433 ; X86-NEXT:    rep bsfl %eax, %eax
1434 ; X86-NEXT:    retl
1436 ; X64-LABEL: sext_known_nonzero:
1437 ; X64:       # %bb.0:
1438 ; X64-NEXT:    movl %edi, %ecx
1439 ; X64-NEXT:    movl $256, %eax # imm = 0x100
1440 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1441 ; X64-NEXT:    shll %cl, %eax
1442 ; X64-NEXT:    movzwl %ax, %eax
1443 ; X64-NEXT:    rep bsfl %eax, %eax
1444 ; X64-NEXT:    retq
1445   %x = shl nuw nsw i16 256, %xx
1446   %z = sext i16 %x to i32
1447   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1448   ret i32 %r
1451 define i32 @sext_maybe_zero(i16 %x) {
1452 ; X86-LABEL: sext_maybe_zero:
1453 ; X86:       # %bb.0:
1454 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
1455 ; X86-NEXT:    bsfl %eax, %ecx
1456 ; X86-NEXT:    movl $32, %eax
1457 ; X86-NEXT:    cmovnel %ecx, %eax
1458 ; X86-NEXT:    retl
1460 ; X64-LABEL: sext_maybe_zero:
1461 ; X64:       # %bb.0:
1462 ; X64-NEXT:    movswl %di, %eax
1463 ; X64-NEXT:    movabsq $4294967296, %rcx # imm = 0x100000000
1464 ; X64-NEXT:    orq %rax, %rcx
1465 ; X64-NEXT:    rep bsfq %rcx, %rax
1466 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
1467 ; X64-NEXT:    retq
1468   %z = sext i16 %x to i32
1469   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
1470   ret i32 %r