Fix an error in optimized modulus operator, add unit test.
Review URL: http://codereview.chromium.org/1118008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4235 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
01bcdbcdb1
commit
c3b5e22764
@ -7380,6 +7380,15 @@ void CodeGenerator::Int32BinaryOperation(BinaryOperation* node) {
|
||||
__ cdq(); // Sign-extend eax into edx:eax
|
||||
__ idiv(right_reg);
|
||||
if (op == Token::MOD) {
|
||||
// Negative zero can arise as a negative divident with a zero result.
|
||||
if (!node->no_negative_zero()) {
|
||||
Label not_negative_zero;
|
||||
__ test(edx, Operand(edx));
|
||||
__ j(not_zero, ¬_negative_zero);
|
||||
__ test(eax, Operand(eax));
|
||||
unsafe_bailout_->Branch(negative);
|
||||
__ bind(¬_negative_zero);
|
||||
}
|
||||
Result edx_result(edx, NumberInfo::Integer32());
|
||||
edx_result.set_untagged_int32(true);
|
||||
frame_->Push(&edx_result);
|
||||
|
@ -169,3 +169,24 @@ function compute_mod(dividend, divisor) {
|
||||
assertEquals(somenum, somenum % -0x40000000, "%minsmi-32");
|
||||
assertEquals(somenum, somenum % -0x80000000, "%minsmi-64");
|
||||
})();
|
||||
|
||||
|
||||
// Side-effect-free expressions containing bit operations use
|
||||
// an optimized compiler with int32 values. Ensure that modulus
|
||||
// produces negative zeros correctly.
|
||||
function negative_zero_modulus_test() {
|
||||
var x = 4;
|
||||
var y = -4;
|
||||
x = x + x - x;
|
||||
y = y + y - y;
|
||||
var z = (y | y | y | y) % x;
|
||||
assertEquals(-1 / 0, 1 / z);
|
||||
z = (x | x | x | x) % x;
|
||||
assertEquals(1 / 0, 1 / z);
|
||||
z = (y | y | y | y) % y;
|
||||
assertEquals(-1 / 0, 1 / z);
|
||||
z = (x | x | x | x) % y;
|
||||
assertEquals(1 / 0, 1 / z);
|
||||
}
|
||||
|
||||
negative_zero_modulus_test();
|
||||
|
Loading…
Reference in New Issue
Block a user