Bug 1550751 - Skip rounding the dividend of non-truncated integer division, as already handled by a bailout. r=mgaudet

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas B. Pierron 2019-05-20 13:02:43 +00:00
Родитель 132d447ea6
Коммит d9f43206ff
2 изменённых файлов: 17 добавлений и 4 удалений

Просмотреть файл

@ -1208,13 +1208,22 @@ void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) {
// rounded result when the numerator is negative. See 10-1
// "Signed Division by a Known Power of 2" in Henry
// S. Warren, Jr.'s Hacker's Delight.
if (mir->canBeNegativeDividend()) {
if (mir->canBeNegativeDividend() && mir->isTruncated()) {
// Note: There is no need to execute this code, which handles how to
// round the signed integer division towards 0, if we previously bailed
// due to a non-zero remainder.
Register lhsCopy = ToRegister(ins->numeratorCopy());
MOZ_ASSERT(lhsCopy != lhs);
if (shift > 1) {
// Copy the sign bit of the numerator. (= (2^32 - 1) or 0)
masm.sarl(Imm32(31), lhs);
}
// Divide by 2^(32 - shift)
// i.e. (= (2^32 - 1) / 2^(32 - shift) or 0)
// i.e. (= (2^shift - 1) or 0)
masm.shrl(Imm32(32 - shift), lhs);
// If signed, make any 1 bit below the shifted bits to bubble up, such
// that once shifted the value would be rounded towards 0.
masm.addl(lhsCopy, lhs);
}
masm.sarl(Imm32(shift), lhs);

Просмотреть файл

@ -173,12 +173,16 @@ void LIRGeneratorX86Shared::lowerDivI(MDiv* div) {
if (rhs != 0 && uint32_t(1) << shift == Abs(rhs)) {
LAllocation lhs = useRegisterAtStart(div->lhs());
LDivPowTwoI* lir;
if (!div->canBeNegativeDividend()) {
// When truncated with maybe a non-zero remainder, we have to round the
// result toward 0. This requires an extra register to round up/down
// whether the left-hand-side is signed.
bool needRoundNeg = div->canBeNegativeDividend() && div->isTruncated();
if (!needRoundNeg) {
// Numerator is unsigned, so does not need adjusting.
lir = new (alloc()) LDivPowTwoI(lhs, lhs, shift, rhs < 0);
} else {
// Numerator is signed, and needs adjusting, and an extra
// lhs copy register is needed.
// Numerator might be signed, and needs adjusting, and an extra lhs copy
// is needed to round the result of the integer division towards zero.
lir = new (alloc())
LDivPowTwoI(lhs, useRegister(div->lhs()), shift, rhs < 0);
}