author | Dan Gohman <sunfish@google.com> |
Sat, 02 Nov 2013 14:29:44 -0700 | |
changeset 153268 | e9ff16009983c0f79efa0f86f65f11f46c857e44 |
parent 153267 | 592b05772531740002535dcfbe9a38a4b897a547 |
child 153269 | 3d175be0fcb0e51946459cdca3abd3917ef3c60e |
push id | 25578 |
push user | philringnalda@gmail.com |
push date | Sun, 03 Nov 2013 21:05:48 +0000 |
treeherder | mozilla-central@fc3414dda755 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 931489 |
milestone | 28.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
|
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -2141,22 +2141,24 @@ class MCompare // All other possible compares Compare_Unknown }; private: CompareType compareType_; JSOp jsop_; bool operandMightEmulateUndefined_; + bool operandsAreNeverNaN_; MCompare(MDefinition *left, MDefinition *right, JSOp jsop) : MBinaryInstruction(left, right), compareType_(Compare_Unknown), jsop_(jsop), - operandMightEmulateUndefined_(true) + operandMightEmulateUndefined_(true), + operandsAreNeverNaN_(false) { setResultType(MIRType_Boolean); setMovable(); } public: INSTRUCTION_HEADER(Compare) static MCompare *New(MDefinition *left, MDefinition *right, JSOp op); @@ -2190,27 +2192,31 @@ class MCompare return this; } void markNoOperandEmulatesUndefined() { operandMightEmulateUndefined_ = false; } bool operandMightEmulateUndefined() const { return operandMightEmulateUndefined_; } + bool operandsAreNeverNaN() const { + return operandsAreNeverNaN_; + } AliasSet getAliasSet() const { // Strict equality is never effectful. if (jsop_ == JSOP_STRICTEQ || jsop_ == JSOP_STRICTNE) return AliasSet::None(); if (compareType_ == Compare_Unknown) return AliasSet::Store(AliasSet::Any); JS_ASSERT(compareType_ <= Compare_Value); return AliasSet::None(); } void printOpcode(FILE *fp) const; + void collectRangeInfo(); void trySpecializeFloat32(); bool isFloat32Commutative() const { return true; } # ifdef DEBUG bool isConsistentFloat32Use() const { return compareType_ == Compare_Float32; }
--- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2402,8 +2402,14 @@ MMod::collectRangeInfo() } void MBoundsCheckLower::collectRangeInfo() { Range indexRange(index()); fallible_ = !indexRange.hasInt32LowerBound() || indexRange.lower() < minimum_; } + +void +MCompare::collectRangeInfo() +{ + operandsAreNeverNaN_ = !Range(lhs()).canBeNaN() && !Range(rhs()).canBeNaN(); +}
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -189,32 +189,40 @@ CodeGeneratorX86Shared::visitCompareAndB bool CodeGeneratorX86Shared::visitCompareD(LCompareD *comp) { FloatRegister lhs = ToFloatRegister(comp->left()); FloatRegister rhs = ToFloatRegister(comp->right()); Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + + Assembler::NaNCond nanCond = Assembler::NaNCondFromDoubleCondition(cond); + if (comp->mir()->operandsAreNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.compareDouble(cond, lhs, rhs); - masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()), - Assembler::NaNCondFromDoubleCondition(cond)); + masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()), nanCond); return true; } bool CodeGeneratorX86Shared::visitCompareF(LCompareF *comp) { FloatRegister lhs = ToFloatRegister(comp->left()); FloatRegister rhs = ToFloatRegister(comp->right()); Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + + Assembler::NaNCond nanCond = Assembler::NaNCondFromDoubleCondition(cond); + if (comp->mir()->operandsAreNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.compareFloat(cond, lhs, rhs); - masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()), - Assembler::NaNCondFromDoubleCondition(cond)); + masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()), nanCond); return true; } bool CodeGeneratorX86Shared::visitNotI(LNotI *ins) { masm.cmpl(ToRegister(ins->input()), Imm32(0)); masm.emitSet(Assembler::Equal, ToRegister(ins->output())); @@ -245,32 +253,40 @@ CodeGeneratorX86Shared::visitNotF(LNotF bool CodeGeneratorX86Shared::visitCompareDAndBranch(LCompareDAndBranch *comp) { FloatRegister lhs = ToFloatRegister(comp->left()); FloatRegister rhs = ToFloatRegister(comp->right()); Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + + Assembler::NaNCond nanCond = Assembler::NaNCondFromDoubleCondition(cond); + if (comp->mir()->operandsAreNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.compareDouble(cond, lhs, rhs); - emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse(), - Assembler::NaNCondFromDoubleCondition(cond)); + emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse(), nanCond); return true; } bool CodeGeneratorX86Shared::visitCompareFAndBranch(LCompareFAndBranch *comp) { FloatRegister lhs = ToFloatRegister(comp->left()); FloatRegister rhs = ToFloatRegister(comp->right()); Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + + Assembler::NaNCond nanCond = Assembler::NaNCondFromDoubleCondition(cond); + if (comp->mir()->operandsAreNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.compareFloat(cond, lhs, rhs); - emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse(), - Assembler::NaNCondFromDoubleCondition(cond)); + emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse(), nanCond); return true; } bool CodeGeneratorX86Shared::visitAsmJSPassStackArg(LAsmJSPassStackArg *ins) { const MAsmJSPassStackArg *mir = ins->mir(); Address dst(StackPointer, mir->spOffset());