Bug 951988 - IonMonkey: Use canBeNegativeDividend() in the ARM backend. r=mjrosenb, a=lsblakk
authorDouglas Crosher <dtc-moz@scieneer.com>
Sun, 22 Dec 2013 08:48:02 +1100
changeset 175792 cb1622bda20842af930c012ff076ad7c18aae56b
parent 175791 1f6eaab92cb98210ae1fb233856ef673821b4bf1
child 175793 e54abcb180642da1228d1c218ea57f644f5449b5
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjrosenb, lsblakk
bugs951988
milestone28.0a2
Bug 951988 - IonMonkey: Use canBeNegativeDividend() in the ARM backend. r=mjrosenb, a=lsblakk
js/src/jit/arm/CodeGenerator-arm.cpp
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -698,29 +698,31 @@ CodeGeneratorARM::modICommon(MMod *mir, 
     // Prevent 0 / X (with X < 0) and X / 0
     // testing X / Y.  Compare Y with 0.
     // There are three cases: (Y < 0), (Y == 0) and (Y > 0)
     // If (Y < 0), then we compare X with 0, and bail if X == 0
     // If (Y == 0), then we simply want to bail.  Since this does not set
     // the flags necessary for LT to trigger, we don't test X, and take the
     // bailout because the EQ flag is set.
     // if (Y > 0), we don't set EQ, and we don't trigger LT, so we don't take the bailout.
-    masm.ma_cmp(rhs, Imm32(0));
-    masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
-    if (mir->isTruncated()) {
-        // NaN|0 == 0 and (0 % -X)|0 == 0
-        Label skip;
-        masm.ma_b(&skip, Assembler::NotEqual);
-        masm.ma_mov(Imm32(0), output);
-        masm.ma_b(&done);
-        masm.bind(&skip);
-    } else {
-        JS_ASSERT(mir->fallible());
-        if (!bailoutIf(Assembler::Equal, snapshot))
-            return false;
+    if (mir->canBeDivideByZero() || mir->canBeNegativeDividend()) {
+        masm.ma_cmp(rhs, Imm32(0));
+        masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
+        if (mir->isTruncated()) {
+            // NaN|0 == 0 and (0 % -X)|0 == 0
+            Label skip;
+            masm.ma_b(&skip, Assembler::NotEqual);
+            masm.ma_mov(Imm32(0), output);
+            masm.ma_b(&done);
+            masm.bind(&skip);
+        } else {
+            JS_ASSERT(mir->fallible());
+            if (!bailoutIf(Assembler::Equal, snapshot))
+                return false;
+        }
     }
 
     return true;
 }
 
 bool
 CodeGeneratorARM::visitModI(LModI *ins)
 {
@@ -735,26 +737,28 @@ CodeGeneratorARM::visitModI(LModI *ins)
 
     Label done;
     if (!modICommon(mir, lhs, rhs, output, ins->snapshot(), done))
         return false;
 
     masm.ma_smod(lhs, rhs, output);
 
     // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
-    if (mir->isTruncated()) {
-        // -0.0|0 == 0
-    } else {
-        JS_ASSERT(mir->fallible());
-        // See if X < 0
-        masm.ma_cmp(output, Imm32(0));
-        masm.ma_b(&done, Assembler::NotEqual);
-        masm.ma_cmp(callTemp, Imm32(0));
-        if (!bailoutIf(Assembler::Signed, ins->snapshot()))
-            return false;
+    if (mir->canBeNegativeDividend()) {
+        if (mir->isTruncated()) {
+            // -0.0|0 == 0
+        } else {
+            JS_ASSERT(mir->fallible());
+            // See if X < 0
+            masm.ma_cmp(output, Imm32(0));
+            masm.ma_b(&done, Assembler::NotEqual);
+            masm.ma_cmp(callTemp, Imm32(0));
+            if (!bailoutIf(Assembler::Signed, ins->snapshot()))
+                return false;
+        }
     }
 
     masm.bind(&done);
     return true;
 }
 
 bool
 CodeGeneratorARM::visitSoftModI(LSoftModI *ins)
@@ -797,26 +801,28 @@ CodeGeneratorARM::visitSoftModI(LSoftMod
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
     if (gen->compilingAsmJS())
         masm.callWithABI(AsmJSImm_aeabi_idivmod);
     else
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
 
     // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
-    if (mir->isTruncated()) {
-        // -0.0|0 == 0
-    } else {
-        JS_ASSERT(mir->fallible());
-        // See if X < 0
-        masm.ma_cmp(r1, Imm32(0));
-        masm.ma_b(&done, Assembler::NotEqual);
-        masm.ma_cmp(callTemp, Imm32(0));
-        if (!bailoutIf(Assembler::Signed, ins->snapshot()))
-            return false;
+    if (mir->canBeNegativeDividend()) {
+        if (mir->isTruncated()) {
+            // -0.0|0 == 0
+        } else {
+            JS_ASSERT(mir->fallible());
+            // See if X < 0
+            masm.ma_cmp(r1, Imm32(0));
+            masm.ma_b(&done, Assembler::NotEqual);
+            masm.ma_cmp(callTemp, Imm32(0));
+            if (!bailoutIf(Assembler::Signed, ins->snapshot()))
+                return false;
+        }
     }
     masm.bind(&done);
     return true;
 }
 
 bool
 CodeGeneratorARM::visitModPowTwoI(LModPowTwoI *ins)
 {
@@ -825,41 +831,45 @@ CodeGeneratorARM::visitModPowTwoI(LModPo
     MMod *mir = ins->mir();
     Label fin;
     // bug 739870, jbramley has a different sequence that may help with speed here
     masm.ma_mov(in, out, SetCond);
     masm.ma_b(&fin, Assembler::Zero);
     masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed);
     masm.ma_and(Imm32((1<<ins->shift())-1), out);
     masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed);
-    if (!mir->isTruncated()) {
-        JS_ASSERT(mir->fallible());
-        if (!bailoutIf(Assembler::Zero, ins->snapshot()))
-            return false;
-    } else {
-        // -0|0 == 0
+    if (mir->canBeNegativeDividend()) {
+        if (!mir->isTruncated()) {
+            JS_ASSERT(mir->fallible());
+            if (!bailoutIf(Assembler::Zero, ins->snapshot()))
+                return false;
+        } else {
+            // -0|0 == 0
+        }
     }
     masm.bind(&fin);
     return true;
 }
 
 bool
 CodeGeneratorARM::visitModMaskI(LModMaskI *ins)
 {
     Register src = ToRegister(ins->getOperand(0));
     Register dest = ToRegister(ins->getDef(0));
     Register tmp = ToRegister(ins->getTemp(0));
     MMod *mir = ins->mir();
     masm.ma_mod_mask(src, dest, tmp, ins->shift());
-    if (!mir->isTruncated()) {
-        JS_ASSERT(mir->fallible());
-        if (!bailoutIf(Assembler::Zero, ins->snapshot()))
-            return false;
-    } else {
-        // -0|0 == 0
+    if (mir->canBeNegativeDividend()) {
+        if (!mir->isTruncated()) {
+            JS_ASSERT(mir->fallible());
+            if (!bailoutIf(Assembler::Zero, ins->snapshot()))
+                return false;
+        } else {
+            // -0|0 == 0
+        }
     }
     return true;
 }
 bool
 CodeGeneratorARM::visitBitNotI(LBitNotI *ins)
 {
     const LAllocation *input = ins->getOperand(0);
     const LDefinition *dest = ins->getDef(0);