From 1351ebbb40478af0b779fdc9060d5346ac1d8774 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 27 Jul 2022 23:06:39 -0700 Subject: [PATCH 1/7] Add bunch of shortcircuit checks --- src/coreclr/jit/assertionprop.cpp | 15 +++++++++++++++ src/coreclr/jit/compiler.cpp | 4 ++++ src/coreclr/jit/compiler.h | 5 +++++ 3 files changed, 24 insertions(+) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 45ca1da3915f47..db488ce9e9dace 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -1350,6 +1350,7 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, assertion.op1.kind = O1K_ARR_BND; assertion.op1.bnd.vnIdx = optConservativeNormalVN(arrBndsChk->GetIndex()); assertion.op1.bnd.vnLen = optConservativeNormalVN(arrBndsChk->GetArrayLength()); + optCanPropBndsChk = true; goto DONE_ASSERTION; } } @@ -2228,6 +2229,7 @@ AssertionIndex Compiler::optAssertionGenCast(GenTreeCast* cast) assertion.op1.lcl.ssaNum = lclVar->GetSsaNum(); assertion.op2.kind = O2K_SUBRANGE; assertion.op2.u2 = IntegralRange::ForCastInput(cast); + optCanPropSubRange = true; return optFinalizeCreatingAssertion(&assertion); } @@ -2370,6 +2372,7 @@ AssertionInfo Compiler::optCreateJTrueBoundsAssertion(GenTree* tree) dsc.op1.bnd.vnLen = vnStore->VNNormalValue(unsignedCompareBnd.vnBound); dsc.op2.kind = O2K_INVALID; dsc.op2.vn = ValueNumStore::NoVN; + optCanPropBndsChk = true; AssertionIndex index = optAddAssertion(&dsc); if (unsignedCompareBnd.cmpOper == VNF_GE_UN) @@ -2839,6 +2842,8 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran (curAssertion->assertionKind == OAK_SUBRANGE) && (curAssertion->op1.kind == O1K_LCLVAR)) { + assert(optCanPropSubRange); + // For local assertion prop use comparison on locals, and use comparison on vns for global prop. bool isEqual = optLocalAssertionProp ? (curAssertion->op1.lcl.lclNum == tree->AsLclVarCommon()->GetLclNum()) @@ -3613,6 +3618,8 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL continue; } + assert(optCanPropLclVar); + // Copy prop. if (curAssertion->op2.kind == O2K_LCLVAR_COPY) { @@ -3814,6 +3821,8 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as continue; } + assert(optCanPropEqual); + if ((curAssertion->op1.vn == vnStore->VNConservativeNormalValue(op1->gtVNPair)) && (curAssertion->op2.vn == vnStore->VNConservativeNormalValue(op2->gtVNPair))) { @@ -3867,6 +3876,8 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_T continue; } + assert(optCanPropEqual); + if ((curAssertion->op1.vn == vnStore->VNConservativeNormalValue(op1->gtVNPair)) && (curAssertion->op2.vn == vnStore->VNZeroForType(op1->TypeGet()))) { @@ -4541,6 +4552,8 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op, continue; } + assert(optCanPropNonNull); + if ((curAssertion->op1.vn != vn) && (curAssertion->op1.vn != vnBase)) { continue; @@ -4719,6 +4732,8 @@ GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree continue; } + assert(optCanPropBndsChk); + GenTreeBoundsChk* arrBndsChk = tree->AsBoundsChk(); // Set 'isRedundant' to true if we can determine that 'arrBndsChk' can be diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index e73052a780f60f..ae3548d3256c5d 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -6400,6 +6400,10 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, compHasBackwardJump = false; compHasBackwardJumpInHandler = false; + optCanPropLclVar = false; + optCanPropEqual = false; + optCanPropNonNull = false; + optCanPropBndsChk = false; #ifdef DEBUG compCurBB = nullptr; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 3291aca767c382..145eeee2fc2949 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7231,6 +7231,11 @@ class Compiler AssertionDsc* optAssertionTabPrivate; // table that holds info about value assignments AssertionIndex optAssertionCount; // total number of assertions in the assertion table AssertionIndex optMaxAssertionCount; + bool optCanPropLclVar; + bool optCanPropEqual; + bool optCanPropNonNull; + bool optCanPropBndsChk; + bool optCanPropSubRange; public: void optVnNonNullPropCurStmt(BasicBlock* block, Statement* stmt, GenTree* tree); From 432d3151b375c295a081e2243d754a8166db62f3 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 29 Jul 2022 15:41:13 -0700 Subject: [PATCH 2/7] shortcircuit varTypeIsStruct() --- src/coreclr/jit/assertionprop.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index db488ce9e9dace..0f0ee0e698d32c 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3602,6 +3602,13 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL return nullptr; } + // There are no constant assertions for structs in global propagation. + // + if (!optLocalAssertionProp && varTypeIsStruct(tree)) + { + return nullptr; + } + BitVecOps::Iter iter(apTraits, assertions); unsigned index = 0; while (iter.NextElem(&index)) From 9c334508d6e6b00076334dbfcb59031649cf08b8 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 29 Jul 2022 17:21:59 -0700 Subject: [PATCH 3/7] optCanPropBndsChk --- src/coreclr/jit/assertionprop.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 0f0ee0e698d32c..9bb430a6f320fc 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -4701,7 +4701,7 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal */ GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt) { - if (optLocalAssertionProp) + if (optLocalAssertionProp || !optCanPropBndsChk) { return nullptr; } @@ -4739,8 +4739,6 @@ GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree continue; } - assert(optCanPropBndsChk); - GenTreeBoundsChk* arrBndsChk = tree->AsBoundsChk(); // Set 'isRedundant' to true if we can determine that 'arrBndsChk' can be From 16f9f8fa36804eb75cc8eaf7d9661b4cc098a8f4 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 29 Jul 2022 17:37:01 -0700 Subject: [PATCH 4/7] Add some shortcircuit code --- src/coreclr/jit/assertionprop.cpp | 36 +++++++++++++++++-------------- src/coreclr/jit/compiler.cpp | 4 ---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 9bb430a6f320fc..c066cc0c44a396 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -979,6 +979,10 @@ void Compiler::optAssertionInit(bool isLocalProp) optAssertionCount = 0; optAssertionPropagated = false; bbJtrueAssertionOut = nullptr; + optCanPropLclVar = false; + optCanPropEqual = false; + optCanPropNonNull = false; + optCanPropBndsChk = false; } #ifdef DEBUG @@ -1350,7 +1354,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, assertion.op1.kind = O1K_ARR_BND; assertion.op1.bnd.vnIdx = optConservativeNormalVN(arrBndsChk->GetIndex()); assertion.op1.bnd.vnLen = optConservativeNormalVN(arrBndsChk->GetArrayLength()); - optCanPropBndsChk = true; goto DONE_ASSERTION; } } @@ -1997,6 +2000,13 @@ AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion) } #endif // DEBUG + optCanPropLclVar |= newAssertion->assertionKind == OAK_EQUAL && newAssertion->op1.kind != O1K_LCLVAR; + optCanPropEqual |= newAssertion->assertionKind == OAK_EQUAL || newAssertion->assertionKind == OAK_NOT_EQUAL; + optCanPropNonNull |= + newAssertion->assertionKind == OAK_NOT_EQUAL && newAssertion->op2.vn == ValueNumStore::VNForNull(); + optCanPropSubRange |= newAssertion->assertionKind == OAK_SUBRANGE && newAssertion->op1.kind == O1K_LCLVAR; + optCanPropBndsChk |= newAssertion->op1.kind == O1K_ARR_BND; + // Assertion mask bits are [index + 1]. if (optLocalAssertionProp) { @@ -2372,7 +2382,6 @@ AssertionInfo Compiler::optCreateJTrueBoundsAssertion(GenTree* tree) dsc.op1.bnd.vnLen = vnStore->VNNormalValue(unsignedCompareBnd.vnBound); dsc.op2.kind = O2K_INVALID; dsc.op2.vn = ValueNumStore::NoVN; - optCanPropBndsChk = true; AssertionIndex index = optAddAssertion(&dsc); if (unsignedCompareBnd.cmpOper == VNF_GE_UN) @@ -2829,7 +2838,7 @@ AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex) // AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange range, ASSERT_VALARG_TP assertions) { - if (!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions)) + if ((!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions) || !optCanPropSubRange) { return NO_ASSERTION_INDEX; } @@ -2842,8 +2851,6 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran (curAssertion->assertionKind == OAK_SUBRANGE) && (curAssertion->op1.kind == O1K_LCLVAR)) { - assert(optCanPropSubRange); - // For local assertion prop use comparison on locals, and use comparison on vns for global prop. bool isEqual = optLocalAssertionProp ? (curAssertion->op1.lcl.lclNum == tree->AsLclVarCommon()->GetLclNum()) @@ -3604,7 +3611,7 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL // There are no constant assertions for structs in global propagation. // - if (!optLocalAssertionProp && varTypeIsStruct(tree)) + if ((!optLocalAssertionProp && varTypeIsStruct(tree)) || !optCanPropLclVar) { return nullptr; } @@ -3625,8 +3632,6 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL continue; } - assert(optCanPropLclVar); - // Copy prop. if (curAssertion->op2.kind == O2K_LCLVAR_COPY) { @@ -3809,7 +3814,7 @@ AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual( // AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions, GenTree* op1, GenTree* op2) { - if (BitVecOps::IsEmpty(apTraits, assertions)) + if (BitVecOps::IsEmpty(apTraits, assertions) || !optCanPropEqual) { return NO_ASSERTION_INDEX; } @@ -3828,8 +3833,6 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as continue; } - assert(optCanPropEqual); - if ((curAssertion->op1.vn == vnStore->VNConservativeNormalValue(op1->gtVNPair)) && (curAssertion->op2.vn == vnStore->VNConservativeNormalValue(op2->gtVNPair))) { @@ -3864,7 +3867,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as */ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_TP assertions, GenTree* op1) { - if (BitVecOps::IsEmpty(apTraits, assertions)) + if (BitVecOps::IsEmpty(apTraits, assertions) || !optCanPropEqual) { return NO_ASSERTION_INDEX; } @@ -3883,8 +3886,6 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_T continue; } - assert(optCanPropEqual); - if ((curAssertion->op1.vn == vnStore->VNConservativeNormalValue(op1->gtVNPair)) && (curAssertion->op2.vn == vnStore->VNZeroForType(op1->TypeGet()))) { @@ -4505,6 +4506,11 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op, *pVnBased = false; #endif + if (!optCanPropNonNull) + { + return NO_ASSERTION_INDEX; + } + // If local assertion prop use lcl comparison, else use VN comparison. if (!optLocalAssertionProp) { @@ -4559,8 +4565,6 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op, continue; } - assert(optCanPropNonNull); - if ((curAssertion->op1.vn != vn) && (curAssertion->op1.vn != vnBase)) { continue; diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index ae3548d3256c5d..e73052a780f60f 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -6400,10 +6400,6 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, compHasBackwardJump = false; compHasBackwardJumpInHandler = false; - optCanPropLclVar = false; - optCanPropEqual = false; - optCanPropNonNull = false; - optCanPropBndsChk = false; #ifdef DEBUG compCurBB = nullptr; From 337ee1dc0c1c18920d206282ca66fd5a5420ad22 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Sat, 30 Jul 2022 09:49:30 -0700 Subject: [PATCH 5/7] jit format --- src/coreclr/jit/assertionprop.cpp | 3 ++- src/coreclr/jit/compiler.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index c066cc0c44a396..8e888f9e65f0a0 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -983,6 +983,7 @@ void Compiler::optAssertionInit(bool isLocalProp) optCanPropEqual = false; optCanPropNonNull = false; optCanPropBndsChk = false; + optCanPropSubRange = false; } #ifdef DEBUG @@ -2838,7 +2839,7 @@ AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex) // AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange range, ASSERT_VALARG_TP assertions) { - if ((!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions) || !optCanPropSubRange) + if ((!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions)) || !optCanPropSubRange) { return NO_ASSERTION_INDEX; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 145eeee2fc2949..17697dbc03d69b 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7231,11 +7231,11 @@ class Compiler AssertionDsc* optAssertionTabPrivate; // table that holds info about value assignments AssertionIndex optAssertionCount; // total number of assertions in the assertion table AssertionIndex optMaxAssertionCount; - bool optCanPropLclVar; - bool optCanPropEqual; - bool optCanPropNonNull; - bool optCanPropBndsChk; - bool optCanPropSubRange; + bool optCanPropLclVar; + bool optCanPropEqual; + bool optCanPropNonNull; + bool optCanPropBndsChk; + bool optCanPropSubRange; public: void optVnNonNullPropCurStmt(BasicBlock* block, Statement* stmt, GenTree* tree); From 324e4d877bc6ca81df34738a5142dd4cfee136a0 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Sat, 30 Jul 2022 09:54:31 -0700 Subject: [PATCH 6/7] Fix a bug --- src/coreclr/jit/assertionprop.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 8e888f9e65f0a0..3714b56387bd96 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -2001,7 +2001,8 @@ AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion) } #endif // DEBUG - optCanPropLclVar |= newAssertion->assertionKind == OAK_EQUAL && newAssertion->op1.kind != O1K_LCLVAR; + // Track the shortcircuit criterias + optCanPropLclVar |= newAssertion->assertionKind == OAK_EQUAL && newAssertion->op1.kind == O1K_LCLVAR; optCanPropEqual |= newAssertion->assertionKind == OAK_EQUAL || newAssertion->assertionKind == OAK_NOT_EQUAL; optCanPropNonNull |= newAssertion->assertionKind == OAK_NOT_EQUAL && newAssertion->op2.vn == ValueNumStore::VNForNull(); From 9b44443af58c1e6586bc59e3c36661f067397063 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Sun, 31 Jul 2022 23:23:39 -0700 Subject: [PATCH 7/7] Added helper methods to have consistent checks --- src/coreclr/jit/assertionprop.cpp | 28 ++++++++++------------------ src/coreclr/jit/compiler.h | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 3714b56387bd96..e1f24367d17eae 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -2002,12 +2002,11 @@ AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion) #endif // DEBUG // Track the shortcircuit criterias - optCanPropLclVar |= newAssertion->assertionKind == OAK_EQUAL && newAssertion->op1.kind == O1K_LCLVAR; - optCanPropEqual |= newAssertion->assertionKind == OAK_EQUAL || newAssertion->assertionKind == OAK_NOT_EQUAL; - optCanPropNonNull |= - newAssertion->assertionKind == OAK_NOT_EQUAL && newAssertion->op2.vn == ValueNumStore::VNForNull(); - optCanPropSubRange |= newAssertion->assertionKind == OAK_SUBRANGE && newAssertion->op1.kind == O1K_LCLVAR; - optCanPropBndsChk |= newAssertion->op1.kind == O1K_ARR_BND; + optCanPropLclVar |= newAssertion->CanPropLclVar(); + optCanPropEqual |= newAssertion->CanPropEqualOrNotEqual(); + optCanPropNonNull |= newAssertion->CanPropNonNull(); + optCanPropSubRange |= newAssertion->CanPropSubRange(); + optCanPropBndsChk |= newAssertion->CanPropBndsCheck(); // Assertion mask bits are [index + 1]. if (optLocalAssertionProp) @@ -2241,7 +2240,6 @@ AssertionIndex Compiler::optAssertionGenCast(GenTreeCast* cast) assertion.op1.lcl.ssaNum = lclVar->GetSsaNum(); assertion.op2.kind = O2K_SUBRANGE; assertion.op2.u2 = IntegralRange::ForCastInput(cast); - optCanPropSubRange = true; return optFinalizeCreatingAssertion(&assertion); } @@ -2850,8 +2848,7 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran AssertionDsc* curAssertion = optGetAssertion(index); if ((optLocalAssertionProp || BitVecOps::IsMember(apTraits, assertions, index - 1)) && // either local prop or use propagated assertions - (curAssertion->assertionKind == OAK_SUBRANGE) && - (curAssertion->op1.kind == O1K_LCLVAR)) + curAssertion->CanPropSubRange()) { // For local assertion prop use comparison on locals, and use comparison on vns for global prop. bool isEqual = optLocalAssertionProp @@ -3629,7 +3626,7 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL } // See if the variable is equal to a constant or another variable. AssertionDsc* curAssertion = optGetAssertion(assertionIndex); - if (curAssertion->assertionKind != OAK_EQUAL || curAssertion->op1.kind != O1K_LCLVAR) + if (!curAssertion->CanPropLclVar()) { continue; } @@ -3830,7 +3827,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as break; } AssertionDsc* curAssertion = optGetAssertion(assertionIndex); - if ((curAssertion->assertionKind != OAK_EQUAL && curAssertion->assertionKind != OAK_NOT_EQUAL)) + if (!curAssertion->CanPropEqualOrNotEqual()) { continue; } @@ -3883,7 +3880,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_T break; } AssertionDsc* curAssertion = optGetAssertion(assertionIndex); - if ((curAssertion->assertionKind != OAK_EQUAL && curAssertion->assertionKind != OAK_NOT_EQUAL)) + if (!curAssertion->CanPropEqualOrNotEqual()) { continue; } @@ -4557,12 +4554,7 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op, break; } AssertionDsc* curAssertion = optGetAssertion(assertionIndex); - if (curAssertion->assertionKind != OAK_NOT_EQUAL) - { - continue; - } - - if (curAssertion->op2.vn != ValueNumStore::VNForNull()) + if (!curAssertion->CanPropNonNull()) { continue; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 17697dbc03d69b..0b201557d526cd 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7110,6 +7110,31 @@ class Compiler return ((assertionKind == OAK_EQUAL) || (assertionKind == OAK_NOT_EQUAL)) && (op2.kind == O2K_CONST_INT); } + bool CanPropLclVar() + { + return assertionKind == OAK_EQUAL && op1.kind == O1K_LCLVAR; + } + + bool CanPropEqualOrNotEqual() + { + return assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL; + } + + bool CanPropNonNull() + { + return assertionKind == OAK_NOT_EQUAL && op2.vn == ValueNumStore::VNForNull(); + } + + bool CanPropBndsCheck() + { + return op1.kind == O1K_ARR_BND; + } + + bool CanPropSubRange() + { + return assertionKind == OAK_SUBRANGE && op1.kind == O1K_LCLVAR; + } + static bool SameKind(AssertionDsc* a1, AssertionDsc* a2) { return a1->assertionKind == a2->assertionKind && a1->op1.kind == a2->op1.kind &&