@@ -6468,6 +6468,12 @@ GlobOpt::GetConstantVar(IR::Opnd *opnd, Value *val)
6468
6468
return Js::TaggedInt::ToVarUnchecked(opnd->AsIntConstOpnd()->AsInt32());
6469
6469
}
6470
6470
}
6471
+ #if FLOATVAR
6472
+ else if (opnd->IsFloatConstOpnd())
6473
+ {
6474
+ return Js::JavascriptNumber::ToVar(opnd->AsFloatConstOpnd()->m_value);
6475
+ }
6476
+ #endif
6471
6477
else if (opnd->IsRegOpnd() && opnd->AsRegOpnd()->m_sym->IsSingleDef())
6472
6478
{
6473
6479
if (valueInfo->IsBoolean())
@@ -6489,19 +6495,110 @@ GlobOpt::GetConstantVar(IR::Opnd *opnd, Value *val)
6489
6495
{
6490
6496
return (Js::Var)this->func->GetScriptContextInfo()->GetNullAddr();
6491
6497
}
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
6492
6508
}
6493
6509
6494
6510
return nullptr;
6495
6511
}
6496
6512
6497
- bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src1Var, Js::Var src2Var)
6513
+ namespace
6498
6514
{
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
6504
6579
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
+ }
6505
6602
6506
6603
bool
6507
6604
GlobOpt::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
6629
6726
}
6630
6727
else
6631
6728
{
6632
- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6729
+ if (!Op_JitEq(result, src1Val, src2Val, src1Var, src2Var, this->func, false /* isStrict */ ))
6633
6730
{
6634
- // TODO: OOP JIT, const folding
6635
6731
return false;
6636
6732
}
6637
- *result = Js::JavascriptOperators::Equal(src1Var, src2Var, this->func->GetScriptContext());
6638
6733
}
6639
6734
break;
6640
6735
case Js::OpCode::BrNeq_A:
@@ -6661,12 +6756,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6661
6756
}
6662
6757
else
6663
6758
{
6664
- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6759
+ if (!Op_JitNeq(result, src1Val, src2Val, src1Var, src2Var, this->func, false /* isStrict */ ))
6665
6760
{
6666
- // TODO: OOP JIT, const folding
6667
6761
return false;
6668
6762
}
6669
- *result = Js::JavascriptOperators::NotEqual(src1Var, src2Var, this->func->GetScriptContext());
6670
6763
}
6671
6764
break;
6672
6765
case Js::OpCode::BrSrEq_A:
@@ -6702,12 +6795,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6702
6795
}
6703
6796
else
6704
6797
{
6705
- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6798
+ if (!Op_JitEq(result, src1Val, src2Val, src1Var, src2Var, this->func, true /* isStrict */ ))
6706
6799
{
6707
- // TODO: OOP JIT, const folding
6708
6800
return false;
6709
6801
}
6710
- *result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6711
6802
}
6712
6803
break;
6713
6804
@@ -6744,12 +6835,10 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6744
6835
}
6745
6836
else
6746
6837
{
6747
- if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts ))
6838
+ if (!Op_JitNeq(result, src1Val, src2Val, src1Var, src2Var, this->func, true /* isStrict */ ))
6748
6839
{
6749
- // TODO: OOP JIT, const folding
6750
6840
return false;
6751
6841
}
6752
- *result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6753
6842
}
6754
6843
break;
6755
6844
0 commit comments