Bug 1272948 - IonMonkey: MIPS: Trap on integer divide by zero. r=bbouvier
authorHeiher <r@hev.cc>
Mon, 23 May 2016 10:14:00 +0800
changeset 298400 c7f1135092e15039adf1d51afebd6b6c26ec645b
parent 298399 7ec3b365c990a01cd4039b2425235c952bb24d98
child 298401 212b7582efe7db1147275a0890f3e8eda0c9f97d
push id77151
push userr@hev.cc
push dateMon, 23 May 2016 02:14:20 +0000
treeherdermozilla-inbound@c7f1135092e1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1272948
milestone49.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 1272948 - IonMonkey: MIPS: Trap on integer divide by zero. r=bbouvier --- .../jit/mips-shared/CodeGenerator-mips-shared.cpp | 38 ++++++++++++++-------- js/src/jit/mips-shared/LIR-mips-shared.h | 6 ++++ 2 files changed, 31 insertions(+), 13 deletions(-)
js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
js/src/jit/mips-shared/LIR-mips-shared.h
--- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
+++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
@@ -523,17 +523,19 @@ CodeGeneratorMIPSShared::visitDivI(LDivI
     Register dest = ToRegister(ins->output());
     Register temp = ToRegister(ins->getTemp(0));
     MDiv* mir = ins->mir();
 
     Label done;
 
     // Handle divide by zero.
     if (mir->canBeDivideByZero()) {
-        if (mir->canTruncateInfinities()) {
+        if (mir->trapOnError()) {
+            masm.ma_b(rhs, rhs, wasm::JumpTarget::IntegerDivideByZero, Assembler::Zero);
+        } else if (mir->canTruncateInfinities()) {
             // Truncated division by zero is zero (Infinity|0 == 0)
             Label notzero;
             masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump);
             masm.move32(Imm32(0), dest);
             masm.ma_b(&done, ShortJump);
             masm.bind(&notzero);
         } else {
             MOZ_ASSERT(mir->fallible());
@@ -543,17 +545,19 @@ CodeGeneratorMIPSShared::visitDivI(LDivI
 
     // Handle an integer overflow exception from -2147483648 / -1.
     if (mir->canBeNegativeOverflow()) {
         Label notMinInt;
         masm.move32(Imm32(INT32_MIN), temp);
         masm.ma_b(lhs, temp, &notMinInt, Assembler::NotEqual, ShortJump);
 
         masm.move32(Imm32(-1), temp);
-        if (mir->canTruncateOverflow()) {
+        if (mir->trapOnError()) {
+            masm.ma_b(rhs, temp, wasm::JumpTarget::IntegerOverflow, Assembler::Equal);
+        } else if (mir->canTruncateOverflow()) {
             // (-INT32_MIN)|0 == INT32_MIN
             Label skip;
             masm.ma_b(rhs, temp, &skip, Assembler::NotEqual, ShortJump);
             masm.move32(Imm32(INT32_MIN), dest);
             masm.ma_b(&done, ShortJump);
             masm.bind(&skip);
         } else {
             MOZ_ASSERT(mir->fallible());
@@ -669,21 +673,25 @@ CodeGeneratorMIPSShared::visitModI(LModI
     // 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.
     // if (Y > 0), we don't bail.
 
     if (mir->canBeDivideByZero()) {
         if (mir->isTruncated()) {
-            Label skip;
-            masm.ma_b(rhs, Imm32(0), &skip, Assembler::NotEqual, ShortJump);
-            masm.move32(Imm32(0), dest);
-            masm.ma_b(&done, ShortJump);
-            masm.bind(&skip);
+            if (mir->trapOnError()) {
+                masm.ma_b(rhs, rhs, wasm::JumpTarget::IntegerDivideByZero, Assembler::Zero);
+            } else {
+                Label skip;
+                masm.ma_b(rhs, Imm32(0), &skip, Assembler::NotEqual, ShortJump);
+                masm.move32(Imm32(0), dest);
+                masm.ma_b(&done, ShortJump);
+                masm.bind(&skip);
+            }
         } else {
             MOZ_ASSERT(mir->fallible());
             bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot());
         }
     }
 
     if (mir->canBeNegativeDividend()) {
         Label notNegative;
@@ -2077,22 +2085,26 @@ CodeGeneratorMIPSShared::visitUDivOrMod(
     Register lhs = ToRegister(ins->lhs());
     Register rhs = ToRegister(ins->rhs());
     Register output = ToRegister(ins->output());
     Label done;
 
     // Prevent divide by zero.
     if (ins->canBeDivideByZero()) {
         if (ins->mir()->isTruncated()) {
-            // Infinity|0 == 0
-            Label notzero;
-            masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump);
-            masm.move32(Imm32(0), output);
-            masm.ma_b(&done, ShortJump);
-            masm.bind(&notzero);
+            if (ins->trapOnError()) {
+                masm.ma_b(rhs, rhs, wasm::JumpTarget::IntegerDivideByZero, Assembler::Zero);
+            } else {
+                // Infinity|0 == 0
+                Label notzero;
+                masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump);
+                masm.move32(Imm32(0), output);
+                masm.ma_b(&done, ShortJump);
+                masm.bind(&notzero);
+            }
         } else {
             bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot());
         }
     }
 
     masm.as_divu(lhs, rhs);
     masm.as_mfhi(output);
 
--- a/js/src/jit/mips-shared/LIR-mips-shared.h
+++ b/js/src/jit/mips-shared/LIR-mips-shared.h
@@ -264,16 +264,22 @@ class LUDivOrMod : public LBinaryMath<0>
         return static_cast<MBinaryArithInstruction*>(mir_);
     }
 
     bool canBeDivideByZero() const {
         if (mir_->isMod())
             return mir_->toMod()->canBeDivideByZero();
         return mir_->toDiv()->canBeDivideByZero();
     }
+
+    bool trapOnError() const {
+        if (mir_->isMod())
+            return mir_->toMod()->trapOnError();
+        return mir_->toDiv()->trapOnError();
+    }
 };
 
 class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(AsmJSLoadFuncPtr);
     LAsmJSLoadFuncPtr(const LAllocation& index) {
         setOperand(0, index);