diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index cd0f28d0bc2914..6a059f865f4116 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -1337,55 +1337,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, GenTree* op2, bool equ return NO_ASSERTION_INDEX; } -/***************************************************************************** - * - * If tree is a constant node holding an integral value, retrieve the value in - * pConstant. If the method returns true, pConstant holds the appropriate - * constant. Set "vnBased" to true to indicate local or global assertion prop. - * "pFlags" indicates if the constant is a handle marked by GTF_ICON_HDL_MASK. - */ -bool Compiler::optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, GenTreeFlags* pFlags) -{ - // Is Local assertion prop? - if (!vnBased) - { - if (tree->OperIs(GT_CNS_INT)) - { - *pConstant = tree->AsIntCon()->IconValue(); - *pFlags = tree->GetIconHandleFlag(); - return true; - } - return false; - } - - // Global assertion prop - ValueNum vn = vnStore->VNConservativeNormalValue(tree->gtVNPair); - if (!vnStore->IsVNConstant(vn)) - { - return false; - } - - // ValueNumber 'vn' indicates that this node evaluates to a constant - - var_types vnType = vnStore->TypeOfVN(vn); - if (vnType == TYP_INT) - { - *pConstant = vnStore->ConstantValue(vn); - *pFlags = vnStore->IsVNHandle(vn) ? vnStore->GetHandleFlags(vn) : GTF_EMPTY; - return true; - } -#ifdef TARGET_64BIT - else if (vnType == TYP_LONG) - { - *pConstant = vnStore->ConstantValue(vn); - *pFlags = vnStore->IsVNHandle(vn) ? vnStore->GetHandleFlags(vn) : GTF_EMPTY; - return true; - } -#endif - - return false; -} - /***************************************************************************** * * Given an assertion add it to the assertion table diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ebce8cdf96ca8e..5607ef74193291 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9075,7 +9075,6 @@ class Compiler // Assertion prop data flow functions. PhaseStatus optAssertionPropMain(); Statement* optVNAssertionPropCurStmt(BasicBlock* block, Statement* stmt); - bool optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, GenTreeFlags* pIconFlags); ASSERT_TP* optInitAssertionDataflowFlags(); ASSERT_TP* optComputeAssertionGen(); diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp index f855c9c5175970..222c0b839950f6 100644 --- a/src/coreclr/jit/rangecheck.cpp +++ b/src/coreclr/jit/rangecheck.cpp @@ -272,73 +272,15 @@ void RangeCheck::OptimizeRangeCheck(BasicBlock* block, Statement* stmt, GenTree* return; } - GenTree* comma = treeParent->OperIs(GT_COMMA) ? treeParent : nullptr; - GenTreeBoundsChk* bndsChk = tree->AsBoundsChk(); - m_preferredBound = m_compiler->vnStore->VNConservativeNormalValue(bndsChk->GetArrayLength()->gtVNPair); - GenTree* treeIndex = bndsChk->GetIndex(); + GenTree* comma = treeParent->OperIs(GT_COMMA) ? treeParent : nullptr; + GenTreeBoundsChk* bndsChk = tree->AsBoundsChk(); + GenTree* treeIndex = bndsChk->GetIndex(); // Take care of constant index first, like a[2], for example. - ValueNum idxVn = m_compiler->vnStore->VNConservativeNormalValue(treeIndex->gtVNPair); - ValueNum arrLenVn = m_compiler->vnStore->VNConservativeNormalValue(bndsChk->GetArrayLength()->gtVNPair); - int arrSize = 0; + ValueNum idxVn = m_compiler->optConservativeNormalVN(treeIndex); + ValueNum arrLenVn = m_compiler->optConservativeNormalVN(bndsChk->GetArrayLength()); - if (m_compiler->vnStore->IsVNConstant(arrLenVn)) - { - ssize_t constVal = -1; - GenTreeFlags iconFlags = GTF_EMPTY; - - if (m_compiler->optIsTreeKnownIntValue(true, bndsChk->GetArrayLength(), &constVal, &iconFlags)) - { - arrSize = (int)constVal; - } - } - else - { - arrSize = GetArrLength(arrLenVn); - - // if we can't find the array length, see if there - // are any assertions about the array size we can use to get a minimum length - if (arrSize <= 0) - { - JITDUMP("Looking for array size assertions for: " FMT_VN "\n", arrLenVn); - Range arrLength = Range(Limit(Limit::keDependent)); - MergeEdgeAssertions(m_compiler, arrLenVn, arrLenVn, block->bbAssertionIn, &arrLength); - if (arrLength.lLimit.IsConstant()) - { - arrSize = arrLength.lLimit.GetConstant(); - } - else - { - // Fast path didn't find anything - do the slow SSA-based search. - arrLength = GetRangeWorker(block, bndsChk->GetArrayLength(), false DEBUGARG(0)); - if (arrLength.lLimit.IsConstant()) - { - arrSize = arrLength.lLimit.GetConstant(); - } - } - } - } - - JITDUMP("ArrSize for lengthVN:%03X = %d\n", arrLenVn, arrSize); - if (m_compiler->vnStore->IsVNConstant(idxVn) && (arrSize > 0)) - { - ssize_t idxVal = -1; - GenTreeFlags iconFlags = GTF_EMPTY; - if (!m_compiler->optIsTreeKnownIntValue(true, treeIndex, &idxVal, &iconFlags)) - { - return; - } - - JITDUMP("[RangeCheck::OptimizeRangeCheck] Is index %d in <0, arrLenVn " FMT_VN " sz:%d>.\n", idxVal, arrLenVn, - arrSize); - if ((idxVal < arrSize) && (idxVal >= 0)) - { - JITDUMP("Removing range check\n"); - m_compiler->optRemoveRangeCheck(bndsChk, comma, stmt); - m_updateStmt = true; - return; - } - } + m_preferredBound = arrLenVn; // Special case: arr[arr.Length - CNS] if we know that arr.Length >= CNS // We assume that SUB(x, CNS) is canonized into ADD(x, -CNS) @@ -428,6 +370,9 @@ void RangeCheck::OptimizeRangeCheck(BasicBlock* block, Statement* stmt, GenTree* return; } + Range arrSizeRng = GetRangeFromAssertions(m_compiler, arrLenVn, block->bbAssertionIn); + int arrSize = arrSizeRng.LowerLimit().GetConstant(); + // Is the range between the lower and upper bound values. if (BetweenBounds(range, bndsChk->GetArrayLength(), arrSize)) {