1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=X64
8 ; The register+memory form of the BT instruction should be usable on
9 ; pentium4, however it is currently disabled due to the register+memory
10 ; form having different semantics than the register+register form.
12 ; Test these patterns:
13 ; (X & (1 << N)) != 0 --> BT(X, N).
14 ; ((X >>u N) & 1) != 0 --> BT(X, N).
15 ; as well as several variations:
16 ; - The second form can use an arithmetic shift.
17 ; - Either form can use == instead of !=.
18 ; - Either form can compare with an operand of the &
20 ; - The comparison can be commuted (only cases where neither
21 ; operand is constant are included).
22 ; - The and can be commuted.
24 define void @test2(i32 %x, i32 %n) nounwind {
26 ; X86: # %bb.0: # %entry
27 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
28 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
29 ; X86-NEXT: btl %ecx, %eax
30 ; X86-NEXT: jb .LBB0_2
31 ; X86-NEXT: # %bb.1: # %bb
33 ; X86-NEXT: .LBB0_2: # %UnifiedReturnBlock
37 ; X64: # %bb.0: # %entry
38 ; X64-NEXT: btl %esi, %edi
39 ; X64-NEXT: jb .LBB0_2
40 ; X64-NEXT: # %bb.1: # %bb
41 ; X64-NEXT: pushq %rax
44 ; X64-NEXT: .LBB0_2: # %UnifiedReturnBlock
47 %tmp29 = lshr i32 %x, %n
48 %tmp3 = and i32 %tmp29, 1
49 %tmp4 = icmp eq i32 %tmp3, 0
50 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
60 define void @test2b(i32 %x, i32 %n) nounwind {
62 ; X86: # %bb.0: # %entry
63 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
64 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
65 ; X86-NEXT: btl %ecx, %eax
66 ; X86-NEXT: jae .LBB1_1
67 ; X86-NEXT: # %bb.2: # %UnifiedReturnBlock
69 ; X86-NEXT: .LBB1_1: # %bb
74 ; X64: # %bb.0: # %entry
75 ; X64-NEXT: btl %esi, %edi
76 ; X64-NEXT: jae .LBB1_1
77 ; X64-NEXT: # %bb.2: # %UnifiedReturnBlock
79 ; X64-NEXT: .LBB1_1: # %bb
80 ; X64-NEXT: pushq %rax
85 %tmp29 = lshr i32 %x, %n
86 %tmp3 = and i32 1, %tmp29
87 %tmp4 = icmp eq i32 %tmp3, 0
88 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
98 define void @atest2(i32 %x, i32 %n) nounwind {
100 ; X86: # %bb.0: # %entry
101 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
102 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
103 ; X86-NEXT: btl %ecx, %eax
104 ; X86-NEXT: jb .LBB2_2
105 ; X86-NEXT: # %bb.1: # %bb
106 ; X86-NEXT: calll foo
107 ; X86-NEXT: .LBB2_2: # %UnifiedReturnBlock
111 ; X64: # %bb.0: # %entry
112 ; X64-NEXT: btl %esi, %edi
113 ; X64-NEXT: jb .LBB2_2
114 ; X64-NEXT: # %bb.1: # %bb
115 ; X64-NEXT: pushq %rax
116 ; X64-NEXT: callq foo
117 ; X64-NEXT: popq %rax
118 ; X64-NEXT: .LBB2_2: # %UnifiedReturnBlock
121 %tmp29 = ashr i32 %x, %n
122 %tmp3 = and i32 %tmp29, 1
123 %tmp4 = icmp eq i32 %tmp3, 0
124 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
134 define void @atest2b(i32 %x, i32 %n) nounwind {
135 ; X86-LABEL: atest2b:
136 ; X86: # %bb.0: # %entry
137 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
138 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
139 ; X86-NEXT: btl %ecx, %eax
140 ; X86-NEXT: jae .LBB3_1
141 ; X86-NEXT: # %bb.2: # %UnifiedReturnBlock
143 ; X86-NEXT: .LBB3_1: # %bb
144 ; X86-NEXT: calll foo
147 ; X64-LABEL: atest2b:
148 ; X64: # %bb.0: # %entry
149 ; X64-NEXT: btl %esi, %edi
150 ; X64-NEXT: jae .LBB3_1
151 ; X64-NEXT: # %bb.2: # %UnifiedReturnBlock
153 ; X64-NEXT: .LBB3_1: # %bb
154 ; X64-NEXT: pushq %rax
155 ; X64-NEXT: callq foo
156 ; X64-NEXT: popq %rax
159 %tmp29 = ashr i32 %x, %n
160 %tmp3 = and i32 1, %tmp29
161 %tmp4 = icmp eq i32 %tmp3, 0
162 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
172 define void @test3(i32 %x, i32 %n) nounwind {
174 ; X86: # %bb.0: # %entry
175 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
176 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
177 ; X86-NEXT: btl %ecx, %eax
178 ; X86-NEXT: jae .LBB4_1
179 ; X86-NEXT: # %bb.2: # %UnifiedReturnBlock
181 ; X86-NEXT: .LBB4_1: # %bb
182 ; X86-NEXT: calll foo
186 ; X64: # %bb.0: # %entry
187 ; X64-NEXT: btl %esi, %edi
188 ; X64-NEXT: jae .LBB4_1
189 ; X64-NEXT: # %bb.2: # %UnifiedReturnBlock
191 ; X64-NEXT: .LBB4_1: # %bb
192 ; X64-NEXT: pushq %rax
193 ; X64-NEXT: callq foo
194 ; X64-NEXT: popq %rax
197 %tmp29 = shl i32 1, %n
198 %tmp3 = and i32 %tmp29, %x
199 %tmp4 = icmp eq i32 %tmp3, 0
200 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
210 define void @test3b(i32 %x, i32 %n) nounwind {
212 ; X86: # %bb.0: # %entry
213 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
214 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
215 ; X86-NEXT: btl %ecx, %eax
216 ; X86-NEXT: jae .LBB5_1
217 ; X86-NEXT: # %bb.2: # %UnifiedReturnBlock
219 ; X86-NEXT: .LBB5_1: # %bb
220 ; X86-NEXT: calll foo
224 ; X64: # %bb.0: # %entry
225 ; X64-NEXT: btl %esi, %edi
226 ; X64-NEXT: jae .LBB5_1
227 ; X64-NEXT: # %bb.2: # %UnifiedReturnBlock
229 ; X64-NEXT: .LBB5_1: # %bb
230 ; X64-NEXT: pushq %rax
231 ; X64-NEXT: callq foo
232 ; X64-NEXT: popq %rax
235 %tmp29 = shl i32 1, %n
236 %tmp3 = and i32 %x, %tmp29
237 %tmp4 = icmp eq i32 %tmp3, 0
238 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
248 define void @testne2(i32 %x, i32 %n) nounwind {
249 ; X86-LABEL: testne2:
250 ; X86: # %bb.0: # %entry
251 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
252 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
253 ; X86-NEXT: btl %ecx, %eax
254 ; X86-NEXT: jae .LBB6_2
255 ; X86-NEXT: # %bb.1: # %bb
256 ; X86-NEXT: calll foo
257 ; X86-NEXT: .LBB6_2: # %UnifiedReturnBlock
260 ; X64-LABEL: testne2:
261 ; X64: # %bb.0: # %entry
262 ; X64-NEXT: btl %esi, %edi
263 ; X64-NEXT: jae .LBB6_2
264 ; X64-NEXT: # %bb.1: # %bb
265 ; X64-NEXT: pushq %rax
266 ; X64-NEXT: callq foo
267 ; X64-NEXT: popq %rax
268 ; X64-NEXT: .LBB6_2: # %UnifiedReturnBlock
271 %tmp29 = lshr i32 %x, %n
272 %tmp3 = and i32 %tmp29, 1
273 %tmp4 = icmp ne i32 %tmp3, 0
274 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
284 define void @testne2b(i32 %x, i32 %n) nounwind {
285 ; X86-LABEL: testne2b:
286 ; X86: # %bb.0: # %entry
287 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
288 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
289 ; X86-NEXT: btl %ecx, %eax
290 ; X86-NEXT: jae .LBB7_2
291 ; X86-NEXT: # %bb.1: # %bb
292 ; X86-NEXT: calll foo
293 ; X86-NEXT: .LBB7_2: # %UnifiedReturnBlock
296 ; X64-LABEL: testne2b:
297 ; X64: # %bb.0: # %entry
298 ; X64-NEXT: btl %esi, %edi
299 ; X64-NEXT: jae .LBB7_2
300 ; X64-NEXT: # %bb.1: # %bb
301 ; X64-NEXT: pushq %rax
302 ; X64-NEXT: callq foo
303 ; X64-NEXT: popq %rax
304 ; X64-NEXT: .LBB7_2: # %UnifiedReturnBlock
307 %tmp29 = lshr i32 %x, %n
308 %tmp3 = and i32 1, %tmp29
309 %tmp4 = icmp ne i32 %tmp3, 0
310 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
320 define void @atestne2(i32 %x, i32 %n) nounwind {
321 ; X86-LABEL: atestne2:
322 ; X86: # %bb.0: # %entry
323 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
324 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
325 ; X86-NEXT: btl %ecx, %eax
326 ; X86-NEXT: jae .LBB8_2
327 ; X86-NEXT: # %bb.1: # %bb
328 ; X86-NEXT: calll foo
329 ; X86-NEXT: .LBB8_2: # %UnifiedReturnBlock
332 ; X64-LABEL: atestne2:
333 ; X64: # %bb.0: # %entry
334 ; X64-NEXT: btl %esi, %edi
335 ; X64-NEXT: jae .LBB8_2
336 ; X64-NEXT: # %bb.1: # %bb
337 ; X64-NEXT: pushq %rax
338 ; X64-NEXT: callq foo
339 ; X64-NEXT: popq %rax
340 ; X64-NEXT: .LBB8_2: # %UnifiedReturnBlock
343 %tmp29 = ashr i32 %x, %n
344 %tmp3 = and i32 %tmp29, 1
345 %tmp4 = icmp ne i32 %tmp3, 0
346 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
356 define void @atestne2b(i32 %x, i32 %n) nounwind {
357 ; X86-LABEL: atestne2b:
358 ; X86: # %bb.0: # %entry
359 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
360 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
361 ; X86-NEXT: btl %ecx, %eax
362 ; X86-NEXT: jae .LBB9_2
363 ; X86-NEXT: # %bb.1: # %bb
364 ; X86-NEXT: calll foo
365 ; X86-NEXT: .LBB9_2: # %UnifiedReturnBlock
368 ; X64-LABEL: atestne2b:
369 ; X64: # %bb.0: # %entry
370 ; X64-NEXT: btl %esi, %edi
371 ; X64-NEXT: jae .LBB9_2
372 ; X64-NEXT: # %bb.1: # %bb
373 ; X64-NEXT: pushq %rax
374 ; X64-NEXT: callq foo
375 ; X64-NEXT: popq %rax
376 ; X64-NEXT: .LBB9_2: # %UnifiedReturnBlock
379 %tmp29 = ashr i32 %x, %n
380 %tmp3 = and i32 1, %tmp29
381 %tmp4 = icmp ne i32 %tmp3, 0
382 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
392 define void @testne3(i32 %x, i32 %n) nounwind {
393 ; X86-LABEL: testne3:
394 ; X86: # %bb.0: # %entry
395 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
396 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
397 ; X86-NEXT: btl %ecx, %eax
398 ; X86-NEXT: jae .LBB10_2
399 ; X86-NEXT: # %bb.1: # %bb
400 ; X86-NEXT: calll foo
401 ; X86-NEXT: .LBB10_2: # %UnifiedReturnBlock
404 ; X64-LABEL: testne3:
405 ; X64: # %bb.0: # %entry
406 ; X64-NEXT: btl %esi, %edi
407 ; X64-NEXT: jae .LBB10_2
408 ; X64-NEXT: # %bb.1: # %bb
409 ; X64-NEXT: pushq %rax
410 ; X64-NEXT: callq foo
411 ; X64-NEXT: popq %rax
412 ; X64-NEXT: .LBB10_2: # %UnifiedReturnBlock
415 %tmp29 = shl i32 1, %n
416 %tmp3 = and i32 %tmp29, %x
417 %tmp4 = icmp ne i32 %tmp3, 0
418 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
428 define void @testne3b(i32 %x, i32 %n) nounwind {
429 ; X86-LABEL: testne3b:
430 ; X86: # %bb.0: # %entry
431 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
432 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
433 ; X86-NEXT: btl %ecx, %eax
434 ; X86-NEXT: jae .LBB11_2
435 ; X86-NEXT: # %bb.1: # %bb
436 ; X86-NEXT: calll foo
437 ; X86-NEXT: .LBB11_2: # %UnifiedReturnBlock
440 ; X64-LABEL: testne3b:
441 ; X64: # %bb.0: # %entry
442 ; X64-NEXT: btl %esi, %edi
443 ; X64-NEXT: jae .LBB11_2
444 ; X64-NEXT: # %bb.1: # %bb
445 ; X64-NEXT: pushq %rax
446 ; X64-NEXT: callq foo
447 ; X64-NEXT: popq %rax
448 ; X64-NEXT: .LBB11_2: # %UnifiedReturnBlock
451 %tmp29 = shl i32 1, %n
452 %tmp3 = and i32 %x, %tmp29
453 %tmp4 = icmp ne i32 %tmp3, 0
454 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
464 define void @query2(i32 %x, i32 %n) nounwind {
466 ; X86: # %bb.0: # %entry
467 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
468 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
469 ; X86-NEXT: btl %ecx, %eax
470 ; X86-NEXT: jae .LBB12_2
471 ; X86-NEXT: # %bb.1: # %bb
472 ; X86-NEXT: calll foo
473 ; X86-NEXT: .LBB12_2: # %UnifiedReturnBlock
477 ; X64: # %bb.0: # %entry
478 ; X64-NEXT: btl %esi, %edi
479 ; X64-NEXT: jae .LBB12_2
480 ; X64-NEXT: # %bb.1: # %bb
481 ; X64-NEXT: pushq %rax
482 ; X64-NEXT: callq foo
483 ; X64-NEXT: popq %rax
484 ; X64-NEXT: .LBB12_2: # %UnifiedReturnBlock
487 %tmp29 = lshr i32 %x, %n
488 %tmp3 = and i32 %tmp29, 1
489 %tmp4 = icmp eq i32 %tmp3, 1
490 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
500 define void @query2b(i32 %x, i32 %n) nounwind {
501 ; X86-LABEL: query2b:
502 ; X86: # %bb.0: # %entry
503 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
504 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
505 ; X86-NEXT: btl %ecx, %eax
506 ; X86-NEXT: jae .LBB13_2
507 ; X86-NEXT: # %bb.1: # %bb
508 ; X86-NEXT: calll foo
509 ; X86-NEXT: .LBB13_2: # %UnifiedReturnBlock
512 ; X64-LABEL: query2b:
513 ; X64: # %bb.0: # %entry
514 ; X64-NEXT: btl %esi, %edi
515 ; X64-NEXT: jae .LBB13_2
516 ; X64-NEXT: # %bb.1: # %bb
517 ; X64-NEXT: pushq %rax
518 ; X64-NEXT: callq foo
519 ; X64-NEXT: popq %rax
520 ; X64-NEXT: .LBB13_2: # %UnifiedReturnBlock
523 %tmp29 = lshr i32 %x, %n
524 %tmp3 = and i32 1, %tmp29
525 %tmp4 = icmp eq i32 %tmp3, 1
526 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
536 define void @aquery2(i32 %x, i32 %n) nounwind {
537 ; X86-LABEL: aquery2:
538 ; X86: # %bb.0: # %entry
539 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
540 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
541 ; X86-NEXT: btl %ecx, %eax
542 ; X86-NEXT: jae .LBB14_2
543 ; X86-NEXT: # %bb.1: # %bb
544 ; X86-NEXT: calll foo
545 ; X86-NEXT: .LBB14_2: # %UnifiedReturnBlock
548 ; X64-LABEL: aquery2:
549 ; X64: # %bb.0: # %entry
550 ; X64-NEXT: btl %esi, %edi
551 ; X64-NEXT: jae .LBB14_2
552 ; X64-NEXT: # %bb.1: # %bb
553 ; X64-NEXT: pushq %rax
554 ; X64-NEXT: callq foo
555 ; X64-NEXT: popq %rax
556 ; X64-NEXT: .LBB14_2: # %UnifiedReturnBlock
559 %tmp29 = ashr i32 %x, %n
560 %tmp3 = and i32 %tmp29, 1
561 %tmp4 = icmp eq i32 %tmp3, 1
562 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
572 define void @aquery2b(i32 %x, i32 %n) nounwind {
573 ; X86-LABEL: aquery2b:
574 ; X86: # %bb.0: # %entry
575 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
576 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
577 ; X86-NEXT: btl %ecx, %eax
578 ; X86-NEXT: jae .LBB15_2
579 ; X86-NEXT: # %bb.1: # %bb
580 ; X86-NEXT: calll foo
581 ; X86-NEXT: .LBB15_2: # %UnifiedReturnBlock
584 ; X64-LABEL: aquery2b:
585 ; X64: # %bb.0: # %entry
586 ; X64-NEXT: btl %esi, %edi
587 ; X64-NEXT: jae .LBB15_2
588 ; X64-NEXT: # %bb.1: # %bb
589 ; X64-NEXT: pushq %rax
590 ; X64-NEXT: callq foo
591 ; X64-NEXT: popq %rax
592 ; X64-NEXT: .LBB15_2: # %UnifiedReturnBlock
595 %tmp29 = ashr i32 %x, %n
596 %tmp3 = and i32 1, %tmp29
597 %tmp4 = icmp eq i32 %tmp3, 1
598 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
608 define void @query3(i32 %x, i32 %n) nounwind {
610 ; X86: # %bb.0: # %entry
611 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
612 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
613 ; X86-NEXT: btl %ecx, %eax
614 ; X86-NEXT: jae .LBB16_2
615 ; X86-NEXT: # %bb.1: # %bb
616 ; X86-NEXT: calll foo
617 ; X86-NEXT: .LBB16_2: # %UnifiedReturnBlock
621 ; X64: # %bb.0: # %entry
622 ; X64-NEXT: btl %esi, %edi
623 ; X64-NEXT: jae .LBB16_2
624 ; X64-NEXT: # %bb.1: # %bb
625 ; X64-NEXT: pushq %rax
626 ; X64-NEXT: callq foo
627 ; X64-NEXT: popq %rax
628 ; X64-NEXT: .LBB16_2: # %UnifiedReturnBlock
631 %tmp29 = shl i32 1, %n
632 %tmp3 = and i32 %tmp29, %x
633 %tmp4 = icmp eq i32 %tmp3, %tmp29
634 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
644 define void @query3b(i32 %x, i32 %n) nounwind {
645 ; X86-LABEL: query3b:
646 ; X86: # %bb.0: # %entry
647 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
648 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
649 ; X86-NEXT: btl %ecx, %eax
650 ; X86-NEXT: jae .LBB17_2
651 ; X86-NEXT: # %bb.1: # %bb
652 ; X86-NEXT: calll foo
653 ; X86-NEXT: .LBB17_2: # %UnifiedReturnBlock
656 ; X64-LABEL: query3b:
657 ; X64: # %bb.0: # %entry
658 ; X64-NEXT: btl %esi, %edi
659 ; X64-NEXT: jae .LBB17_2
660 ; X64-NEXT: # %bb.1: # %bb
661 ; X64-NEXT: pushq %rax
662 ; X64-NEXT: callq foo
663 ; X64-NEXT: popq %rax
664 ; X64-NEXT: .LBB17_2: # %UnifiedReturnBlock
667 %tmp29 = shl i32 1, %n
668 %tmp3 = and i32 %x, %tmp29
669 %tmp4 = icmp eq i32 %tmp3, %tmp29
670 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
680 define void @query3x(i32 %x, i32 %n) nounwind {
681 ; X86-LABEL: query3x:
682 ; X86: # %bb.0: # %entry
683 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
684 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
685 ; X86-NEXT: btl %ecx, %eax
686 ; X86-NEXT: jae .LBB18_2
687 ; X86-NEXT: # %bb.1: # %bb
688 ; X86-NEXT: calll foo
689 ; X86-NEXT: .LBB18_2: # %UnifiedReturnBlock
692 ; X64-LABEL: query3x:
693 ; X64: # %bb.0: # %entry
694 ; X64-NEXT: btl %esi, %edi
695 ; X64-NEXT: jae .LBB18_2
696 ; X64-NEXT: # %bb.1: # %bb
697 ; X64-NEXT: pushq %rax
698 ; X64-NEXT: callq foo
699 ; X64-NEXT: popq %rax
700 ; X64-NEXT: .LBB18_2: # %UnifiedReturnBlock
703 %tmp29 = shl i32 1, %n
704 %tmp3 = and i32 %tmp29, %x
705 %tmp4 = icmp eq i32 %tmp29, %tmp3
706 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
716 define void @query3bx(i32 %x, i32 %n) nounwind {
717 ; X86-LABEL: query3bx:
718 ; X86: # %bb.0: # %entry
719 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
720 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
721 ; X86-NEXT: btl %ecx, %eax
722 ; X86-NEXT: jae .LBB19_2
723 ; X86-NEXT: # %bb.1: # %bb
724 ; X86-NEXT: calll foo
725 ; X86-NEXT: .LBB19_2: # %UnifiedReturnBlock
728 ; X64-LABEL: query3bx:
729 ; X64: # %bb.0: # %entry
730 ; X64-NEXT: btl %esi, %edi
731 ; X64-NEXT: jae .LBB19_2
732 ; X64-NEXT: # %bb.1: # %bb
733 ; X64-NEXT: pushq %rax
734 ; X64-NEXT: callq foo
735 ; X64-NEXT: popq %rax
736 ; X64-NEXT: .LBB19_2: # %UnifiedReturnBlock
739 %tmp29 = shl i32 1, %n
740 %tmp3 = and i32 %x, %tmp29
741 %tmp4 = icmp eq i32 %tmp29, %tmp3
742 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
752 define void @queryne2(i32 %x, i32 %n) nounwind {
753 ; X86-LABEL: queryne2:
754 ; X86: # %bb.0: # %entry
755 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
756 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
757 ; X86-NEXT: btl %ecx, %eax
758 ; X86-NEXT: jb .LBB20_2
759 ; X86-NEXT: # %bb.1: # %bb
760 ; X86-NEXT: calll foo
761 ; X86-NEXT: .LBB20_2: # %UnifiedReturnBlock
764 ; X64-LABEL: queryne2:
765 ; X64: # %bb.0: # %entry
766 ; X64-NEXT: btl %esi, %edi
767 ; X64-NEXT: jb .LBB20_2
768 ; X64-NEXT: # %bb.1: # %bb
769 ; X64-NEXT: pushq %rax
770 ; X64-NEXT: callq foo
771 ; X64-NEXT: popq %rax
772 ; X64-NEXT: .LBB20_2: # %UnifiedReturnBlock
775 %tmp29 = lshr i32 %x, %n
776 %tmp3 = and i32 %tmp29, 1
777 %tmp4 = icmp ne i32 %tmp3, 1
778 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
788 define void @queryne2b(i32 %x, i32 %n) nounwind {
789 ; X86-LABEL: queryne2b:
790 ; X86: # %bb.0: # %entry
791 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
792 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
793 ; X86-NEXT: btl %ecx, %eax
794 ; X86-NEXT: jb .LBB21_2
795 ; X86-NEXT: # %bb.1: # %bb
796 ; X86-NEXT: calll foo
797 ; X86-NEXT: .LBB21_2: # %UnifiedReturnBlock
800 ; X64-LABEL: queryne2b:
801 ; X64: # %bb.0: # %entry
802 ; X64-NEXT: btl %esi, %edi
803 ; X64-NEXT: jb .LBB21_2
804 ; X64-NEXT: # %bb.1: # %bb
805 ; X64-NEXT: pushq %rax
806 ; X64-NEXT: callq foo
807 ; X64-NEXT: popq %rax
808 ; X64-NEXT: .LBB21_2: # %UnifiedReturnBlock
811 %tmp29 = lshr i32 %x, %n
812 %tmp3 = and i32 1, %tmp29
813 %tmp4 = icmp ne i32 %tmp3, 1
814 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
824 define void @aqueryne2(i32 %x, i32 %n) nounwind {
825 ; X86-LABEL: aqueryne2:
826 ; X86: # %bb.0: # %entry
827 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
828 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
829 ; X86-NEXT: btl %ecx, %eax
830 ; X86-NEXT: jb .LBB22_2
831 ; X86-NEXT: # %bb.1: # %bb
832 ; X86-NEXT: calll foo
833 ; X86-NEXT: .LBB22_2: # %UnifiedReturnBlock
836 ; X64-LABEL: aqueryne2:
837 ; X64: # %bb.0: # %entry
838 ; X64-NEXT: btl %esi, %edi
839 ; X64-NEXT: jb .LBB22_2
840 ; X64-NEXT: # %bb.1: # %bb
841 ; X64-NEXT: pushq %rax
842 ; X64-NEXT: callq foo
843 ; X64-NEXT: popq %rax
844 ; X64-NEXT: .LBB22_2: # %UnifiedReturnBlock
847 %tmp29 = ashr i32 %x, %n
848 %tmp3 = and i32 %tmp29, 1
849 %tmp4 = icmp ne i32 %tmp3, 1
850 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
860 define void @aqueryne2b(i32 %x, i32 %n) nounwind {
861 ; X86-LABEL: aqueryne2b:
862 ; X86: # %bb.0: # %entry
863 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
864 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
865 ; X86-NEXT: btl %ecx, %eax
866 ; X86-NEXT: jb .LBB23_2
867 ; X86-NEXT: # %bb.1: # %bb
868 ; X86-NEXT: calll foo
869 ; X86-NEXT: .LBB23_2: # %UnifiedReturnBlock
872 ; X64-LABEL: aqueryne2b:
873 ; X64: # %bb.0: # %entry
874 ; X64-NEXT: btl %esi, %edi
875 ; X64-NEXT: jb .LBB23_2
876 ; X64-NEXT: # %bb.1: # %bb
877 ; X64-NEXT: pushq %rax
878 ; X64-NEXT: callq foo
879 ; X64-NEXT: popq %rax
880 ; X64-NEXT: .LBB23_2: # %UnifiedReturnBlock
883 %tmp29 = ashr i32 %x, %n
884 %tmp3 = and i32 1, %tmp29
885 %tmp4 = icmp ne i32 %tmp3, 1
886 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
896 define void @queryne3(i32 %x, i32 %n) nounwind {
897 ; X86-LABEL: queryne3:
898 ; X86: # %bb.0: # %entry
899 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
900 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
901 ; X86-NEXT: btl %ecx, %eax
902 ; X86-NEXT: jb .LBB24_2
903 ; X86-NEXT: # %bb.1: # %bb
904 ; X86-NEXT: calll foo
905 ; X86-NEXT: .LBB24_2: # %UnifiedReturnBlock
908 ; X64-LABEL: queryne3:
909 ; X64: # %bb.0: # %entry
910 ; X64-NEXT: btl %esi, %edi
911 ; X64-NEXT: jb .LBB24_2
912 ; X64-NEXT: # %bb.1: # %bb
913 ; X64-NEXT: pushq %rax
914 ; X64-NEXT: callq foo
915 ; X64-NEXT: popq %rax
916 ; X64-NEXT: .LBB24_2: # %UnifiedReturnBlock
919 %tmp29 = shl i32 1, %n
920 %tmp3 = and i32 %tmp29, %x
921 %tmp4 = icmp ne i32 %tmp3, %tmp29
922 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
932 define void @queryne3b(i32 %x, i32 %n) nounwind {
933 ; X86-LABEL: queryne3b:
934 ; X86: # %bb.0: # %entry
935 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
936 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
937 ; X86-NEXT: btl %ecx, %eax
938 ; X86-NEXT: jb .LBB25_2
939 ; X86-NEXT: # %bb.1: # %bb
940 ; X86-NEXT: calll foo
941 ; X86-NEXT: .LBB25_2: # %UnifiedReturnBlock
944 ; X64-LABEL: queryne3b:
945 ; X64: # %bb.0: # %entry
946 ; X64-NEXT: btl %esi, %edi
947 ; X64-NEXT: jb .LBB25_2
948 ; X64-NEXT: # %bb.1: # %bb
949 ; X64-NEXT: pushq %rax
950 ; X64-NEXT: callq foo
951 ; X64-NEXT: popq %rax
952 ; X64-NEXT: .LBB25_2: # %UnifiedReturnBlock
955 %tmp29 = shl i32 1, %n
956 %tmp3 = and i32 %x, %tmp29
957 %tmp4 = icmp ne i32 %tmp3, %tmp29
958 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
968 define void @queryne3x(i32 %x, i32 %n) nounwind {
969 ; X86-LABEL: queryne3x:
970 ; X86: # %bb.0: # %entry
971 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
972 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
973 ; X86-NEXT: btl %ecx, %eax
974 ; X86-NEXT: jb .LBB26_2
975 ; X86-NEXT: # %bb.1: # %bb
976 ; X86-NEXT: calll foo
977 ; X86-NEXT: .LBB26_2: # %UnifiedReturnBlock
980 ; X64-LABEL: queryne3x:
981 ; X64: # %bb.0: # %entry
982 ; X64-NEXT: btl %esi, %edi
983 ; X64-NEXT: jb .LBB26_2
984 ; X64-NEXT: # %bb.1: # %bb
985 ; X64-NEXT: pushq %rax
986 ; X64-NEXT: callq foo
987 ; X64-NEXT: popq %rax
988 ; X64-NEXT: .LBB26_2: # %UnifiedReturnBlock
991 %tmp29 = shl i32 1, %n
992 %tmp3 = and i32 %tmp29, %x
993 %tmp4 = icmp ne i32 %tmp29, %tmp3
994 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
1004 define void @queryne3bx(i32 %x, i32 %n) nounwind {
1005 ; X86-LABEL: queryne3bx:
1006 ; X86: # %bb.0: # %entry
1007 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1008 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1009 ; X86-NEXT: btl %ecx, %eax
1010 ; X86-NEXT: jb .LBB27_2
1011 ; X86-NEXT: # %bb.1: # %bb
1012 ; X86-NEXT: calll foo
1013 ; X86-NEXT: .LBB27_2: # %UnifiedReturnBlock
1016 ; X64-LABEL: queryne3bx:
1017 ; X64: # %bb.0: # %entry
1018 ; X64-NEXT: btl %esi, %edi
1019 ; X64-NEXT: jb .LBB27_2
1020 ; X64-NEXT: # %bb.1: # %bb
1021 ; X64-NEXT: pushq %rax
1022 ; X64-NEXT: callq foo
1023 ; X64-NEXT: popq %rax
1024 ; X64-NEXT: .LBB27_2: # %UnifiedReturnBlock
1027 %tmp29 = shl i32 1, %n
1028 %tmp3 = and i32 %x, %tmp29
1029 %tmp4 = icmp ne i32 %tmp29, %tmp3
1030 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
1042 define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind {
1043 ; X86-LABEL: invert:
1045 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1046 ; X86-NEXT: notl %eax
1047 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1048 ; X86-NEXT: btl %ecx, %eax
1049 ; X86-NEXT: setb %al
1052 ; X64-LABEL: invert:
1054 ; X64-NEXT: notl %edi
1055 ; X64-NEXT: btl %esi, %edi
1056 ; X64-NEXT: setb %al
1058 %neg = xor i32 %flags, -1
1059 %shl = shl i32 1, %flag
1060 %and = and i32 %shl, %neg
1061 %tobool = icmp ne i32 %and, 0
1065 define zeroext i1 @extend(i32 %bit, i64 %bits) {
1066 ; X86-LABEL: extend:
1067 ; X86: # %bb.0: # %entry
1068 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1069 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1070 ; X86-NEXT: btl %ecx, %eax
1071 ; X86-NEXT: setb %al
1074 ; X64-LABEL: extend:
1075 ; X64: # %bb.0: # %entry
1076 ; X64-NEXT: btl %edi, %esi
1077 ; X64-NEXT: setb %al
1080 %and = and i32 %bit, 31
1081 %sh_prom = zext i32 %and to i64
1082 %shl = shl i64 1, %sh_prom
1083 %and1 = and i64 %shl, %bits
1084 %tobool = icmp ne i64 %and1, 0
1088 ; TODO: BT fails to look through to demanded bits as c%32 has more than one use.
1089 ; void demanded_i32(int *a, int *b, unsigned c) {
1090 ; if ((a[c/32] >> (c % 32)) & 1)
1091 ; b[c/32] |= 1 << (c % 32);
1093 define void @demanded_i32(i32* nocapture readonly, i32* nocapture, i32) nounwind {
1094 ; X86-LABEL: demanded_i32:
1096 ; X86-NEXT: pushl %esi
1097 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
1098 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1099 ; X86-NEXT: movl %ecx, %eax
1100 ; X86-NEXT: shrl $5, %eax
1101 ; X86-NEXT: movl (%edx,%eax,4), %esi
1102 ; X86-NEXT: movl $1, %edx
1103 ; X86-NEXT: shll %cl, %edx
1104 ; X86-NEXT: btl %ecx, %esi
1105 ; X86-NEXT: jae .LBB30_2
1106 ; X86-NEXT: # %bb.1:
1107 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1108 ; X86-NEXT: orl %edx, (%ecx,%eax,4)
1109 ; X86-NEXT: .LBB30_2:
1110 ; X86-NEXT: popl %esi
1113 ; X64-LABEL: demanded_i32:
1115 ; X64-NEXT: movl %edx, %ecx
1116 ; X64-NEXT: movl %edx, %eax
1117 ; X64-NEXT: shrl $5, %eax
1118 ; X64-NEXT: movl (%rdi,%rax,4), %edi
1119 ; X64-NEXT: movl $1, %edx
1120 ; X64-NEXT: shll %cl, %edx
1121 ; X64-NEXT: btl %ecx, %edi
1122 ; X64-NEXT: jae .LBB30_2
1123 ; X64-NEXT: # %bb.1:
1124 ; X64-NEXT: orl %edx, (%rsi,%rax,4)
1125 ; X64-NEXT: .LBB30_2:
1128 %5 = zext i32 %4 to i64
1129 %6 = getelementptr inbounds i32, i32* %0, i64 %5
1130 %7 = load i32, i32* %6, align 4
1133 %10 = and i32 %7, %9
1134 %11 = icmp eq i32 %10, 0
1135 br i1 %11, label %16, label %12
1138 %13 = getelementptr inbounds i32, i32* %1, i64 %5
1139 %14 = load i32, i32* %13, align 4
1140 %15 = or i32 %14, %9
1141 store i32 %15, i32* %13, align 4
1148 ; Make sure we can simplify bt when the shift amount has known zeros in it
1149 ; which cause the and mask to have bits removed.
1150 define zeroext i1 @demanded_with_known_zeroes(i32 %bit, i32 %bits) {
1151 ; X86-LABEL: demanded_with_known_zeroes:
1152 ; X86: # %bb.0: # %entry
1153 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
1154 ; X86-NEXT: shlb $2, %al
1155 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1156 ; X86-NEXT: movzbl %al, %eax
1157 ; X86-NEXT: btl %eax, %ecx
1158 ; X86-NEXT: setb %al
1161 ; X64-LABEL: demanded_with_known_zeroes:
1162 ; X64: # %bb.0: # %entry
1163 ; X64-NEXT: shll $2, %edi
1164 ; X64-NEXT: btl %edi, %esi
1165 ; X64-NEXT: setb %al
1168 %bit2 = shl i32 %bit, 2
1169 %and = and i32 %bit2, 31
1170 %shl = shl i32 1, %and
1171 %and1 = and i32 %shl, %bits
1172 %tobool = icmp ne i32 %and1, 0