Bug 1438727: [Part 12] Implement JSOP_MOD in CacheIR r=jandem
authorMatthew Gaudet <mgaudet@mozilla.com>
Tue, 01 May 2018 14:35:19 -0400
changeset 483697 7cb598e5f90c43782070de16aa1e82c7182483c5
parent 483696 5b25886cfb6444c950bb40b01c306b0d74d1abc3
child 483698 8127fbd4988d8d5f0d4a3885ffa1992a4d656b05
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1438727
milestone63.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 1438727: [Part 12] Implement JSOP_MOD in CacheIR r=jandem
js/src/jit/BaselineIC.cpp
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
js/src/jit/IonBuilder.cpp
js/src/jit/IonIC.cpp
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4953,16 +4953,17 @@ DoCacheIRBinaryArithFallback(JSContext* 
     switch(op) {
       case JSOP_ADD:
       case JSOP_SUB:
       case JSOP_BITOR:
       case JSOP_BITXOR:
       case JSOP_BITAND:
       case JSOP_MUL:
       case JSOP_DIV:
+      case JSOP_MOD:
         break;
       default:
         return false; // Fallback to shared IC.
     }
 
     FallbackICSpew(cx, stub, "CacheIRBinaryArith(%s,%d,%d)", CodeName[op],
             int(lhs.isDouble() ? JSVAL_TYPE_DOUBLE : lhs.extractNonDoubleType()),
             int(rhs.isDouble() ? JSVAL_TYPE_DOUBLE : rhs.extractNonDoubleType()));
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -5155,17 +5155,17 @@ BinaryArithIRGenerator::tryAttachDouble(
 }
 
 bool
 BinaryArithIRGenerator::tryAttachInt32()
 {
     if (op_ != JSOP_ADD && op_ != JSOP_SUB &&
         op_ != JSOP_BITOR && op_ != JSOP_BITAND &&
         op_ != JSOP_BITXOR && op_ != JSOP_MUL &&
-        op_ != JSOP_DIV)
+        op_ != JSOP_DIV && op_ != JSOP_MOD)
     {
         return false;
     }
 
     if (!lhs_.isInt32() || !rhs_.isInt32())
         return false;
 
     ValOperandId lhsId(writer.setInputOperandId(0));
@@ -5186,16 +5186,20 @@ BinaryArithIRGenerator::tryAttachInt32()
       case JSOP_MUL:
         writer.int32MulResult(lhsIntId, rhsIntId);
         trackAttached("BinaryArith.Int32.Mul");
         break;
       case JSOP_DIV:
         writer.int32DivResult(lhsIntId, rhsIntId);
         trackAttached("BinaryArith.Int32.Div");
         break;
+      case JSOP_MOD:
+        writer.int32ModResult(lhsIntId, rhsIntId);
+        trackAttached("BinaryArith.Int32.Mod");
+        break;
       case JSOP_BITOR:
         writer.int32BitOrResult(lhsIntId, rhsIntId);
         trackAttached("BinaryArith.Int32.BitOr");
         break;
       case JSOP_BITXOR:
         writer.int32BitXOrResult(lhsIntId, rhsIntId);
         trackAttached("BinaryArith.Int32.BitXOr");
         break;
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -294,16 +294,17 @@ extern const char* CacheKindNames[];
     _(LoadTypeOfObjectResult)             \
     _(DoubleAddResult)                    \
     _(DoubleSubResult)                    \
     _(DoubleMulResult)                    \
     _(Int32AddResult)                     \
     _(Int32SubResult)                     \
     _(Int32MulResult)                     \
     _(Int32DivResult)                     \
+    _(Int32ModResult)                     \
     _(Int32BitOrResult)                   \
     _(Int32BitXorResult)                  \
     _(Int32BitAndResult)                  \
     _(Int32NotResult)                     \
     _(Int32NegationResult)                \
     _(DoubleNegationResult)               \
     _(LoadInt32TruthyResult)              \
     _(LoadDoubleTruthyResult)             \
@@ -1030,16 +1031,20 @@ class MOZ_RAII CacheIRWriter : public JS
     void int32MulResult(Int32OperandId lhs, Int32OperandId rhs) {
         writeOpWithOperandId(CacheOp::Int32MulResult, lhs);
         writeOperandId(rhs);
     }
     void int32DivResult(Int32OperandId lhs, Int32OperandId rhs) {
         writeOpWithOperandId(CacheOp::Int32DivResult, lhs);
         writeOperandId(rhs);
     }
+    void int32ModResult(Int32OperandId lhs, Int32OperandId rhs) {
+        writeOpWithOperandId(CacheOp::Int32ModResult, lhs);
+        writeOperandId(rhs);
+    }
     void int32BitOrResult(Int32OperandId lhs, Int32OperandId rhs) {
         writeOpWithOperandId(CacheOp::Int32BitOrResult, lhs);
         writeOperandId(rhs);
     }
     void int32BitXOrResult(Int32OperandId lhs, Int32OperandId rhs) {
         writeOpWithOperandId(CacheOp::Int32BitXorResult, lhs);
         writeOperandId(rhs);
     }
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -2087,16 +2087,46 @@ CacheIRCompiler::emitInt32DivResult()
 
     // A remainder implies a double result.
     masm.branchTest32(Assembler::NonZero, rem, rem, failure->label());
     EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
     return true;
 }
 
 bool
