Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / known-never-zero.ll
blobcc9862769f2b66de341cf030e1ec6fe95f426912
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=CHECK
4 ;; Use cttz to test if we properly prove never-zero. There is a very
5 ;; simple transform from cttz -> cttz_zero_undef if its operand is
6 ;; known never zero.
7 declare i32 @llvm.cttz.i32(i32, i1)
8 declare i32 @llvm.uadd.sat.i32(i32, i32)
9 declare i32 @llvm.umax.i32(i32, i32)
10 declare i32 @llvm.umin.i32(i32, i32)
11 declare i32 @llvm.smin.i32(i32, i32)
12 declare i32 @llvm.smax.i32(i32, i32)
13 declare i32 @llvm.bswap.i32(i32)
14 declare i32 @llvm.bitreverse.i32(i32)
15 declare i32 @llvm.ctpop.i32(i32)
16 declare i32 @llvm.abs.i32(i32, i1)
17 declare i32 @llvm.fshl.i32(i32, i32, i32)
18 declare i32 @llvm.fshr.i32(i32, i32, i32)
20 define i32 @or_known_nonzero(i32 %x) {
21 ; CHECK-LABEL: or_known_nonzero:
22 ; CHECK:       # %bb.0:
23 ; CHECK-NEXT:    orl $1, %edi
24 ; CHECK-NEXT:    rep bsfl %edi, %eax
25 ; CHECK-NEXT:    retq
26   %z = or i32 %x, 1
27   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
28   ret i32 %r
31 define i32 @or_maybe_zero(i32 %x, i32 %y) {
32 ; CHECK-LABEL: or_maybe_zero:
33 ; CHECK:       # %bb.0:
34 ; CHECK-NEXT:    orl %esi, %edi
35 ; CHECK-NEXT:    je .LBB1_1
36 ; CHECK-NEXT:  # %bb.2: # %cond.false
37 ; CHECK-NEXT:    rep bsfl %edi, %eax
38 ; CHECK-NEXT:    retq
39 ; CHECK-NEXT:  .LBB1_1:
40 ; CHECK-NEXT:    movl $32, %eax
41 ; CHECK-NEXT:    retq
42   %z = or i32 %x, %y
43   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
44   ret i32 %r
47 define i32 @select_known_nonzero(i1 %c, i32 %x) {
48 ; CHECK-LABEL: select_known_nonzero:
49 ; CHECK:       # %bb.0:
50 ; CHECK-NEXT:    orl $1, %esi
51 ; CHECK-NEXT:    testb $1, %dil
52 ; CHECK-NEXT:    movl $122, %eax
53 ; CHECK-NEXT:    cmovnel %esi, %eax
54 ; CHECK-NEXT:    rep bsfl %eax, %eax
55 ; CHECK-NEXT:    retq
56   %y = or i32 %x, 1
57   %z = select i1 %c, i32 %y, i32 122
58   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
59   ret i32 %r
62 define i32 @select_maybe_zero(i1 %c, i32 %x) {
63 ; CHECK-LABEL: select_maybe_zero:
64 ; CHECK:       # %bb.0:
65 ; CHECK-NEXT:    orl $1, %esi
66 ; CHECK-NEXT:    xorl %eax, %eax
67 ; CHECK-NEXT:    testb $1, %dil
68 ; CHECK-NEXT:    cmovnel %esi, %eax
69 ; CHECK-NEXT:    testl %eax, %eax
70 ; CHECK-NEXT:    je .LBB3_1
71 ; CHECK-NEXT:  # %bb.2: # %cond.false
72 ; CHECK-NEXT:    rep bsfl %eax, %eax
73 ; CHECK-NEXT:    retq
74 ; CHECK-NEXT:  .LBB3_1:
75 ; CHECK-NEXT:    movl $32, %eax
76 ; CHECK-NEXT:    retq
77   %y = or i32 %x, 1
78   %z = select i1 %c, i32 %y, i32 0
79   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
80   ret i32 %r
83 define i32 @shl_known_nonzero_1s_bit_set(i32 %x) {
84 ; CHECK-LABEL: shl_known_nonzero_1s_bit_set:
85 ; CHECK:       # %bb.0:
86 ; CHECK-NEXT:    movl %edi, %ecx
87 ; CHECK-NEXT:    movl $123, %eax
88 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
89 ; CHECK-NEXT:    shll %cl, %eax
90 ; CHECK-NEXT:    rep bsfl %eax, %eax
91 ; CHECK-NEXT:    retq
92   %z = shl i32 123, %x
93   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
94   ret i32 %r
97 define i32 @shl_known_nonzero_nsw(i32 %x, i32 %yy) {
98 ; CHECK-LABEL: shl_known_nonzero_nsw:
99 ; CHECK:       # %bb.0:
100 ; CHECK-NEXT:    movl %edi, %ecx
101 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
102 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
103 ; CHECK-NEXT:    shll %cl, %esi
104 ; CHECK-NEXT:    rep bsfl %esi, %eax
105 ; CHECK-NEXT:    retq
106   %y = or i32 %yy, 256
107   %z = shl nsw i32 %y, %x
108   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
109   ret i32 %r
112 define i32 @shl_known_nonzero_nuw(i32 %x, i32 %yy) {
113 ; CHECK-LABEL: shl_known_nonzero_nuw:
114 ; CHECK:       # %bb.0:
115 ; CHECK-NEXT:    movl %edi, %ecx
116 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
117 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
118 ; CHECK-NEXT:    shll %cl, %esi
119 ; CHECK-NEXT:    rep bsfl %esi, %eax
120 ; CHECK-NEXT:    retq
121   %y = or i32 %yy, 256
122   %z = shl nuw i32 %y, %x
123   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
124   ret i32 %r
127 define i32 @shl_maybe_zero(i32 %x, i32 %y) {
128 ; CHECK-LABEL: shl_maybe_zero:
129 ; CHECK:       # %bb.0:
130 ; CHECK-NEXT:    movl %edi, %ecx
131 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
132 ; CHECK-NEXT:    shll %cl, %esi
133 ; CHECK-NEXT:    testl %esi, %esi
134 ; CHECK-NEXT:    je .LBB7_1
135 ; CHECK-NEXT:  # %bb.2: # %cond.false
136 ; CHECK-NEXT:    rep bsfl %esi, %eax
137 ; CHECK-NEXT:    retq
138 ; CHECK-NEXT:  .LBB7_1:
139 ; CHECK-NEXT:    movl $32, %eax
140 ; CHECK-NEXT:    retq
141   %z = shl nuw nsw i32 %y, %x
142   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
143   ret i32 %r
146 define i32 @uaddsat_known_nonzero(i32 %x) {
147 ; CHECK-LABEL: uaddsat_known_nonzero:
148 ; CHECK:       # %bb.0:
149 ; CHECK-NEXT:    incl %edi
150 ; CHECK-NEXT:    movl $-1, %eax
151 ; CHECK-NEXT:    cmovnel %edi, %eax
152 ; CHECK-NEXT:    rep bsfl %eax, %eax
153 ; CHECK-NEXT:    retq
154   %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 1)
155   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
156   ret i32 %r
159 define i32 @uaddsat_maybe_zero(i32 %x, i32 %y) {
160 ; CHECK-LABEL: uaddsat_maybe_zero:
161 ; CHECK:       # %bb.0:
162 ; CHECK-NEXT:    addl %esi, %edi
163 ; CHECK-NEXT:    movl $-1, %eax
164 ; CHECK-NEXT:    cmovael %edi, %eax
165 ; CHECK-NEXT:    testl %eax, %eax
166 ; CHECK-NEXT:    je .LBB9_1
167 ; CHECK-NEXT:  # %bb.2: # %cond.false
168 ; CHECK-NEXT:    rep bsfl %eax, %eax
169 ; CHECK-NEXT:    retq
170 ; CHECK-NEXT:  .LBB9_1:
171 ; CHECK-NEXT:    movl $32, %eax
172 ; CHECK-NEXT:    retq
173   %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 %y)
174   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
175   ret i32 %r
178 define i32 @umax_known_nonzero(i32 %x, i32 %y) {
179 ; CHECK-LABEL: umax_known_nonzero:
180 ; CHECK:       # %bb.0:
181 ; CHECK-NEXT:    movl %esi, %ecx
182 ; CHECK-NEXT:    movl $4, %eax
183 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
184 ; CHECK-NEXT:    shll %cl, %eax
185 ; CHECK-NEXT:    cmpl %eax, %edi
186 ; CHECK-NEXT:    cmoval %edi, %eax
187 ; CHECK-NEXT:    rep bsfl %eax, %eax
188 ; CHECK-NEXT:    retq
189   %yy = shl nuw i32 4, %y
190   %z = call i32 @llvm.umax.i32(i32 %x, i32 %yy)
191   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
192   ret i32 %r
195 define i32 @umax_maybe_zero(i32 %x, i32 %y) {
196 ; CHECK-LABEL: umax_maybe_zero:
197 ; CHECK:       # %bb.0:
198 ; CHECK-NEXT:    cmpl %esi, %edi
199 ; CHECK-NEXT:    cmoval %edi, %esi
200 ; CHECK-NEXT:    testl %esi, %esi
201 ; CHECK-NEXT:    je .LBB11_1
202 ; CHECK-NEXT:  # %bb.2: # %cond.false
203 ; CHECK-NEXT:    rep bsfl %esi, %eax
204 ; CHECK-NEXT:    retq
205 ; CHECK-NEXT:  .LBB11_1:
206 ; CHECK-NEXT:    movl $32, %eax
207 ; CHECK-NEXT:    retq
208   %z = call i32 @llvm.umax.i32(i32 %x, i32 %y)
209   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
210   ret i32 %r
213 define i32 @umin_known_nonzero(i32 %xx, i32 %yy) {
214 ; CHECK-LABEL: umin_known_nonzero:
215 ; CHECK:       # %bb.0:
216 ; CHECK-NEXT:    movl %edi, %ecx
217 ; CHECK-NEXT:    movl $4, %eax
218 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
219 ; CHECK-NEXT:    shll %cl, %eax
220 ; CHECK-NEXT:    addl $4, %esi
221 ; CHECK-NEXT:    cmpl %esi, %eax
222 ; CHECK-NEXT:    cmovbl %eax, %esi
223 ; CHECK-NEXT:    rep bsfl %esi, %eax
224 ; CHECK-NEXT:    retq
225   %x = shl nuw i32 4, %xx
226   %y = add nuw nsw i32 %yy, 4
227   %z = call i32 @llvm.umin.i32(i32 %x, i32 %y)
228   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
229   ret i32 %r
232 define i32 @umin_maybe_zero(i32 %x, i32 %y) {
233 ; CHECK-LABEL: umin_maybe_zero:
234 ; CHECK:       # %bb.0:
235 ; CHECK-NEXT:    cmpl $54, %edi
236 ; CHECK-NEXT:    movl $54, %eax
237 ; CHECK-NEXT:    cmovbl %edi, %eax
238 ; CHECK-NEXT:    testl %eax, %eax
239 ; CHECK-NEXT:    je .LBB13_1
240 ; CHECK-NEXT:  # %bb.2: # %cond.false
241 ; CHECK-NEXT:    rep bsfl %eax, %eax
242 ; CHECK-NEXT:    retq
243 ; CHECK-NEXT:  .LBB13_1:
244 ; CHECK-NEXT:    movl $32, %eax
245 ; CHECK-NEXT:    retq
246   %z = call i32 @llvm.umin.i32(i32 %x, i32 54)
247   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
248   ret i32 %r
251 define i32 @smin_known_nonzero(i32 %xx, i32 %yy) {
252 ; CHECK-LABEL: smin_known_nonzero:
253 ; CHECK:       # %bb.0:
254 ; CHECK-NEXT:    movl %edi, %ecx
255 ; CHECK-NEXT:    movl $4, %eax
256 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
257 ; CHECK-NEXT:    shll %cl, %eax
258 ; CHECK-NEXT:    addl $4, %esi
259 ; CHECK-NEXT:    cmpl %esi, %eax
260 ; CHECK-NEXT:    cmovll %eax, %esi
261 ; CHECK-NEXT:    rep bsfl %esi, %eax
262 ; CHECK-NEXT:    retq
263   %x = shl nuw i32 4, %xx
264   %y = add nuw nsw i32 %yy, 4
265   %z = call i32 @llvm.smin.i32(i32 %x, i32 %y)
266   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
267   ret i32 %r
270 define i32 @smin_maybe_zero(i32 %x, i32 %y) {
271 ; CHECK-LABEL: smin_maybe_zero:
272 ; CHECK:       # %bb.0:
273 ; CHECK-NEXT:    cmpl $54, %edi
274 ; CHECK-NEXT:    movl $54, %eax
275 ; CHECK-NEXT:    cmovll %edi, %eax
276 ; CHECK-NEXT:    testl %eax, %eax
277 ; CHECK-NEXT:    je .LBB15_1
278 ; CHECK-NEXT:  # %bb.2: # %cond.false
279 ; CHECK-NEXT:    rep bsfl %eax, %eax
280 ; CHECK-NEXT:    retq
281 ; CHECK-NEXT:  .LBB15_1:
282 ; CHECK-NEXT:    movl $32, %eax
283 ; CHECK-NEXT:    retq
284   %z = call i32 @llvm.smin.i32(i32 %x, i32 54)
285   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
286   ret i32 %r
289 define i32 @smax_known_nonzero(i32 %xx, i32 %yy) {
290 ; CHECK-LABEL: smax_known_nonzero:
291 ; CHECK:       # %bb.0:
292 ; CHECK-NEXT:    movl %edi, %ecx
293 ; CHECK-NEXT:    movl $4, %eax
294 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
295 ; CHECK-NEXT:    shll %cl, %eax
296 ; CHECK-NEXT:    addl $4, %esi
297 ; CHECK-NEXT:    cmpl %esi, %eax
298 ; CHECK-NEXT:    cmovgl %eax, %esi
299 ; CHECK-NEXT:    rep bsfl %esi, %eax
300 ; CHECK-NEXT:    retq
301   %x = shl nuw i32 4, %xx
302   %y = add nuw nsw i32 %yy, 4
303   %z = call i32 @llvm.smax.i32(i32 %x, i32 %y)
304   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
305   ret i32 %r
308 define i32 @smax_maybe_zero(i32 %x, i32 %y) {
309 ; CHECK-LABEL: smax_maybe_zero:
310 ; CHECK:       # %bb.0:
311 ; CHECK-NEXT:    cmpl $55, %edi
312 ; CHECK-NEXT:    movl $54, %eax
313 ; CHECK-NEXT:    cmovgel %edi, %eax
314 ; CHECK-NEXT:    bsfl %eax, %ecx
315 ; CHECK-NEXT:    movl $32, %eax
316 ; CHECK-NEXT:    cmovnel %ecx, %eax
317 ; CHECK-NEXT:    retq
318   %z = call i32 @llvm.smax.i32(i32 %x, i32 54)
319   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
320   ret i32 %r
323 define i32 @rotr_known_nonzero(i32 %xx, i32 %y) {
324 ; CHECK-LABEL: rotr_known_nonzero:
325 ; CHECK:       # %bb.0:
326 ; CHECK-NEXT:    movl %esi, %ecx
327 ; CHECK-NEXT:    orl $256, %edi # imm = 0x100
328 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
329 ; CHECK-NEXT:    rorl %cl, %edi
330 ; CHECK-NEXT:    testl %edi, %edi
331 ; CHECK-NEXT:    je .LBB18_1
332 ; CHECK-NEXT:  # %bb.2: # %cond.false
333 ; CHECK-NEXT:    rep bsfl %edi, %eax
334 ; CHECK-NEXT:    retq
335 ; CHECK-NEXT:  .LBB18_1:
336 ; CHECK-NEXT:    movl $32, %eax
337 ; CHECK-NEXT:    retq
338   %x = or i32 %xx, 256
339   %shr = lshr i32 %x, %y
340   %sub = sub i32 32, %y
341   %shl = shl i32 %x, %sub
342   %z = or i32 %shl, %shr
343   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
344   ret i32 %r
347 define i32 @rotr_maybe_zero(i32 %x, i32 %y) {
348 ; CHECK-LABEL: rotr_maybe_zero:
349 ; CHECK:       # %bb.0:
350 ; CHECK-NEXT:    movl %esi, %ecx
351 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
352 ; CHECK-NEXT:    rorl %cl, %edi
353 ; CHECK-NEXT:    testl %edi, %edi
354 ; CHECK-NEXT:    je .LBB19_1
355 ; CHECK-NEXT:  # %bb.2: # %cond.false
356 ; CHECK-NEXT:    rep bsfl %edi, %eax
357 ; CHECK-NEXT:    retq
358 ; CHECK-NEXT:  .LBB19_1:
359 ; CHECK-NEXT:    movl $32, %eax
360 ; CHECK-NEXT:    retq
361   %shr = lshr i32 %x, %y
362   %sub = sub i32 32, %y
363   %shl = shl i32 %x, %sub
364   %z = or i32 %shl, %shr
365   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
366   ret i32 %r
369 define i32 @rotr_with_fshr_known_nonzero(i32 %xx, i32 %y) {
370 ; CHECK-LABEL: rotr_with_fshr_known_nonzero:
371 ; CHECK:       # %bb.0:
372 ; CHECK-NEXT:    movl %esi, %ecx
373 ; CHECK-NEXT:    orl $256, %edi # imm = 0x100
374 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
375 ; CHECK-NEXT:    rorl %cl, %edi
376 ; CHECK-NEXT:    rep bsfl %edi, %eax
377 ; CHECK-NEXT:    retq
378   %x = or i32 %xx, 256
379   %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
380   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
381   ret i32 %r
384 define i32 @rotr_with_fshr_maybe_zero(i32 %x, i32 %y) {
385 ; CHECK-LABEL: rotr_with_fshr_maybe_zero:
386 ; CHECK:       # %bb.0:
387 ; CHECK-NEXT:    movl %esi, %ecx
388 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
389 ; CHECK-NEXT:    rorl %cl, %edi
390 ; CHECK-NEXT:    testl %edi, %edi
391 ; CHECK-NEXT:    je .LBB21_1
392 ; CHECK-NEXT:  # %bb.2: # %cond.false
393 ; CHECK-NEXT:    rep bsfl %edi, %eax
394 ; CHECK-NEXT:    retq
395 ; CHECK-NEXT:  .LBB21_1:
396 ; CHECK-NEXT:    movl $32, %eax
397 ; CHECK-NEXT:    retq
398   %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
399   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
400   ret i32 %r
403 define i32 @rotl_known_nonzero(i32 %xx, i32 %y) {
404 ; CHECK-LABEL: rotl_known_nonzero:
405 ; CHECK:       # %bb.0:
406 ; CHECK-NEXT:    movl %esi, %ecx
407 ; CHECK-NEXT:    orl $256, %edi # imm = 0x100
408 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
409 ; CHECK-NEXT:    roll %cl, %edi
410 ; CHECK-NEXT:    testl %edi, %edi
411 ; CHECK-NEXT:    je .LBB22_1
412 ; CHECK-NEXT:  # %bb.2: # %cond.false
413 ; CHECK-NEXT:    rep bsfl %edi, %eax
414 ; CHECK-NEXT:    retq
415 ; CHECK-NEXT:  .LBB22_1:
416 ; CHECK-NEXT:    movl $32, %eax
417 ; CHECK-NEXT:    retq
418   %x = or i32 %xx, 256
419   %shl = shl i32 %x, %y
420   %sub = sub i32 32, %y
421   %shr = lshr i32 %x, %sub
422   %z = or i32 %shr, %shl
423   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
424   ret i32 %r
427 define i32 @rotl_maybe_zero(i32 %x, i32 %y) {
428 ; CHECK-LABEL: rotl_maybe_zero:
429 ; CHECK:       # %bb.0:
430 ; CHECK-NEXT:    movl %esi, %ecx
431 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
432 ; CHECK-NEXT:    roll %cl, %edi
433 ; CHECK-NEXT:    testl %edi, %edi
434 ; CHECK-NEXT:    je .LBB23_1
435 ; CHECK-NEXT:  # %bb.2: # %cond.false
436 ; CHECK-NEXT:    rep bsfl %edi, %eax
437 ; CHECK-NEXT:    retq
438 ; CHECK-NEXT:  .LBB23_1:
439 ; CHECK-NEXT:    movl $32, %eax
440 ; CHECK-NEXT:    retq
441   %shl = shl i32 %x, %y
442   %sub = sub i32 32, %y
443   %shr = lshr i32 %x, %sub
444   %z = or i32 %shr, %shl
445   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
446   ret i32 %r
449 define i32 @rotl_with_fshl_known_nonzero(i32 %xx, i32 %y) {
450 ; CHECK-LABEL: rotl_with_fshl_known_nonzero:
451 ; CHECK:       # %bb.0:
452 ; CHECK-NEXT:    movl %esi, %ecx
453 ; CHECK-NEXT:    orl $256, %edi # imm = 0x100
454 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
455 ; CHECK-NEXT:    roll %cl, %edi
456 ; CHECK-NEXT:    rep bsfl %edi, %eax
457 ; CHECK-NEXT:    retq
458   %x = or i32 %xx, 256
459   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)
460   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
461   ret i32 %r
464 define i32 @rotl_with_fshl_maybe_zero(i32 %x, i32 %y) {
465 ; CHECK-LABEL: rotl_with_fshl_maybe_zero:
466 ; CHECK:       # %bb.0:
467 ; CHECK-NEXT:    movl %esi, %ecx
468 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
469 ; CHECK-NEXT:    roll %cl, %edi
470 ; CHECK-NEXT:    testl %edi, %edi
471 ; CHECK-NEXT:    je .LBB25_1
472 ; CHECK-NEXT:  # %bb.2: # %cond.false
473 ; CHECK-NEXT:    rep bsfl %edi, %eax
474 ; CHECK-NEXT:    retq
475 ; CHECK-NEXT:  .LBB25_1:
476 ; CHECK-NEXT:    movl $32, %eax
477 ; CHECK-NEXT:    retq
478   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)
479   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
480   ret i32 %r
483 define i32 @sra_known_nonzero_sign_bit_set(i32 %x) {
484 ; CHECK-LABEL: sra_known_nonzero_sign_bit_set:
485 ; CHECK:       # %bb.0:
486 ; CHECK-NEXT:    movl %edi, %ecx
487 ; CHECK-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
488 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
489 ; CHECK-NEXT:    sarl %cl, %eax
490 ; CHECK-NEXT:    rep bsfl %eax, %eax
491 ; CHECK-NEXT:    retq
492   %z = ashr i32 2147606891, %x
493   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
494   ret i32 %r
497 define i32 @sra_known_nonzero_exact(i32 %x, i32 %yy) {
498 ; CHECK-LABEL: sra_known_nonzero_exact:
499 ; CHECK:       # %bb.0:
500 ; CHECK-NEXT:    movl %edi, %ecx
501 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
502 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
503 ; CHECK-NEXT:    sarl %cl, %esi
504 ; CHECK-NEXT:    rep bsfl %esi, %eax
505 ; CHECK-NEXT:    retq
506   %y = or i32 %yy, 256
507   %z = ashr exact i32 %y, %x
508   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
509   ret i32 %r
512 define i32 @sra_maybe_zero(i32 %x, i32 %y) {
513 ; CHECK-LABEL: sra_maybe_zero:
514 ; CHECK:       # %bb.0:
515 ; CHECK-NEXT:    movl %edi, %ecx
516 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
517 ; CHECK-NEXT:    sarl %cl, %esi
518 ; CHECK-NEXT:    testl %esi, %esi
519 ; CHECK-NEXT:    je .LBB28_1
520 ; CHECK-NEXT:  # %bb.2: # %cond.false
521 ; CHECK-NEXT:    rep bsfl %esi, %eax
522 ; CHECK-NEXT:    retq
523 ; CHECK-NEXT:  .LBB28_1:
524 ; CHECK-NEXT:    movl $32, %eax
525 ; CHECK-NEXT:    retq
526   %z = ashr exact i32 %y, %x
527   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
528   ret i32 %r
531 define i32 @srl_known_nonzero_sign_bit_set(i32 %x) {
532 ; CHECK-LABEL: srl_known_nonzero_sign_bit_set:
533 ; CHECK:       # %bb.0:
534 ; CHECK-NEXT:    movl %edi, %ecx
535 ; CHECK-NEXT:    movl $-2147360405, %eax # imm = 0x8001E16B
536 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
537 ; CHECK-NEXT:    shrl %cl, %eax
538 ; CHECK-NEXT:    rep bsfl %eax, %eax
539 ; CHECK-NEXT:    retq
540   %z = lshr i32 2147606891, %x
541   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
542   ret i32 %r
545 define i32 @srl_known_nonzero_exact(i32 %x, i32 %yy) {
546 ; CHECK-LABEL: srl_known_nonzero_exact:
547 ; CHECK:       # %bb.0:
548 ; CHECK-NEXT:    movl %edi, %ecx
549 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
550 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
551 ; CHECK-NEXT:    shrl %cl, %esi
552 ; CHECK-NEXT:    rep bsfl %esi, %eax
553 ; CHECK-NEXT:    retq
554   %y = or i32 %yy, 256
555   %z = lshr exact i32 %y, %x
556   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
557   ret i32 %r
560 define i32 @srl_maybe_zero(i32 %x, i32 %y) {
561 ; CHECK-LABEL: srl_maybe_zero:
562 ; CHECK:       # %bb.0:
563 ; CHECK-NEXT:    movl %edi, %ecx
564 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
565 ; CHECK-NEXT:    shrl %cl, %esi
566 ; CHECK-NEXT:    testl %esi, %esi
567 ; CHECK-NEXT:    je .LBB31_1
568 ; CHECK-NEXT:  # %bb.2: # %cond.false
569 ; CHECK-NEXT:    rep bsfl %esi, %eax
570 ; CHECK-NEXT:    retq
571 ; CHECK-NEXT:  .LBB31_1:
572 ; CHECK-NEXT:    movl $32, %eax
573 ; CHECK-NEXT:    retq
574   %z = lshr exact i32 %y, %x
575   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
576   ret i32 %r
579 define i32 @udiv_known_nonzero(i32 %xx, i32 %y) {
580 ; CHECK-LABEL: udiv_known_nonzero:
581 ; CHECK:       # %bb.0:
582 ; CHECK-NEXT:    movl %edi, %eax
583 ; CHECK-NEXT:    orl $64, %eax
584 ; CHECK-NEXT:    xorl %edx, %edx
585 ; CHECK-NEXT:    divl %esi
586 ; CHECK-NEXT:    rep bsfl %eax, %eax
587 ; CHECK-NEXT:    retq
588   %x = or i32 %xx, 64
589   %z = udiv exact i32 %x, %y
590   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
591   ret i32 %r
594 define i32 @udiv_maybe_zero(i32 %x, i32 %y) {
595 ; CHECK-LABEL: udiv_maybe_zero:
596 ; CHECK:       # %bb.0:
597 ; CHECK-NEXT:    movl %edi, %eax
598 ; CHECK-NEXT:    xorl %edx, %edx
599 ; CHECK-NEXT:    divl %esi
600 ; CHECK-NEXT:    testl %eax, %eax
601 ; CHECK-NEXT:    je .LBB33_1
602 ; CHECK-NEXT:  # %bb.2: # %cond.false
603 ; CHECK-NEXT:    rep bsfl %eax, %eax
604 ; CHECK-NEXT:    retq
605 ; CHECK-NEXT:  .LBB33_1:
606 ; CHECK-NEXT:    movl $32, %eax
607 ; CHECK-NEXT:    retq
608   %z = udiv exact i32 %x, %y
609   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
610   ret i32 %r
613 define i32 @sdiv_known_nonzero(i32 %xx, i32 %y) {
614 ; CHECK-LABEL: sdiv_known_nonzero:
615 ; CHECK:       # %bb.0:
616 ; CHECK-NEXT:    movl %edi, %eax
617 ; CHECK-NEXT:    orl $64, %eax
618 ; CHECK-NEXT:    cltd
619 ; CHECK-NEXT:    idivl %esi
620 ; CHECK-NEXT:    rep bsfl %eax, %eax
621 ; CHECK-NEXT:    retq
622   %x = or i32 %xx, 64
623   %z = sdiv exact i32 %x, %y
624   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
625   ret i32 %r
628 define i32 @sdiv_maybe_zero(i32 %x, i32 %y) {
629 ; CHECK-LABEL: sdiv_maybe_zero:
630 ; CHECK:       # %bb.0:
631 ; CHECK-NEXT:    movl %edi, %eax
632 ; CHECK-NEXT:    cltd
633 ; CHECK-NEXT:    idivl %esi
634 ; CHECK-NEXT:    testl %eax, %eax
635 ; CHECK-NEXT:    je .LBB35_1
636 ; CHECK-NEXT:  # %bb.2: # %cond.false
637 ; CHECK-NEXT:    rep bsfl %eax, %eax
638 ; CHECK-NEXT:    retq
639 ; CHECK-NEXT:  .LBB35_1:
640 ; CHECK-NEXT:    movl $32, %eax
641 ; CHECK-NEXT:    retq
642   %z = sdiv exact i32 %x, %y
643   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
644   ret i32 %r
647 define i32 @add_known_nonzero(i32 %xx, i32 %y) {
648 ; CHECK-LABEL: add_known_nonzero:
649 ; CHECK:       # %bb.0:
650 ; CHECK-NEXT:    orl $1, %edi
651 ; CHECK-NEXT:    addl %esi, %edi
652 ; CHECK-NEXT:    rep bsfl %edi, %eax
653 ; CHECK-NEXT:    retq
654   %x = or i32 %xx, 1
655   %z = add nuw i32 %x, %y
656   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
657   ret i32 %r
660 define i32 @add_maybe_zero(i32 %xx, i32 %y) {
661 ; CHECK-LABEL: add_maybe_zero:
662 ; CHECK:       # %bb.0:
663 ; CHECK-NEXT:    orl $1, %edi
664 ; CHECK-NEXT:    addl %esi, %edi
665 ; CHECK-NEXT:    je .LBB37_1
666 ; CHECK-NEXT:  # %bb.2: # %cond.false
667 ; CHECK-NEXT:    rep bsfl %edi, %eax
668 ; CHECK-NEXT:    retq
669 ; CHECK-NEXT:  .LBB37_1:
670 ; CHECK-NEXT:    movl $32, %eax
671 ; CHECK-NEXT:    retq
672   %x = or i32 %xx, 1
673   %z = add nsw i32 %x, %y
674   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
675   ret i32 %r
678 define i32 @sub_known_nonzero_neg_case(i32 %xx) {
679 ; CHECK-LABEL: sub_known_nonzero_neg_case:
680 ; CHECK:       # %bb.0:
681 ; CHECK-NEXT:    movl %edi, %ecx
682 ; CHECK-NEXT:    movl $256, %eax # imm = 0x100
683 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
684 ; CHECK-NEXT:    shll %cl, %eax
685 ; CHECK-NEXT:    negl %eax
686 ; CHECK-NEXT:    rep bsfl %eax, %eax
687 ; CHECK-NEXT:    retq
688   %x = shl nuw nsw i32 256, %xx
689   %z = sub i32 0, %x
690   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
691   ret i32 %r
694 define i32 @sub_known_nonzero_ne_case(i32 %xx, i32 %yy) {
695 ; CHECK-LABEL: sub_known_nonzero_ne_case:
696 ; CHECK:       # %bb.0:
697 ; CHECK-NEXT:    movl %edi, %eax
698 ; CHECK-NEXT:    orl $64, %eax
699 ; CHECK-NEXT:    andl $-65, %edi
700 ; CHECK-NEXT:    subl %eax, %edi
701 ; CHECK-NEXT:    rep bsfl %edi, %eax
702 ; CHECK-NEXT:    retq
703   %x = or i32 %xx, 64
704   %y = and i32 %xx, -65
705   %z = sub i32 %y, %x
706   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
707   ret i32 %r
710 define i32 @sub_maybe_zero(i32 %x) {
711 ; CHECK-LABEL: sub_maybe_zero:
712 ; CHECK:       # %bb.0:
713 ; CHECK-NEXT:    movl %edi, %eax
714 ; CHECK-NEXT:    orl $64, %eax
715 ; CHECK-NEXT:    subl %edi, %eax
716 ; CHECK-NEXT:    je .LBB40_1
717 ; CHECK-NEXT:  # %bb.2: # %cond.false
718 ; CHECK-NEXT:    rep bsfl %eax, %eax
719 ; CHECK-NEXT:    retq
720 ; CHECK-NEXT:  .LBB40_1:
721 ; CHECK-NEXT:    movl $32, %eax
722 ; CHECK-NEXT:    retq
723   %y = or i32 %x, 64
724   %z = sub i32 %y, %x
725   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
726   ret i32 %r
729 define i32 @sub_maybe_zero2(i32 %x) {
730 ; CHECK-LABEL: sub_maybe_zero2:
731 ; CHECK:       # %bb.0:
732 ; CHECK-NEXT:    negl %edi
733 ; CHECK-NEXT:    je .LBB41_1
734 ; CHECK-NEXT:  # %bb.2: # %cond.false
735 ; CHECK-NEXT:    rep bsfl %edi, %eax
736 ; CHECK-NEXT:    retq
737 ; CHECK-NEXT:  .LBB41_1:
738 ; CHECK-NEXT:    movl $32, %eax
739 ; CHECK-NEXT:    retq
740   %z = sub i32 0, %x
741   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
742   ret i32 %r
745 define i32 @mul_known_nonzero_nsw(i32 %x, i32 %yy) {
746 ; CHECK-LABEL: mul_known_nonzero_nsw:
747 ; CHECK:       # %bb.0:
748 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
749 ; CHECK-NEXT:    imull %edi, %esi
750 ; CHECK-NEXT:    testl %esi, %esi
751 ; CHECK-NEXT:    je .LBB42_1
752 ; CHECK-NEXT:  # %bb.2: # %cond.false
753 ; CHECK-NEXT:    rep bsfl %esi, %eax
754 ; CHECK-NEXT:    retq
755 ; CHECK-NEXT:  .LBB42_1:
756 ; CHECK-NEXT:    movl $32, %eax
757 ; CHECK-NEXT:    retq
758   %y = or i32 %yy, 256
759   %z = mul nsw i32 %y, %x
760   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
761   ret i32 %r
764 define i32 @mul_known_nonzero_nuw(i32 %x, i32 %yy) {
765 ; CHECK-LABEL: mul_known_nonzero_nuw:
766 ; CHECK:       # %bb.0:
767 ; CHECK-NEXT:    orl $256, %esi # imm = 0x100
768 ; CHECK-NEXT:    imull %edi, %esi
769 ; CHECK-NEXT:    testl %esi, %esi
770 ; CHECK-NEXT:    je .LBB43_1
771 ; CHECK-NEXT:  # %bb.2: # %cond.false
772 ; CHECK-NEXT:    rep bsfl %esi, %eax
773 ; CHECK-NEXT:    retq
774 ; CHECK-NEXT:  .LBB43_1:
775 ; CHECK-NEXT:    movl $32, %eax
776 ; CHECK-NEXT:    retq
777   %y = or i32 %yy, 256
778   %z = mul nuw i32 %y, %x
779   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
780   ret i32 %r
783 define i32 @mul_maybe_zero(i32 %x, i32 %y) {
784 ; CHECK-LABEL: mul_maybe_zero:
785 ; CHECK:       # %bb.0:
786 ; CHECK-NEXT:    imull %esi, %edi
787 ; CHECK-NEXT:    testl %edi, %edi
788 ; CHECK-NEXT:    je .LBB44_1
789 ; CHECK-NEXT:  # %bb.2: # %cond.false
790 ; CHECK-NEXT:    rep bsfl %edi, %eax
791 ; CHECK-NEXT:    retq
792 ; CHECK-NEXT:  .LBB44_1:
793 ; CHECK-NEXT:    movl $32, %eax
794 ; CHECK-NEXT:    retq
795   %z = mul nuw nsw i32 %y, %x
796   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
797   ret i32 %r
800 define i32 @bitcast_known_nonzero(<2 x i16> %xx) {
801 ; CHECK-LABEL: bitcast_known_nonzero:
802 ; CHECK:       # %bb.0:
803 ; CHECK-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
804 ; CHECK-NEXT:    pslld $23, %xmm0
805 ; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
806 ; CHECK-NEXT:    cvttps2dq %xmm0, %xmm0
807 ; CHECK-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
808 ; CHECK-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
809 ; CHECK-NEXT:    movd %xmm0, %eax
810 ; CHECK-NEXT:    bsfl %eax, %ecx
811 ; CHECK-NEXT:    movl $32, %eax
812 ; CHECK-NEXT:    cmovnel %ecx, %eax
813 ; CHECK-NEXT:    retq
814   %x = shl nuw nsw <2 x i16> <i16 256, i16 256>, %xx
815   %z = bitcast <2 x i16> %x to i32
816   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
817   ret i32 %r
820 define i32 @bitcast_maybe_zero(<2 x i16> %x) {
821 ; CHECK-LABEL: bitcast_maybe_zero:
822 ; CHECK:       # %bb.0:
823 ; CHECK-NEXT:    movd %xmm0, %eax
824 ; CHECK-NEXT:    testl %eax, %eax
825 ; CHECK-NEXT:    je .LBB46_1
826 ; CHECK-NEXT:  # %bb.2: # %cond.false
827 ; CHECK-NEXT:    rep bsfl %eax, %eax
828 ; CHECK-NEXT:    retq
829 ; CHECK-NEXT:  .LBB46_1:
830 ; CHECK-NEXT:    movl $32, %eax
831 ; CHECK-NEXT:    retq
832   %z = bitcast <2 x i16> %x to i32
833   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
834   ret i32 %r
837 define i32 @bitcast_from_float(float %x) {
838 ; CHECK-LABEL: bitcast_from_float:
839 ; CHECK:       # %bb.0:
840 ; CHECK-NEXT:    movd %xmm0, %eax
841 ; CHECK-NEXT:    testl %eax, %eax
842 ; CHECK-NEXT:    je .LBB47_1
843 ; CHECK-NEXT:  # %bb.2: # %cond.false
844 ; CHECK-NEXT:    rep bsfl %eax, %eax
845 ; CHECK-NEXT:    retq
846 ; CHECK-NEXT:  .LBB47_1:
847 ; CHECK-NEXT:    movl $32, %eax
848 ; CHECK-NEXT:    retq
849   %z = bitcast float %x to i32
850   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
851   ret i32 %r
854 define i32 @zext_known_nonzero(i16 %xx) {
855 ; CHECK-LABEL: zext_known_nonzero:
856 ; CHECK:       # %bb.0:
857 ; CHECK-NEXT:    movl %edi, %ecx
858 ; CHECK-NEXT:    movl $256, %eax # imm = 0x100
859 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
860 ; CHECK-NEXT:    shll %cl, %eax
861 ; CHECK-NEXT:    movzwl %ax, %eax
862 ; CHECK-NEXT:    rep bsfl %eax, %eax
863 ; CHECK-NEXT:    retq
864   %x = shl nuw nsw i16 256, %xx
865   %z = zext i16 %x to i32
866   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
867   ret i32 %r
870 define i32 @zext_maybe_zero(i16 %x) {
871 ; CHECK-LABEL: zext_maybe_zero:
872 ; CHECK:       # %bb.0:
873 ; CHECK-NEXT:    testw %di, %di
874 ; CHECK-NEXT:    je .LBB49_1
875 ; CHECK-NEXT:  # %bb.2: # %cond.false
876 ; CHECK-NEXT:    movzwl %di, %eax
877 ; CHECK-NEXT:    rep bsfl %eax, %eax
878 ; CHECK-NEXT:    retq
879 ; CHECK-NEXT:  .LBB49_1:
880 ; CHECK-NEXT:    movl $32, %eax
881 ; CHECK-NEXT:    retq
882   %z = zext i16 %x to i32
883   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
884   ret i32 %r
887 define i32 @sext_known_nonzero(i16 %xx) {
888 ; CHECK-LABEL: sext_known_nonzero:
889 ; CHECK:       # %bb.0:
890 ; CHECK-NEXT:    movl %edi, %ecx
891 ; CHECK-NEXT:    movl $256, %eax # imm = 0x100
892 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
893 ; CHECK-NEXT:    shll %cl, %eax
894 ; CHECK-NEXT:    cwtl
895 ; CHECK-NEXT:    rep bsfl %eax, %eax
896 ; CHECK-NEXT:    retq
897   %x = shl nuw nsw i16 256, %xx
898   %z = sext i16 %x to i32
899   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
900   ret i32 %r
903 define i32 @sext_maybe_zero(i16 %x) {
904 ; CHECK-LABEL: sext_maybe_zero:
905 ; CHECK:       # %bb.0:
906 ; CHECK-NEXT:    testw %di, %di
907 ; CHECK-NEXT:    je .LBB51_1
908 ; CHECK-NEXT:  # %bb.2: # %cond.false
909 ; CHECK-NEXT:    movswl %di, %eax
910 ; CHECK-NEXT:    rep bsfl %eax, %eax
911 ; CHECK-NEXT:    retq
912 ; CHECK-NEXT:  .LBB51_1:
913 ; CHECK-NEXT:    movl $32, %eax
914 ; CHECK-NEXT:    retq
915   %z = sext i16 %x to i32
916   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
917   ret i32 %r