diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp index 475f2cb91605d3..e362d73bac21d1 100644 --- a/src/coreclr/jit/rangecheck.cpp +++ b/src/coreclr/jit/rangecheck.cpp @@ -1163,6 +1163,9 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp, } else if (normalLclVN == lenVN) { + ValueNum indexOp1VN; + int indexOp2Cns; + if (comp->vnStore->IsVNInt32Constant(indexVN)) { // We have "Const < arr.Length" assertion, it means that "arr.Length > Const" @@ -1177,6 +1180,14 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp, continue; } } + // arr[arr.Length - CNS] means arr.Length >= CNS, so we can deduce "normalLclVN >= CNS" + // On the VN level it's VNF_ADD(normalLclVN, -CNS). + else if (comp->vnStore->IsVNBinFuncWithConst(indexVN, VNF_ADD, &indexOp1VN, &indexOp2Cns) && + (indexOp1VN == normalLclVN) && (indexOp2Cns < 0) && (indexOp2Cns > INT32_MIN)) + { + cmpOper = GT_GE; + limit = Limit(Limit::keConstant, -indexOp2Cns); + } else { // We've seen arr[unknown_index] assertion while normalLclVN == arr.Length.