+CacheIRCompiler::emitInt32ModResult()
+{
+    AutoOutputRegister output(*this);
+    Register lhs = allocator.useRegister(masm, reader.int32OperandId());
+    Register rhs = allocator.useRegister(masm, reader.int32OperandId());
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    // Modulo takes the sign of the dividend; don't handle negative dividends here.
+    masm.branchTest32(Assembler::Signed, lhs, lhs, failure->label());
+
+    // Negative divisor (could be fixed with abs)
+    masm.branchTest32(Assembler::Signed, rhs, rhs, failure->label());
+
+    // x % 0 results in NaN
+    masm.branchTest32(Assembler::Zero, rhs, rhs, failure->label());
+
+    // Prevent negative 0 and -2147483648 / -1.
+    masm.branch32(Assembler::Equal, lhs, Imm32(INT32_MIN), failure->label());
+    LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
+    masm.flexibleRemainder32(rhs, lhs, false, volatileRegs);
+
+    EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
+
+    return true;
+}
+
+bool
 CacheIRCompiler::emitInt32BitOrResult()
 {
     AutoOutputRegister output(*this);
 
     Register lhs = allocator.useRegister(masm, reader.int32OperandId());
     Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
     masm.or32(lhs, rhs);
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -54,16 +54,17 @@ namespace jit {
     _(LoadInt32ArrayLengthResult)         \
     _(DoubleAddResult)                    \
     _(DoubleSubResult)                    \
     _(DoubleMulResult)                    \
     _(Int32AddResult)                     \
     _(Int32SubResult)                     \
     _(Int32MulResult)                     \
     _(Int32DivResult)                     \
+    _(Int32ModResult)                     \
     _(Int32BitOrResult)                   \
     _(Int32BitXorResult)                  \
     _(Int32BitAndResult)                  \
     _(Int32NegationResult)                \
     _(Int32NotResult)                     \
     _(DoubleNegationResult)               \
     _(TruncateDoubleToUInt32)             \
     _(LoadArgumentsObjectLengthResult)    \
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -3568,24 +3568,23 @@ IonBuilder::arithTrySharedStub(bool* emi
                       left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1);
         MOZ_ASSERT_IF(op != JSOP_MUL, !left);
         stub = MUnaryCache::New(alloc(), right);
         break;
       case JSOP_ADD:
       case JSOP_SUB:
       case JSOP_MUL:
       case JSOP_DIV:
-
+      case JSOP_MOD:
         // If not disabled, prefer the cache IR stub.
         if (!JitOptions.disableCacheIRBinaryArith) {
             stub = MBinaryCache::New(alloc(), left, right);
             break;
         }
         MOZ_FALLTHROUGH;
-      case JSOP_MOD:
       case JSOP_POW:
         stub = MBinarySharedStub::New(alloc(), left, right);
         break;
       default:
         MOZ_CRASH("unsupported arith");
     }
 
     current->add(stub);
--- a/js/src/jit/IonIC.cpp
+++ b/js/src/jit/IonIC.cpp
@@ -578,16 +578,20 @@ IonBinaryArithIC::update(JSContext* cx, 
       case JSOP_MUL:
         if (!MulValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_DIV:
         if (!DivValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
+      case JSOP_MOD:
+        if (!ModValues(cx, &lhsCopy, &rhsCopy, ret))
+            return false;
+        break;
       case JSOP_BITOR: {
         int32_t result;
         if (!BitOr(cx, lhs, rhs, &result))
             return false;
         ret.setInt32(result);
         break;
       }
       case JSOP_BITXOR: {