diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 2a25169c5085..fc400485493f 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -2403,7 +2403,8 @@ class MAdd : public MBinaryArithInstruction return false; Range *left = getOperand(0)->range(); Range *right = getOperand(1)->range(); - return range()->update(Range::add(left, right)); + Range next = isTruncated() ? Range::addTruncate(left,right) : Range::add(left, right); + return range()->update(next); } }; @@ -2445,7 +2446,8 @@ class MSub : public MBinaryArithInstruction return false; Range *left = getOperand(0)->range(); Range *right = getOperand(1)->range(); - return range()->update(Range::sub(left, right)); + Range next = isTruncated() ? Range::subTruncate(left,right) : Range::sub(left, right); + return range()->update(next); } }; diff --git a/js/src/ion/RangeAnalysis.cpp b/js/src/ion/RangeAnalysis.cpp index 329363c4388d..4ec201b4e75d 100644 --- a/js/src/ion/RangeAnalysis.cpp +++ b/js/src/ion/RangeAnalysis.cpp @@ -156,7 +156,7 @@ RangeAnalysis::addBetaNobes() if (jsop == JSOP_LT) { smaller = left; greater = right; - } else if (JSOP_GT) { + } else if (jsop == JSOP_GT) { smaller = right; greater = left; } @@ -321,6 +321,22 @@ Range::sub(const Range *lhs, const Range *rhs) return ret; } +Range +Range::addTruncate(const Range *lhs, const Range *rhs) +{ + Range ret = Truncate((int64_t)lhs->lower_ + (int64_t)rhs->lower_, + (int64_t)lhs->upper_ + (int64_t)rhs->upper_); + return ret; +} + +Range +Range::subTruncate(const Range *lhs, const Range *rhs) +{ + Range ret = Truncate((int64_t)lhs->lower_ - (int64_t)rhs->upper_, + (int64_t)lhs->upper_ - (int64_t)rhs->lower_); + return ret; +} + Range Range::and_(const Range *lhs, const Range *rhs) { diff --git a/js/src/ion/RangeAnalysis.h b/js/src/ion/RangeAnalysis.h index e5162effeec1..8218c4a8c43f 100644 --- a/js/src/ion/RangeAnalysis.h +++ b/js/src/ion/RangeAnalysis.h @@ -88,6 +88,14 @@ class Range { upper_(other.upper_), upper_infinite_(other.upper_infinite_) {} + static Range Truncate(int64_t l, int64_t h) { + Range ret(l,h); + if (!ret.isFinite()) { + ret.makeLowerInfinite(); + ret.makeUpperInfinite(); + } + return ret; + } static int64_t abs64(int64_t x) { #ifdef WTF_OS_WINDOWS @@ -110,6 +118,8 @@ class Range { void unionWith(const Range *other); void unionWith(RangeChangeCount *other); static Range intersect(const Range *lhs, const Range *rhs, bool *nullRange); + static Range addTruncate(const Range *lhs, const Range *rhs); + static Range subTruncate(const Range *lhs, const Range *rhs); static Range add(const Range *lhs, const Range *rhs); static Range sub(const Range *lhs, const Range *rhs); static Range mul(const Range *lhs, const Range *rhs);