@@ -6505,11 +6505,18 @@ bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src
6505
6505
bool
6506
6506
GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2Val, Js::Var src1Var, Js::Var src2Var, bool *result)
6507
6507
{
6508
- auto AreSourcesEqual = [&](Value * val1, Value * val2) -> bool
6508
+ auto AreSourcesEqual = [&](Value * val1, Value * val2, bool undefinedCmp ) -> bool
6509
6509
{
6510
6510
// NaN !== NaN, and objects can have valueOf/toString
6511
- return val1->IsEqualTo(val2) &&
6512
- val1->GetValueInfo()->IsPrimitive() && val1->GetValueInfo()->IsNotFloat();
6511
+ if (val1->IsEqualTo(val2))
6512
+ {
6513
+ if (val1->GetValueInfo()->IsUndefined())
6514
+ {
6515
+ return undefinedCmp;
6516
+ }
6517
+ return val1->GetValueInfo()->IsPrimitive() && val1->GetValueInfo()->IsNotFloat();
6518
+ }
6519
+ return false;
6513
6520
};
6514
6521
6515
6522
// Make sure GetConstantVar only returns primitives.
@@ -6523,7 +6530,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6523
6530
6524
6531
switch (instr->m_opcode)
6525
6532
{
6526
- #define BRANCHSIGNED(OPCODE,CMP,TYPE,UNSIGNEDNESS) \
6533
+ #define BRANCHSIGNED(OPCODE,CMP,TYPE,UNSIGNEDNESS,UNDEFINEDCMP ) \
6527
6534
case Js::OpCode::##OPCODE: \
6528
6535
if (src1Val && src2Val) \
6529
6536
{ \
@@ -6537,7 +6544,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6537
6544
{ \
6538
6545
*result = (TYPE)left64 CMP(TYPE)right64; \
6539
6546
} \
6540
- else if (AreSourcesEqual(src1Val, src2Val)) \
6547
+ else if (AreSourcesEqual(src1Val, src2Val, UNDEFINEDCMP )) \
6541
6548
{ \
6542
6549
*result = 0 CMP 0; \
6543
6550
} \
@@ -6552,25 +6559,25 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6552
6559
} \
6553
6560
break;
6554
6561
6555
- BRANCHSIGNED(BrEq_I4, == , int64, false)
6556
- BRANCHSIGNED(BrGe_I4, >= , int64, false)
6557
- BRANCHSIGNED(BrGt_I4, > , int64, false)
6558
- BRANCHSIGNED(BrLt_I4, < , int64, false)
6559
- BRANCHSIGNED(BrLe_I4, <= , int64, false)
6560
- BRANCHSIGNED(BrNeq_I4, != , int64, false)
6561
- BRANCHSIGNED(BrUnGe_I4, >= , uint64, true)
6562
- BRANCHSIGNED(BrUnGt_I4, > , uint64, true)
6563
- BRANCHSIGNED(BrUnLt_I4, < , uint64, true)
6564
- BRANCHSIGNED(BrUnLe_I4, <= , uint64, true)
6562
+ BRANCHSIGNED(BrEq_I4, == , int64, false, true )
6563
+ BRANCHSIGNED(BrGe_I4, >= , int64, false, false )
6564
+ BRANCHSIGNED(BrGt_I4, > , int64, false, false )
6565
+ BRANCHSIGNED(BrLt_I4, < , int64, false, false )
6566
+ BRANCHSIGNED(BrLe_I4, <= , int64, false, false )
6567
+ BRANCHSIGNED(BrNeq_I4, != , int64, false, false )
6568
+ BRANCHSIGNED(BrUnGe_I4, >= , uint64, true, false )
6569
+ BRANCHSIGNED(BrUnGt_I4, > , uint64, true, false )
6570
+ BRANCHSIGNED(BrUnLt_I4, < , uint64, true, false )
6571
+ BRANCHSIGNED(BrUnLe_I4, <= , uint64, true, false )
6565
6572
#undef BRANCHSIGNED
6566
- #define BRANCH(OPCODE,CMP,VARCMPFUNC) \
6573
+ #define BRANCH(OPCODE,CMP,VARCMPFUNC,UNDEFINEDCMP ) \
6567
6574
case Js::OpCode::##OPCODE: \
6568
6575
if (src1Val && src2Val && src1Val->GetValueInfo()->TryGetIntConstantValue(&left) && \
6569
6576
src2Val->GetValueInfo()->TryGetIntConstantValue(&right)) \
6570
6577
{ \
6571
6578
*result = left CMP right; \
6572
6579
} \
6573
- else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val)) \
6580
+ else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val, UNDEFINEDCMP )) \
6574
6581
{ \
6575
6582
*result = 0 CMP 0; \
6576
6583
} \
@@ -6588,14 +6595,14 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6588
6595
} \
6589
6596
break;
6590
6597
6591
- BRANCH(BrGe_A, >= , Js::JavascriptOperators::GreaterEqual)
6592
- BRANCH(BrNotGe_A, <, !Js::JavascriptOperators::GreaterEqual)
6593
- BRANCH(BrLt_A, <, Js::JavascriptOperators::Less)
6594
- BRANCH(BrNotLt_A, >= , !Js::JavascriptOperators::Less)
6595
- BRANCH(BrGt_A, >, Js::JavascriptOperators::Greater)
6596
- BRANCH(BrNotGt_A, <= , !Js::JavascriptOperators::Greater)
6597
- BRANCH(BrLe_A, <= , Js::JavascriptOperators::LessEqual)
6598
- BRANCH(BrNotLe_A, >, !Js::JavascriptOperators::LessEqual)
6598
+ BRANCH(BrGe_A, >= , Js::JavascriptOperators::GreaterEqual, /*undefinedEquality*/ false )
6599
+ BRANCH(BrNotGe_A, <, !Js::JavascriptOperators::GreaterEqual, false )
6600
+ BRANCH(BrLt_A, <, Js::JavascriptOperators::Less, false )
6601
+ BRANCH(BrNotLt_A, >= , !Js::JavascriptOperators::Less, false )
6602
+ BRANCH(BrGt_A, >, Js::JavascriptOperators::Greater, false )
6603
+ BRANCH(BrNotGt_A, <= , !Js::JavascriptOperators::Greater, false )
6604
+ BRANCH(BrLe_A, <= , Js::JavascriptOperators::LessEqual, false )
6605
+ BRANCH(BrNotLe_A, >, !Js::JavascriptOperators::LessEqual, false )
6599
6606
#undef BRANCH
6600
6607
case Js::OpCode::BrEq_A:
6601
6608
case Js::OpCode::BrNotNeq_A:
@@ -6604,7 +6611,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6604
6611
{
6605
6612
*result = left == right;
6606
6613
}
6607
- else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val))
6614
+ else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val, true ))
6608
6615
{
6609
6616
*result = true;
6610
6617
}
@@ -6636,7 +6643,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6636
6643
{
6637
6644
*result = left != right;
6638
6645
}
6639
- else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val))
6646
+ else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val, true ))
6640
6647
{
6641
6648
*result = false;
6642
6649
}
@@ -6683,7 +6690,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6683
6690
{
6684
6691
*result = false;
6685
6692
}
6686
- else if (AreSourcesEqual(src1Val, src2Val))
6693
+ else if (AreSourcesEqual(src1Val, src2Val, true ))
6687
6694
{
6688
6695
*result = true;
6689
6696
}
@@ -6725,7 +6732,7 @@ GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2
6725
6732
{
6726
6733
*result = true;
6727
6734
}
6728
- else if (AreSourcesEqual(src1Val, src2Val))
6735
+ else if (AreSourcesEqual(src1Val, src2Val, true ))
6729
6736
{
6730
6737
*result = false;
6731
6738
}
0 commit comments