@@ -6468,6 +6468,12 @@ GlobOpt::GetConstantVar(IR::Opnd *opnd, Value *val)
64686468 return Js::TaggedInt::ToVarUnchecked(opnd->AsIntConstOpnd()->AsInt32());
64696469 }
64706470 }
6471+ #if FLOATVAR
6472+ else if (opnd->IsFloatConstOpnd())
6473+ {
6474+ return Js::JavascriptNumber::ToVar(opnd->AsFloatConstOpnd()->m_value);
6475+ }
6476+ #endif
64716477 else if (opnd->IsRegOpnd() && opnd->AsRegOpnd()->m_sym->IsSingleDef())
64726478 {
64736479 if (valueInfo->IsBoolean())
@@ -6489,19 +6495,110 @@ GlobOpt::GetConstantVar(IR::Opnd *opnd, Value *val)
64896495 {
64906496 return (Js::Var)this->func->GetScriptContextInfo()->GetNullAddr();
64916497 }
6498+ #if FLOATVAR
6499+ else if (valueInfo->IsFloat())
6500+ {
6501+ IR::Instr * defInstr = opnd->AsRegOpnd()->m_sym->GetInstrDef();
6502+ if (defInstr->m_opcode == Js::OpCode::LdC_F8_R8 && defInstr->GetSrc1()->IsFloatConstOpnd())
6503+ {
6504+ return Js::JavascriptNumber::ToVar(defInstr->GetSrc1()->AsFloatConstOpnd()->m_value);
6505+ }
6506+ }
6507+ #endif
64926508 }
64936509
64946510 return nullptr;
64956511}
64966512
6497- bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src1Var, Js::Var src2Var)
6513+ namespace
64986514{
6499- ValueInfo *src1ValInfo = src1Val->GetValueInfo();
6500- ValueInfo *src2ValInfo = src2Val->GetValueInfo();
6501- return (src1ValInfo->IsNumber() && src1Var && src2ValInfo->IsBoolean() && src1Var != Js::TaggedInt::ToVarUnchecked(0) && src1Var != Js::TaggedInt::ToVarUnchecked(1)) ||
6502- (src2ValInfo->IsNumber() && src2Var && src1ValInfo->IsBoolean() && src2Var != Js::TaggedInt::ToVarUnchecked(0) && src2Var != Js::TaggedInt::ToVarUnchecked(1));
6503- }
6515+ bool TryCompIntAndFloat(bool * result, Js::Var left, Js::Var right)
6516+ {
6517+ if (Js::TaggedInt::Is(left))
6518+ {
6519+ // If both are tagged ints we should not get here.
6520+ Assert(!Js::TaggedInt::Is(right));
6521+ if (Js::JavascriptNumber::Is_NoTaggedIntCheck(right))
6522+ {
6523+ double value = Js::JavascriptNumber::GetValue(right);
6524+ *result = (Js::TaggedInt::ToInt32(left) == value);
6525+ return true;
6526+ }
6527+ }
6528+ return false;
6529+ }
6530+
6531+ bool Op_JitEq(bool * result, Value * src1Val, Value * src2Val, Js::Var src1Var, Js::Var src2Var, Func * func, bool isStrict)
6532+ {
6533+ Assert(src1Val != nullptr && src2Val != nullptr);
6534+ Assert(src1Var != nullptr && src2Var != nullptr);
6535+
6536+ if (src1Var == src2Var)
6537+ {
6538+ if (Js::TaggedInt::Is(src1Var))
6539+ {
6540+ *result = true;
6541+ return true;
6542+ }
6543+
6544+ if (!isStrict && src1Val->GetValueInfo()->IsNotFloat())
6545+ {
6546+ // If the vars are equal and they are not NaN, non-strict equal returns true. Not float guarantees not NaN.
6547+ *result = true;
6548+ return true;
6549+ }
6550+
6551+ #if FLOATVAR
6552+ if (Js::JavascriptNumber::Is_NoTaggedIntCheck(src1Var))
6553+ {
6554+ *result = !Js::JavascriptNumber::IsNan(Js::JavascriptNumber::GetValue(src1Var));
6555+ return true;
6556+ }
6557+ #endif
6558+
6559+ if (src1Var == reinterpret_cast<Js::Var>(func->GetScriptContextInfo()->GetTrueAddr()) ||
6560+ src1Var == reinterpret_cast<Js::Var>(func->GetScriptContextInfo()->GetFalseAddr()) ||
6561+ src1Var == reinterpret_cast<Js::Var>(func->GetScriptContextInfo()->GetNullAddr()) ||
6562+ src1Var == reinterpret_cast<Js::Var>(func->GetScriptContextInfo()->GetUndefinedAddr()))
6563+ {
6564+ *result = true;
6565+ return true;
6566+ }
6567+
6568+ // Other var comparisons require the runtime to prove.
6569+ return false;
6570+ }
6571+
6572+ #if FLOATVAR
6573+ if (TryCompIntAndFloat(result, src1Var, src2Var) || TryCompIntAndFloat(result, src2Var, src1Var))
6574+ {
6575+ return true;
6576+ }
6577+
6578+ #endif
65046579
6580+ return false;
6581+ }
6582+
6583+ bool Op_JitNeq(bool * result, Value * src1Val, Value * src2Val, Js::Var src1Var, Js::Var src2Var, Func * func, bool isStrict)
6584+ {
6585+ if (Op_JitEq(result, src1Val, src2Val, src1Var, src2Var, func, isStrict))
6586+ {
6587+ *result = !*result;
6588+ return true;
6589+ }
6590+
6591+ return false;
6592+ }
6593+
6594+ bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src1Var, Js::Var src2Var)
6595+ {
6596+ ValueInfo *src1ValInfo = src1Val->GetValueInfo();
6597+ ValueInfo *src2ValInfo = src2Val->GetValueInfo();
6598+ return (src1ValInfo->IsNumber() && src1Var && src2ValInfo->IsBoolean() && src1Var != Js::TaggedInt::ToVarUnchecked(0) && src1Var != Js::TaggedInt::ToVarUnchecked(1)) ||
6599+ (src2ValInfo->IsNumber() && src2Var && src1ValInfo->IsBoolean() && src2Var != Js::TaggedInt::ToVarUnchecked(0) && src2Var != Js::TaggedInt::ToVarUnchecked(1));
6600+ }
6601+ }
65056602
65066603bool
65076604GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2Val, Js::Var src1Var, Js::Var src2Var, bool *result)
@@ -6629,12 +6726,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
66296726 }
66306727 else
66316728 {
6632- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6729+ if (!Op_JitEq(result, src1Val, src2Val, src1Var, src2Var, this->func, false /* isStrict */ ))
66336730 {
6634- // TODO: OOP JIT, const folding
66356731 return false;
66366732 }
6637- *result = Js::JavascriptOperators::Equal(src1Var, src2Var, this->func->GetScriptContext());
66386733 }
66396734 break;
66406735 case Js::OpCode::BrNeq_A:
@@ -6661,12 +6756,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
66616756 }
66626757 else
66636758 {
6664- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6759+ if (!Op_JitNeq(result, src1Val, src2Val, src1Var, src2Var, this->func, false /* isStrict */ ))
66656760 {
6666- // TODO: OOP JIT, const folding
66676761 return false;
66686762 }
6669- *result = Js::JavascriptOperators::NotEqual(src1Var, src2Var, this->func->GetScriptContext());
66706763 }
66716764 break;
66726765 case Js::OpCode::BrSrEq_A:
@@ -6702,12 +6795,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
67026795 }
67036796 else
67046797 {
6705- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6798+ if (!Op_JitEq(result, src1Val, src2Val, src1Var, src2Var, this->func, true /* isStrict */ ))
67066799 {
6707- // TODO: OOP JIT, const folding
67086800 return false;
67096801 }
6710- *result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
67116802 }
67126803 break;
67136804
@@ -6744,12 +6835,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
67446835 }
67456836 else
67466837 {
6747- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6838+ if (!Op_JitNeq(result, src1Val, src2Val, src1Var, src2Var, this->func, true /* isStrict */ ))
67486839 {
6749- // TODO: OOP JIT, const folding
67506840 return false;
67516841 }
6752- *result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
67536842 }
67546843 break;
67556844
0 commit comments