@@ -660,71 +660,78 @@ define <8 x half> @fdiv_pow2_8xhalf(<8 x i16> %i) {
660660 ret <8 x half > %r
661661}
662662
663+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
664+ ; in the original IR.
663665define double @fmul_pow_shl_cnt (i64 %cnt ) nounwind {
664666; CHECK-SSE-LABEL: fmul_pow_shl_cnt:
665667; CHECK-SSE: # %bb.0:
666- ; CHECK-SSE-NEXT: shlq $52, %rdi
667- ; CHECK-SSE-NEXT: movabsq $4621256167635550208, %rax # imm = 0x4022000000000000
668- ; CHECK-SSE-NEXT: addq %rdi, %rax
669- ; CHECK-SSE-NEXT: movq %rax, %xmm0
668+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
669+ ; CHECK-SSE-NEXT: shlq $52, %rax
670+ ; CHECK-SSE-NEXT: movabsq $4621256167635550208, %rcx # imm = 0x4022000000000000
671+ ; CHECK-SSE-NEXT: addq %rax, %rcx
672+ ; CHECK-SSE-NEXT: movq %rcx, %xmm0
670673; CHECK-SSE-NEXT: retq
671674;
672675; CHECK-AVX-LABEL: fmul_pow_shl_cnt:
673676; CHECK-AVX: # %bb.0:
674- ; CHECK-AVX-NEXT: shlq $52, %rdi
675- ; CHECK-AVX-NEXT: movabsq $4621256167635550208, %rax # imm = 0x4022000000000000
676- ; CHECK-AVX-NEXT: addq %rdi, %rax
677- ; CHECK-AVX-NEXT: vmovq %rax, %xmm0
677+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
678+ ; CHECK-AVX-NEXT: shlq $52, %rax
679+ ; CHECK-AVX-NEXT: movabsq $4621256167635550208, %rcx # imm = 0x4022000000000000
680+ ; CHECK-AVX-NEXT: addq %rax, %rcx
681+ ; CHECK-AVX-NEXT: vmovq %rcx, %xmm0
678682; CHECK-AVX-NEXT: retq
679683 %shl = shl nuw i64 1 , %cnt
680684 %conv = uitofp i64 %shl to double
681685 %mul = fmul double 9 .000000e+00 , %conv
682686 ret double %mul
683687}
684688
689+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
690+ ; in the original IR.
685691define double @fmul_pow_shl_cnt2 (i64 %cnt ) nounwind {
686692; CHECK-SSE-LABEL: fmul_pow_shl_cnt2:
687693; CHECK-SSE: # %bb.0:
688- ; CHECK-SSE-NEXT: incl %edi
689- ; CHECK-SSE-NEXT: shlq $52, %rdi
690- ; CHECK-SSE-NEXT: movabsq $-4602115869219225600, %rax # imm = 0xC022000000000000
691- ; CHECK-SSE-NEXT: addq %rdi, %rax
692- ; CHECK-SSE-NEXT: movq %rax, %xmm0
694+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
695+ ; CHECK-SSE-NEXT: incl %eax
696+ ; CHECK-SSE-NEXT: shlq $52, %rax
697+ ; CHECK-SSE-NEXT: movabsq $-4602115869219225600, %rcx # imm = 0xC022000000000000
698+ ; CHECK-SSE-NEXT: addq %rax, %rcx
699+ ; CHECK-SSE-NEXT: movq %rcx, %xmm0
693700; CHECK-SSE-NEXT: retq
694701;
695702; CHECK-AVX-LABEL: fmul_pow_shl_cnt2:
696703; CHECK-AVX: # %bb.0:
697- ; CHECK-AVX-NEXT: incl %edi
698- ; CHECK-AVX-NEXT: shlq $52, %rdi
699- ; CHECK-AVX-NEXT: movabsq $-4602115869219225600, %rax # imm = 0xC022000000000000
700- ; CHECK-AVX-NEXT: addq %rdi, %rax
701- ; CHECK-AVX-NEXT: vmovq %rax, %xmm0
704+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
705+ ; CHECK-AVX-NEXT: incl %eax
706+ ; CHECK-AVX-NEXT: shlq $52, %rax
707+ ; CHECK-AVX-NEXT: movabsq $-4602115869219225600, %rcx # imm = 0xC022000000000000
708+ ; CHECK-AVX-NEXT: addq %rax, %rcx
709+ ; CHECK-AVX-NEXT: vmovq %rcx, %xmm0
702710; CHECK-AVX-NEXT: retq
703711 %shl = shl nuw i64 2 , %cnt
704712 %conv = uitofp i64 %shl to double
705713 %mul = fmul double -9 .000000e+00 , %conv
706714 ret double %mul
707715}
708716
709- ; FIXME: The zext of the input is being lost so the upper 4 bits of %rdi after
710- ; the shlq are garbage.
717+ ; Make sure we do a movzbl of the input register.
711718define double @fmul_pow_shl_cnt3 (i8 %cnt ) nounwind {
712719; CHECK-SSE-LABEL: fmul_pow_shl_cnt3:
713720; CHECK-SSE: # %bb.0:
714- ; CHECK-SSE-NEXT: # kill: def $edi killed $edi def $rdi
715- ; CHECK-SSE-NEXT: shlq $52, %rdi
716- ; CHECK-SSE-NEXT: movabsq $-4602115869219225600, %rax # imm = 0xC022000000000000
717- ; CHECK-SSE-NEXT: addq %rdi , %rax
718- ; CHECK-SSE-NEXT: movq %rax , %xmm0
721+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
722+ ; CHECK-SSE-NEXT: shlq $52, %rax
723+ ; CHECK-SSE-NEXT: movabsq $-4602115869219225600, %rcx # imm = 0xC022000000000000
724+ ; CHECK-SSE-NEXT: addq %rax , %rcx
725+ ; CHECK-SSE-NEXT: movq %rcx , %xmm0
719726; CHECK-SSE-NEXT: retq
720727;
721728; CHECK-AVX-LABEL: fmul_pow_shl_cnt3:
722729; CHECK-AVX: # %bb.0:
723- ; CHECK-AVX-NEXT: # kill: def $edi killed $edi def $rdi
724- ; CHECK-AVX-NEXT: shlq $52, %rdi
725- ; CHECK-AVX-NEXT: movabsq $-4602115869219225600, %rax # imm = 0xC022000000000000
726- ; CHECK-AVX-NEXT: addq %rdi , %rax
727- ; CHECK-AVX-NEXT: vmovq %rax , %xmm0
730+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
731+ ; CHECK-AVX-NEXT: shlq $52, %rax
732+ ; CHECK-AVX-NEXT: movabsq $-4602115869219225600, %rcx # imm = 0xC022000000000000
733+ ; CHECK-AVX-NEXT: addq %rax , %rcx
734+ ; CHECK-AVX-NEXT: vmovq %rcx , %xmm0
728735; CHECK-AVX-NEXT: retq
729736 %zext_cnt = zext i8 %cnt to i64
730737 %shl = shl nuw i64 1 , %zext_cnt
@@ -733,27 +740,29 @@ define double @fmul_pow_shl_cnt3(i8 %cnt) nounwind {
733740 ret double %mul
734741}
735742
743+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
744+ ; in the original IR.
736745define float @fmul_pow_select (i32 %cnt , i1 %c ) nounwind {
737746; CHECK-SSE-LABEL: fmul_pow_select:
738747; CHECK-SSE: # %bb.0:
739- ; CHECK-SSE-NEXT: # kill: def $edi killed $edi def $rdi
740- ; CHECK-SSE-NEXT: leal 1(%rdi ), %eax
748+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
749+ ; CHECK-SSE-NEXT: leal 1(%rax ), %ecx
741750; CHECK-SSE-NEXT: testb $1, %sil
742- ; CHECK-SSE-NEXT: cmovnel %edi , %eax
743- ; CHECK-SSE-NEXT: shll $23, %eax
744- ; CHECK-SSE-NEXT: addl $1091567616, %eax # imm = 0x41100000
745- ; CHECK-SSE-NEXT: movd %eax , %xmm0
751+ ; CHECK-SSE-NEXT: cmovnel %eax , %ecx
752+ ; CHECK-SSE-NEXT: shll $23, %ecx
753+ ; CHECK-SSE-NEXT: addl $1091567616, %ecx # imm = 0x41100000
754+ ; CHECK-SSE-NEXT: movd %ecx , %xmm0
746755; CHECK-SSE-NEXT: retq
747756;
748757; CHECK-AVX-LABEL: fmul_pow_select:
749758; CHECK-AVX: # %bb.0:
750- ; CHECK-AVX-NEXT: # kill: def $edi killed $edi def $rdi
751- ; CHECK-AVX-NEXT: leal 1(%rdi ), %eax
759+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
760+ ; CHECK-AVX-NEXT: leal 1(%rax ), %ecx
752761; CHECK-AVX-NEXT: testb $1, %sil
753- ; CHECK-AVX-NEXT: cmovnel %edi , %eax
754- ; CHECK-AVX-NEXT: shll $23, %eax
755- ; CHECK-AVX-NEXT: addl $1091567616, %eax # imm = 0x41100000
756- ; CHECK-AVX-NEXT: vmovd %eax , %xmm0
762+ ; CHECK-AVX-NEXT: cmovnel %eax , %ecx
763+ ; CHECK-AVX-NEXT: shll $23, %ecx
764+ ; CHECK-AVX-NEXT: addl $1091567616, %ecx # imm = 0x41100000
765+ ; CHECK-AVX-NEXT: vmovd %ecx , %xmm0
757766; CHECK-AVX-NEXT: retq
758767 %shl2 = shl nuw i32 2 , %cnt
759768 %shl1 = shl nuw i32 1 , %cnt
@@ -763,27 +772,31 @@ define float @fmul_pow_select(i32 %cnt, i1 %c) nounwind {
763772 ret float %mul
764773}
765774
775+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
776+ ; in the original IR.
766777define float @fmul_fly_pow_mul_min_pow2 (i64 %cnt ) nounwind {
767778; CHECK-SSE-LABEL: fmul_fly_pow_mul_min_pow2:
768779; CHECK-SSE: # %bb.0:
769- ; CHECK-SSE-NEXT: addl $3, %edi
770- ; CHECK-SSE-NEXT: cmpl $13, %edi
771- ; CHECK-SSE-NEXT: movl $13, %eax
772- ; CHECK-SSE-NEXT: cmovbl %edi, %eax
773- ; CHECK-SSE-NEXT: shll $23, %eax
774- ; CHECK-SSE-NEXT: addl $1091567616, %eax # imm = 0x41100000
775- ; CHECK-SSE-NEXT: movd %eax, %xmm0
780+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
781+ ; CHECK-SSE-NEXT: addl $3, %eax
782+ ; CHECK-SSE-NEXT: cmpl $13, %eax
783+ ; CHECK-SSE-NEXT: movl $13, %ecx
784+ ; CHECK-SSE-NEXT: cmovbl %eax, %ecx
785+ ; CHECK-SSE-NEXT: shll $23, %ecx
786+ ; CHECK-SSE-NEXT: addl $1091567616, %ecx # imm = 0x41100000
787+ ; CHECK-SSE-NEXT: movd %ecx, %xmm0
776788; CHECK-SSE-NEXT: retq
777789;
778790; CHECK-AVX-LABEL: fmul_fly_pow_mul_min_pow2:
779791; CHECK-AVX: # %bb.0:
780- ; CHECK-AVX-NEXT: addl $3, %edi
781- ; CHECK-AVX-NEXT: cmpl $13, %edi
782- ; CHECK-AVX-NEXT: movl $13, %eax
783- ; CHECK-AVX-NEXT: cmovbl %edi, %eax
784- ; CHECK-AVX-NEXT: shll $23, %eax
785- ; CHECK-AVX-NEXT: addl $1091567616, %eax # imm = 0x41100000
786- ; CHECK-AVX-NEXT: vmovd %eax, %xmm0
792+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
793+ ; CHECK-AVX-NEXT: addl $3, %eax
794+ ; CHECK-AVX-NEXT: cmpl $13, %eax
795+ ; CHECK-AVX-NEXT: movl $13, %ecx
796+ ; CHECK-AVX-NEXT: cmovbl %eax, %ecx
797+ ; CHECK-AVX-NEXT: shll $23, %ecx
798+ ; CHECK-AVX-NEXT: addl $1091567616, %ecx # imm = 0x41100000
799+ ; CHECK-AVX-NEXT: vmovd %ecx, %xmm0
787800; CHECK-AVX-NEXT: retq
788801 %shl8 = shl nuw i64 8 , %cnt
789802 %shl = call i64 @llvm.umin.i64 (i64 %shl8 , i64 8192 )
@@ -792,28 +805,30 @@ define float @fmul_fly_pow_mul_min_pow2(i64 %cnt) nounwind {
792805 ret float %mul
793806}
794807
808+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
809+ ; in the original IR.
795810define double @fmul_pow_mul_max_pow2 (i16 %cnt ) nounwind {
796811; CHECK-SSE-LABEL: fmul_pow_mul_max_pow2:
797812; CHECK-SSE: # %bb.0:
798- ; CHECK-SSE-NEXT: movl %edi , %eax
813+ ; CHECK-SSE-NEXT: movzbl %dil , %eax
799814; CHECK-SSE-NEXT: leaq 1(%rax), %rcx
800815; CHECK-SSE-NEXT: cmpq %rcx, %rax
801816; CHECK-SSE-NEXT: cmovaq %rax, %rcx
802817; CHECK-SSE-NEXT: shlq $52, %rcx
803818; CHECK-SSE-NEXT: movabsq $4613937818241073152, %rax # imm = 0x4008000000000000
804- ; CHECK-SSE-NEXT: addq %rcx, %rax
819+ ; CHECK-SSE-NEXT: orq %rcx, %rax
805820; CHECK-SSE-NEXT: movq %rax, %xmm0
806821; CHECK-SSE-NEXT: retq
807822;
808823; CHECK-AVX-LABEL: fmul_pow_mul_max_pow2:
809824; CHECK-AVX: # %bb.0:
810- ; CHECK-AVX-NEXT: movl %edi , %eax
825+ ; CHECK-AVX-NEXT: movzbl %dil , %eax
811826; CHECK-AVX-NEXT: leaq 1(%rax), %rcx
812827; CHECK-AVX-NEXT: cmpq %rcx, %rax
813828; CHECK-AVX-NEXT: cmovaq %rax, %rcx
814829; CHECK-AVX-NEXT: shlq $52, %rcx
815830; CHECK-AVX-NEXT: movabsq $4613937818241073152, %rax # imm = 0x4008000000000000
816- ; CHECK-AVX-NEXT: addq %rcx, %rax
831+ ; CHECK-AVX-NEXT: orq %rcx, %rax
817832; CHECK-AVX-NEXT: vmovq %rax, %xmm0
818833; CHECK-AVX-NEXT: retq
819834 %shl2 = shl nuw i16 2 , %cnt
@@ -1188,23 +1203,25 @@ define double @fmul_pow_shl_cnt_fail_maybe_bad_exp(i64 %cnt) nounwind {
11881203 ret double %mul
11891204}
11901205
1206+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
1207+ ; in the original IR.
11911208define double @fmul_pow_shl_cnt_safe (i16 %cnt ) nounwind {
11921209; CHECK-SSE-LABEL: fmul_pow_shl_cnt_safe:
11931210; CHECK-SSE: # %bb.0:
1194- ; CHECK-SSE-NEXT: # kill: def $edi killed $edi def $rdi
1195- ; CHECK-SSE-NEXT: shlq $52, %rdi
1196- ; CHECK-SSE-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
1197- ; CHECK-SSE-NEXT: addq %rdi , %rax
1198- ; CHECK-SSE-NEXT: movq %rax , %xmm0
1211+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
1212+ ; CHECK-SSE-NEXT: shlq $52, %rax
1213+ ; CHECK-SSE-NEXT: movabsq $8930638061065157010, %rcx # imm = 0x7BEFFFFFFF5F3992
1214+ ; CHECK-SSE-NEXT: addq %rax , %rcx
1215+ ; CHECK-SSE-NEXT: movq %rcx , %xmm0
11991216; CHECK-SSE-NEXT: retq
12001217;
12011218; CHECK-AVX-LABEL: fmul_pow_shl_cnt_safe:
12021219; CHECK-AVX: # %bb.0:
1203- ; CHECK-AVX-NEXT: # kill: def $edi killed $edi def $rdi
1204- ; CHECK-AVX-NEXT: shlq $52, %rdi
1205- ; CHECK-AVX-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
1206- ; CHECK-AVX-NEXT: addq %rdi , %rax
1207- ; CHECK-AVX-NEXT: vmovq %rax , %xmm0
1220+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
1221+ ; CHECK-AVX-NEXT: shlq $52, %rax
1222+ ; CHECK-AVX-NEXT: movabsq $8930638061065157010, %rcx # imm = 0x7BEFFFFFFF5F3992
1223+ ; CHECK-AVX-NEXT: addq %rax , %rcx
1224+ ; CHECK-AVX-NEXT: vmovq %rcx , %xmm0
12081225; CHECK-AVX-NEXT: retq
12091226 %shl = shl nuw i16 1 , %cnt
12101227 %conv = uitofp i16 %shl to double
@@ -1572,23 +1589,25 @@ define half @fdiv_pow_shl_cnt_fail_out_of_bound2(i16 %cnt) nounwind {
15721589 ret half %mul
15731590}
15741591
1592+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
1593+ ; in the original IR.
15751594define double @fdiv_pow_shl_cnt32_to_dbl_okay (i32 %cnt ) nounwind {
15761595; CHECK-SSE-LABEL: fdiv_pow_shl_cnt32_to_dbl_okay:
15771596; CHECK-SSE: # %bb.0:
1578- ; CHECK-SSE-NEXT: # kill: def $edi killed $edi def $rdi
1579- ; CHECK-SSE-NEXT: shlq $52, %rdi
1580- ; CHECK-SSE-NEXT: movabsq $3936146074321813504, %rax # imm = 0x36A0000000000000
1581- ; CHECK-SSE-NEXT: subq %rdi , %rax
1582- ; CHECK-SSE-NEXT: movq %rax , %xmm0
1597+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
1598+ ; CHECK-SSE-NEXT: shlq $52, %rax
1599+ ; CHECK-SSE-NEXT: movabsq $3936146074321813504, %rcx # imm = 0x36A0000000000000
1600+ ; CHECK-SSE-NEXT: subq %rax , %rcx
1601+ ; CHECK-SSE-NEXT: movq %rcx , %xmm0
15831602; CHECK-SSE-NEXT: retq
15841603;
15851604; CHECK-AVX-LABEL: fdiv_pow_shl_cnt32_to_dbl_okay:
15861605; CHECK-AVX: # %bb.0:
1587- ; CHECK-AVX-NEXT: # kill: def $edi killed $edi def $rdi
1588- ; CHECK-AVX-NEXT: shlq $52, %rdi
1589- ; CHECK-AVX-NEXT: movabsq $3936146074321813504, %rax # imm = 0x36A0000000000000
1590- ; CHECK-AVX-NEXT: subq %rdi , %rax
1591- ; CHECK-AVX-NEXT: vmovq %rax , %xmm0
1606+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
1607+ ; CHECK-AVX-NEXT: shlq $52, %rax
1608+ ; CHECK-AVX-NEXT: movabsq $3936146074321813504, %rcx # imm = 0x36A0000000000000
1609+ ; CHECK-AVX-NEXT: subq %rax , %rcx
1610+ ; CHECK-AVX-NEXT: vmovq %rcx , %xmm0
15921611; CHECK-AVX-NEXT: retq
15931612 %shl = shl nuw i32 1 , %cnt
15941613 %conv = uitofp i32 %shl to double
@@ -1644,21 +1663,25 @@ define float @fdiv_pow_shl_cnt32_out_of_bounds2(i32 %cnt) nounwind {
16441663 ret float %mul
16451664}
16461665
1666+ ; FIXME: The movzbl is unnecessary. It would be UB for the upper bits to be set
1667+ ; in the original IR.
16471668define float @fdiv_pow_shl_cnt32_okay (i32 %cnt ) nounwind {
16481669; CHECK-SSE-LABEL: fdiv_pow_shl_cnt32_okay:
16491670; CHECK-SSE: # %bb.0:
1650- ; CHECK-SSE-NEXT: shll $23, %edi
1651- ; CHECK-SSE-NEXT: movl $285212672, %eax # imm = 0x11000000
1652- ; CHECK-SSE-NEXT: subl %edi, %eax
1653- ; CHECK-SSE-NEXT: movd %eax, %xmm0
1671+ ; CHECK-SSE-NEXT: movzbl %dil, %eax
1672+ ; CHECK-SSE-NEXT: shll $23, %eax
1673+ ; CHECK-SSE-NEXT: movl $285212672, %ecx # imm = 0x11000000
1674+ ; CHECK-SSE-NEXT: subl %eax, %ecx
1675+ ; CHECK-SSE-NEXT: movd %ecx, %xmm0
16541676; CHECK-SSE-NEXT: retq
16551677;
16561678; CHECK-AVX-LABEL: fdiv_pow_shl_cnt32_okay:
16571679; CHECK-AVX: # %bb.0:
1658- ; CHECK-AVX-NEXT: shll $23, %edi
1659- ; CHECK-AVX-NEXT: movl $285212672, %eax # imm = 0x11000000
1660- ; CHECK-AVX-NEXT: subl %edi, %eax
1661- ; CHECK-AVX-NEXT: vmovd %eax, %xmm0
1680+ ; CHECK-AVX-NEXT: movzbl %dil, %eax
1681+ ; CHECK-AVX-NEXT: shll $23, %eax
1682+ ; CHECK-AVX-NEXT: movl $285212672, %ecx # imm = 0x11000000
1683+ ; CHECK-AVX-NEXT: subl %eax, %ecx
1684+ ; CHECK-AVX-NEXT: vmovd %ecx, %xmm0
16621685; CHECK-AVX-NEXT: retq
16631686 %shl = shl nuw i32 1 , %cnt
16641687 %conv = uitofp i32 %shl to float
0 commit comments