Bug 946284 - IonMonkey: Don't form unsigned divisions when the result could be fractional. r=nbp
authorDan Gohman <sunfish@google.com>
Thu, 05 Dec 2013 07:50:43 -0800
changeset 173639 7c60951f996449110b249792445574ad7e9e74f5
parent 173638 3a4e27241c73dbb49c3f73f659b8311932e39f2c
child 173640 bfb81cac010888be92ad6d9168af2f6686dfe86c
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs946284
milestone28.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
Bug 946284 - IonMonkey: Don't form unsigned divisions when the result could be fractional. r=nbp
js/src/jit-test/tests/ion/bug946284.js
js/src/jit/RangeAnalysis.cpp
js/src/jit/shared/LIR-x86-shared.h
js/src/jit/shared/Lowering-x86-shared.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug946284.js
@@ -0,0 +1,5 @@
+function f(x) {
+    return x.length / 2
+}
+f("")
+assertEq(f(undefined + ""), 4.5);
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -1325,23 +1325,16 @@ MDiv::computeRange(TempAllocator &alloc)
     // handles Infinity cases.
     if (!lhs.hasInt32Bounds() || !rhs.hasInt32Bounds())
         return;
 
     // Something simple for now: When dividing by a positive rhs, the result
     // won't be further from zero than lhs.
     if (lhs.lower() >= 0 && rhs.lower() >= 1) {
         setRange(new(alloc) Range(0, lhs.upper(), true, lhs.exponent()));
-
-        // Also, we can optimize by converting this to an unsigned div.
-        if (specialization() == MIRType_Int32 &&
-            !lhs.canHaveFractionalPart() && !rhs.canHaveFractionalPart())
-        {
-            unsigned_ = true;
-        }
     } else if (unsigned_ && rhs.lower() >= 1) {
         // We shouldn't set the unsigned flag if the inputs can have
         // fractional parts.
         JS_ASSERT(!lhs.canHaveFractionalPart() && !rhs.canHaveFractionalPart());
         // Unsigned division by a non-zero rhs will return a uint32 value.
         setRange(Range::NewUInt32Range(alloc, 0, UINT32_MAX));
     }
 }
--- a/js/src/jit/shared/LIR-x86-shared.h
+++ b/js/src/jit/shared/LIR-x86-shared.h
@@ -53,22 +53,16 @@ class LDivPowTwoI : public LBinaryMath<0
 
     LDivPowTwoI(const LAllocation &lhs, const LAllocation &lhsCopy, int32_t shift)
       : shift_(shift)
     {
         setOperand(0, lhs);
         setOperand(1, lhsCopy);
     }
 
-    LDivPowTwoI(const LAllocation &lhs, int32_t shift)
-      : shift_(shift)
-    {
-        setOperand(0, lhs);
-    }
-
     const LAllocation *numerator() {
         return getOperand(0);
     }
     const LAllocation *numeratorCopy() {
         return getOperand(1);
     }
     int32_t shift() const {
         return shift_;
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.cpp
@@ -143,17 +143,17 @@ LIRGeneratorX86Shared::lowerDivI(MDiv *d
         // similar manner as positive powers of two, and division by other
         // constants can be optimized by a reciprocal multiplication technique.
         int32_t shift = FloorLog2(rhs);
         if (rhs > 0 && 1 << shift == rhs) {
             LAllocation lhs = useRegisterAtStart(div->lhs());
             LDivPowTwoI *lir;
             if (!div->canBeNegativeDividend()) {
                 // Numerator is unsigned, so does not need adjusting.
-                lir = new LDivPowTwoI(lhs, shift);
+                lir = new LDivPowTwoI(lhs, lhs, shift);
             } else {
                 // Numerator is signed, and needs adjusting, and an extra
                 // lhs copy register is needed.
                 lir = new LDivPowTwoI(lhs, useRegister(div->lhs()), shift);
             }
             if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
                 return false;
             return defineReuseInput(lir, div, 0);