tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit d48bfd57f35248fecc074c5cb20080ccf1085d65
parent 7768107fde9612324a6d1300c3592c1389198264
Author: André Bargull <andre.bargull@gmail.com>
Date:   Mon, 10 Nov 2025 15:13:43 +0000

Bug 1998457 - Part 5: Don't generate unnecessary code for modulus by one. r=spidermonkey-reviewers,iain

The 64-bit code added in parts 3-4 handle these cases, too.

Differential Revision: https://phabricator.services.mozilla.com/D271441

Diffstat:
Mjs/src/jit/arm64/CodeGenerator-arm64.cpp | 8++++++++
Mjs/src/jit/x86-shared/CodeGenerator-x86-shared.cpp | 35+++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/js/src/jit/arm64/CodeGenerator-arm64.cpp b/js/src/jit/arm64/CodeGenerator-arm64.cpp @@ -923,6 +923,14 @@ void CodeGenerator::visitModPowTwoI(LModPowTwoI* ins) { bool canBeNegative = !ins->mir()->isUnsigned() && ins->mir()->canBeNegativeDividend(); + if (shift == 0) { + if (canBeNegative && !ins->mir()->isTruncated()) { + bailoutTest32(Assembler::Signed, lhs, lhs, ins->snapshot()); + } + masm.Mov(outw, wzr); + return; + } + Label negative; if (canBeNegative) { // Switch based on sign of the lhs. diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp @@ -1447,18 +1447,45 @@ void CodeGenerator::visitDivI(LDivI* ins) { void CodeGenerator::visitModPowTwoI(LModPowTwoI* ins) { Register lhs = ToRegister(ins->input()); int32_t shift = ins->shift(); + bool canBeNegative = + !ins->mir()->isUnsigned() && ins->mir()->canBeNegativeDividend(); + + if (shift == 0) { + if (canBeNegative && !ins->mir()->isTruncated()) { + bailoutTest32(Assembler::Signed, lhs, lhs, ins->snapshot()); + } + masm.xorl(lhs, lhs); + return; + } + + auto clearHighBits = [&]() { + switch (shift) { + case 16: + masm.movzwl(lhs, lhs); + break; + case 8: + if (AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(lhs)) { + masm.movzbl(lhs, lhs); + break; + } + [[fallthrough]]; + default: + masm.andl(Imm32((uint32_t(1) << shift) - 1), lhs); + break; + } + }; Label negative; - if (!ins->mir()->isUnsigned() && ins->mir()->canBeNegativeDividend()) { + if (canBeNegative) { // Switch based on sign of the lhs. // Positive numbers are just a bitmask masm.branchTest32(Assembler::Signed, lhs, lhs, &negative); } - masm.andl(Imm32((uint32_t(1) << shift) - 1), lhs); + clearHighBits(); - if (!ins->mir()->isUnsigned() && ins->mir()->canBeNegativeDividend()) { + if (canBeNegative) { Label done; masm.jump(&done); @@ -1472,7 +1499,7 @@ void CodeGenerator::visitModPowTwoI(LModPowTwoI* ins) { // The negl instruction overflows if lhs == INT32_MIN, but this is also not // a problem: shift is at most 31, and so the andl also always returns 0. masm.negl(lhs); - masm.andl(Imm32((uint32_t(1) << shift) - 1), lhs); + clearHighBits(); masm.negl(lhs); // Since a%b has the same sign as b, and a is negative in this branch,