diff --git a/js/src/ion/Lowering.cpp b/js/src/ion/Lowering.cpp index 57a3d14865c..642b2b7b976 100644 --- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -339,6 +339,24 @@ LIRGenerator::visitTest(MTest *test) if (opd->type() == MIRType_Object) return add(new LGoto(ifTrue)); + // Constant Double operand. + if (opd->type() == MIRType_Double && opd->isConstant()) { + double dbl = opd->toConstant()->value().toDouble(); + return add(new LGoto(dbl ? ifTrue : ifFalse)); + } + + // Constant Int32 operand. + if (opd->type() == MIRType_Int32 && opd->isConstant()) { + int32 num = opd->toConstant()->value().toInt32(); + return add(new LGoto(num ? ifTrue : ifFalse)); + } + + // Constant Boolean operand. + if (opd->type() == MIRType_Boolean && opd->isConstant()) { + bool result = opd->toConstant()->value().toBoolean(); + return add(new LGoto(result ? ifTrue : ifFalse)); + } + // Check if the operand for this test is a compare operation. If it is, we want // to emit an LCompare*AndBranch rather than an LTest*AndBranch, to fuse the // compare and jump instructions. diff --git a/js/src/ion/MIR.cpp b/js/src/ion/MIR.cpp index 6016027e469..447ea96db21 100644 --- a/js/src/ion/MIR.cpp +++ b/js/src/ion/MIR.cpp @@ -11,6 +11,7 @@ #include "MIRGraph.h" #include "EdgeCaseAnalysis.h" #include "jsnum.h" +#include "jsstr.h" #include "jstypedarrayinlines.h" // For ClampIntForUint8Array using namespace js; @@ -1347,6 +1348,43 @@ MCompare::evaluateConstantOperands(bool *result) Value lhs = left->toConstant()->value(); Value rhs = right->toConstant()->value(); + // Fold away some String equality comparisons. + if (lhs.isString() && rhs.isString()) { + int32_t comp = 0; // Default to equal. + if (left != right) { + if (!CompareStrings(GetIonContext()->cx, lhs.toString(), rhs.toString(), &comp)) + return false; + } + + switch (jsop_) { + case JSOP_LT: + *result = (comp < 0); + break; + case JSOP_LE: + *result = (comp <= 0); + break; + case JSOP_GT: + *result = (comp > 0); + break; + case JSOP_GE: + *result = (comp >= 0); + break; + case JSOP_STRICTEQ: // Fall through. + case JSOP_EQ: + *result = (comp == 0); + break; + case JSOP_STRICTNE: // Fall through. + case JSOP_NE: + *result = (comp != 0); + break; + default: + JS_NOT_REACHED("Unexpected op."); + return false; + } + + return true; + } + if (!lhs.isNumber() || !rhs.isNumber()) return false;