commit 7bf2612d5fc80eb3735ef2288e36a1d6da235732
parent cfd2a9855605d99afee434be297844f6ae095756
Author: André Bargull <andre.bargull@gmail.com>
Date: Tue, 11 Nov 2025 12:29:35 +0000
Bug 1998161 - Part 4: Merge shifts for division by constants for x64. r=iain
Otherwise we can end up performing two consecutive right-shifts.
Also don't emit shifts with a zero shift amount.
Differential Revision: https://phabricator.services.mozilla.com/D271432
Diffstat:
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -1020,7 +1020,9 @@ static void UnsignedDivideWithConstant(MacroAssembler& masm, LUDivOrUMod* ins,
masm.movl(Imm32(rmc.multiplier), temp);
masm.imulq(temp, result);
}
- masm.shrq(Imm32(32), result);
+ if (rmc.multiplier > UINT32_MAX || rmc.shiftAmount == 0) {
+ masm.shrq(Imm32(32), result);
+ }
#endif
if (rmc.multiplier > UINT32_MAX) {
// M >= 2^32 and shift == 0 is impossible, as d >= 2 implies that
@@ -1044,9 +1046,17 @@ static void UnsignedDivideWithConstant(MacroAssembler& masm, LUDivOrUMod* ins,
// Finish the computation.
masm.addl(temp, result);
- masm.shrl(Imm32(rmc.shiftAmount - 1), result);
+ if (rmc.shiftAmount > 1) {
+ masm.shrl(Imm32(rmc.shiftAmount - 1), result);
+ }
} else {
- masm.shrl(Imm32(rmc.shiftAmount), result);
+ if (rmc.shiftAmount > 0) {
+#ifdef JS_CODEGEN_X86
+ masm.shrl(Imm32(rmc.shiftAmount), result);
+#else
+ masm.shrq(Imm32(32 + rmc.shiftAmount), result);
+#endif
+ }
}
}
@@ -1236,7 +1246,9 @@ static void DivideWithConstant(MacroAssembler& masm, LDivOrMod* ins,
// Sign-extend |lhs| in preparation for a 64-bit multiplication.
masm.movslq(lhs, result);
masm.imulq(Imm32(rmc.multiplier), result, result);
- masm.shrq(Imm32(32), result);
+ if (rmc.multiplier > INT32_MAX || rmc.shiftAmount == 0) {
+ masm.shrq(Imm32(32), result);
+ }
#endif
if (rmc.multiplier > INT32_MAX) {
MOZ_ASSERT(rmc.multiplier < (int64_t(1) << 32));
@@ -1250,7 +1262,17 @@ static void DivideWithConstant(MacroAssembler& masm, LDivOrMod* ins,
// (M * n) >> (32 + shift) is the truncated division answer if n is
// non-negative, as proved in the comments of computeDivisionConstants. We
// must add 1 later if n is negative to get the right answer in all cases.
- masm.sarl(Imm32(rmc.shiftAmount), result);
+ if (rmc.shiftAmount > 0) {
+#ifdef JS_CODEGEN_X86
+ masm.sarl(Imm32(rmc.shiftAmount), result);
+#else
+ if (rmc.multiplier > INT32_MAX) {
+ masm.sarl(Imm32(rmc.shiftAmount), result);
+ } else {
+ masm.sarq(Imm32(32 + rmc.shiftAmount), result);
+ }
+#endif
+ }
// We'll subtract -1 instead of adding 1, because (n < 0 ? -1 : 0) can be
// computed with just a sign-extending shift of 31 bits.