author | Dan Gohman <sunfish@google.com> |
Mon, 21 Oct 2013 13:04:15 -0700 | |
changeset 151601 | ce54c42790f64757ed5cdc69b3fe61a7a9fbf477 |
parent 151600 | ec37f434044acfde23203d4a8b267689becc8109 |
child 151602 | 3f03e8b077ca29eef3b7dbdf2fddfbd794cb88b7 |
push id | 25503 |
push user | kwierso@gmail.com |
push date | Tue, 22 Oct 2013 22:12:07 +0000 |
treeherder | mozilla-central@31382b5fa51e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 927389 |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug927389.js @@ -0,0 +1,6 @@ +(function() { + "use asm" + function f() { + +~~1.1 + } +})()
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug927389.js @@ -0,0 +1,4 @@ +(function () { + var x = 0 || 1.1; + x >> x; +})();
--- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -384,26 +384,18 @@ Range::intersect(const Range *lhs, const // possible that we will have computed a newExponent that's more precise // than our newLower and newUpper. This is unusual, so we handle it here // instead of in optimize(). // // For example, when the floating-point range has an actual maximum value // of 1.5, it may have a range like [0,2] and the max_exponent may be zero. // When intersecting such a range with an integer range, the fractional part // of the range is dropped, but the max exponent of 0 remains valid. - if (lhs->canHaveFractionalPart_ != rhs->canHaveFractionalPart_ && - newExponent < MaxInt32Exponent) - { - // pow(2, newExponent+1)-1 to compute the maximum value for newExponent. - int32_t limit = (uint32_t(1) << (newExponent + 1)) - 1; - if (limit != INT32_MIN) { - newUpper = Min(newUpper, limit); - newLower = Max(newLower, -limit); - } - } + if (lhs->canHaveFractionalPart_ != rhs->canHaveFractionalPart_) + refineInt32BoundsByExponent(newExponent, &newLower, &newUpper); return new Range(newLower, newHasInt32LowerBound, newUpper, newHasInt32UpperBound, newFractional, newExponent); } void Range::unionWith(const Range *other) { @@ -1936,20 +1928,27 @@ Range::clampToInt32() int32_t l = hasInt32LowerBound() ? lower() : JSVAL_INT_MIN; int32_t h = hasInt32UpperBound() ? upper() : JSVAL_INT_MAX; setInt32(l, h); } void Range::wrapAroundToInt32() { - if (!hasInt32Bounds()) + if (!hasInt32Bounds()) { setInt32(JSVAL_INT_MIN, JSVAL_INT_MAX); - else if (canHaveFractionalPart()) + } else if (canHaveFractionalPart()) { canHaveFractionalPart_ = false; + + // Clearing the fractional field may provide an opportunity to refine + // lower_ or upper_. + refineInt32BoundsByExponent(max_exponent_, &lower_, &upper_); + + assertInvariants(); + } } void Range::wrapAroundToShiftCount() { wrapAroundToInt32(); if (lower() < 0 || upper() >= 32) setInt32(0, 31);
--- a/js/src/jit/RangeAnalysis.h +++ b/js/src/jit/RangeAnalysis.h @@ -249,16 +249,34 @@ class Range : public TempObject { uint16_t exponentImpliedByInt32Bounds() const { // The number of bits needed to encode |max| is the power of 2 plus one. uint32_t max = Max(mozilla::Abs(lower()), mozilla::Abs(upper())); uint16_t result = mozilla::FloorLog2(max); JS_ASSERT(result == (max == 0 ? 0 : mozilla::ExponentComponent(double(max)))); return result; } + // When converting a range which contains fractional values to a range + // containing only integers, the old max_exponent_ value may imply a better + // lower and/or upper bound than was previously available, because they no + // longer need to be conservative about fractional offsets and the ends of + // the range. + // + // Given an exponent value and pointers to the lower and upper bound values, + // this function refines the lower and upper bound values to the tighest + // bound for integer values implied by the exponent. + static void refineInt32BoundsByExponent(uint16_t e, int32_t *l, int32_t *h) { + if (e < MaxInt32Exponent) { + // pow(2, max_exponent_+1)-1 to compute a maximum absolute value. + int32_t limit = (uint32_t(1) << (e + 1)) - 1; + *h = Min(*h, limit); + *l = Max(*l, -limit); + } + } + // If the value of any of the fields implies a stronger possible value for // any other field, update that field to the stronger value. The range must // be completely valid before and it is guaranteed to be kept valid. void optimize() { assertInvariants(); if (hasInt32Bounds()) { // Examine lower() and upper(), and if they imply a better exponent