Bug 1122403 - IonMonkey: Fix folding of unsigned Div and Mod r=nbp

This commit is contained in:
Dan Gohman 2015-01-22 21:22:10 -08:00
parent 604504d962
commit a27875f30d
2 changed files with 58 additions and 2 deletions

View File

@ -144,10 +144,16 @@ EvaluateConstantOperands(TempAllocator &alloc, MBinaryInstruction *ins, bool *pt
ret.setNumber(lhs.toNumber() * rhs.toNumber());
break;
case MDefinition::Op_Div:
ret.setNumber(NumberDiv(lhs.toNumber(), rhs.toNumber()));
if (ins->toDiv()->isUnsigned())
ret.setInt32(rhs.isInt32(0) ? 0 : uint32_t(lhs.toInt32()) / uint32_t(rhs.toInt32()));
else
ret.setNumber(NumberDiv(lhs.toNumber(), rhs.toNumber()));
break;
case MDefinition::Op_Mod:
ret.setNumber(NumberMod(lhs.toNumber(), rhs.toNumber()));
if (ins->toMod()->isUnsigned())
ret.setInt32(rhs.isInt32(0) ? 0 : uint32_t(lhs.toInt32()) % uint32_t(rhs.toInt32()));
else
ret.setNumber(NumberMod(lhs.toNumber(), rhs.toNumber()));
break;
default:
MOZ_CRASH("NYI");

View File

@ -201,3 +201,53 @@ BEGIN_TEST(testJitNotNotTest)
return true;
}
END_TEST(testJitNotNotTest)
BEGIN_TEST(testJitFoldsTo_UnsignedDiv)
{
MinimalFunc func;
MBasicBlock *block = func.createEntryBlock();
// return 1.0 / 0xffffffff
MConstant *c0 = MConstant::New(func.alloc, Int32Value(1));
block->add(c0);
MConstant *c1 = MConstant::New(func.alloc, Int32Value(0xffffffff));
block->add(c1);
MDiv *div = MDiv::NewAsmJS(func.alloc, c0, c1, MIRType_Int32, /*unsignd=*/true);
block->add(div);
MReturn *ret = MReturn::New(func.alloc, div);
block->end(ret);
if (!func.runGVN())
return false;
// Test that the div got folded to 0.
MConstant *op = ret->getOperand(0)->toConstant();
CHECK(mozilla::NumbersAreIdentical(op->value().toNumber(), 0.0));
return true;
}
END_TEST(testJitFoldsTo_UnsignedDiv)
BEGIN_TEST(testJitFoldsTo_UnsignedMod)
{
MinimalFunc func;
MBasicBlock *block = func.createEntryBlock();
// return 1.0 % 0xffffffff
MConstant *c0 = MConstant::New(func.alloc, Int32Value(1));
block->add(c0);
MConstant *c1 = MConstant::New(func.alloc, Int32Value(0xffffffff));
block->add(c1);
MMod *mod = MMod::NewAsmJS(func.alloc, c0, c1, MIRType_Int32, /*unsignd=*/true);
block->add(mod);
MReturn *ret = MReturn::New(func.alloc, mod);
block->end(ret);
if (!func.runGVN())
return false;
// Test that the mod got folded to 1.
MConstant *op = ret->getOperand(0)->toConstant();
CHECK(mozilla::NumbersAreIdentical(op->value().toNumber(), 1.0));
return true;
}
END_TEST(testJitFoldsTo_UnsignedMod)