* src/hydrogen-instructions.cc (HValue::InferRange): Only mark values
with int32 representation as never being -0. Always return a non-NULL
value; callers should check for representation().IsNone() if that's
their concern.
In practice these invariants were not violated by callers, but they
were sometimes two calls away, which seems brittle.
BUG=
TEST=tests pass, modulo http://code.google.com/p/v8/issues/detail?id=1572
Review URL: http://codereview.chromium.org/7514040
Patch from Andy Wingo <wingo@igalia.com>.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8804
ce2b1a6d-e550-0410-aec6-
3dcde31c8c00
Range* HValue::InferRange() {
- if (representation().IsTagged()) {
- // Tagged values are always in int32 range when converted to integer,
- // but they can contain -0.
- Range* result = new Range();
- result->set_can_be_minus_zero(true);
- return result;
- } else if (representation().IsNone()) {
- return NULL;
- } else {
- // Untagged integer32 cannot be -0 and we don't compute ranges for
- // untagged doubles.
- return new Range();
- }
+ // Untagged integer32 cannot be -0, all other representations can.
+ Range* result = new Range();
+ result->set_can_be_minus_zero(!representation().IsInteger32());
+ return result;
}
testFloor(-Infinity, -Infinity);
testFloor(NaN, NaN);
+ // Ensure that a negative zero coming from Math.floor is properly handled
+ // by other operations.
+ function ifloor(x) {
+ return 1 / Math.floor(x);
+ }
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ %OptimizeFunctionOnNextCall(ifloor);
+ assertEquals(-Infinity, ifloor(-0));
+
testFloor(0, 0.1);
testFloor(0, 0.49999999999999994);
testFloor(0, 0.5);
for (var i = 0; i < 500; i++) {
test();
}
+
+
+// Regression test for a bug where a negative zero coming from Math.floor
+// was not properly handled by other operations.
+function floorsum(i, n) {
+ var ret = Math.floor(n);
+ while (--i > 0) {
+ ret += Math.floor(n);
+ }
+ return ret;
+}
+assertEquals(-0, floorsum(1, -0));
+%OptimizeFunctionOnNextCall(floorsum);
+// The optimized function will deopt. Run it with enough iterations to try
+// to optimize via OSR (triggering the bug).
+assertEquals(-0, floorsum(100000, -0));
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
testRound(-Infinity, -Infinity);
testRound(NaN, NaN);
+// Regression test for a bug where a negative zero coming from Math.round
+// was not properly handled by other operations.
+function roundsum(i, n) {
+ var ret = Math.round(n);
+ while (--i > 0) {
+ ret += Math.round(n);
+ }
+ return ret;
+}
+assertEquals(-0, roundsum(1, -0));
+%OptimizeFunctionOnNextCall(roundsum);
+// The optimized function will deopt. Run it with enough iterations to try
+// to optimize via OSR (triggering the bug).
+assertEquals(-0, roundsum(100000, -0));
+
testRound(1, 0.5);
testRound(1, 0.7);
testRound(1, 1);