diff --git a/src/coreclr/src/jit/assertionprop.cpp b/src/coreclr/src/jit/assertionprop.cpp index 031d4867d87..450f98018db 100644 --- a/src/coreclr/src/jit/assertionprop.cpp +++ b/src/coreclr/src/jit/assertionprop.cpp @@ -854,7 +854,7 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, if (op2 == nullptr) { // - // Must an OAK_NOT_EQUAL assertion + // Must be an OAK_NOT_EQUAL assertion // noway_assert(assertionKind == OAK_NOT_EQUAL); @@ -1796,6 +1796,23 @@ AssertionInfo Compiler::optCreateJTrueBoundsAssertion(GenTree* tree) optCreateComplementaryAssertion(index, nullptr, nullptr); return index; } + // Cases where op1 holds the lhs of the condition and op2 holds the bound arithmetic. + // Loop condition like: "i < bnd +/-k" + // Assertion: "i < bnd +/- k != 0" + else if (vnStore->IsVNCompareCheckedBoundArith(relopVN)) + { + AssertionDsc dsc; + dsc.assertionKind = OAK_NOT_EQUAL; + dsc.op1.kind = O1K_BOUND_OPER_BND; + dsc.op1.vn = relopVN; + dsc.op2.kind = O2K_CONST_INT; + dsc.op2.vn = vnStore->VNZeroForType(op2->TypeGet()); + dsc.op2.u1.iconVal = 0; + dsc.op2.u1.iconFlags = 0; + AssertionIndex index = optAddAssertion(&dsc); + optCreateComplementaryAssertion(index, nullptr, nullptr); + return index; + } // Cases where op1 holds the upper bound and op2 is 0. // Loop condition like: "i < bnd == 0" // Assertion: "i < bnd == false" diff --git a/src/coreclr/src/jit/rangecheck.cpp b/src/coreclr/src/jit/rangecheck.cpp index 3019824427f..c4fcc85b07b 100644 --- a/src/coreclr/src/jit/rangecheck.cpp +++ b/src/coreclr/src/jit/rangecheck.cpp @@ -348,7 +348,13 @@ bool RangeCheck::IsBinOpMonotonicallyIncreasing(GenTreeOp* binop) return IsMonotonicallyIncreasing(op1, true) && IsMonotonicallyIncreasing(op2, true); case GT_CNS_INT: - return (op2->AsIntConCommon()->IconValue() >= 0) && IsMonotonicallyIncreasing(op1, false); + if (op2->AsIntConCommon()->IconValue() < 0) + { + JITDUMP("Not monotonically increasing because of encountered negative constant\n"); + return false; + } + + return IsMonotonicallyIncreasing(op1, false); default: JITDUMP("Not monotonically increasing because expression is not recognized.\n"); @@ -420,6 +426,10 @@ bool RangeCheck::IsMonotonicallyIncreasing(GenTree* expr, bool rejectNegativeCon } return true; } + else if (expr->OperGet() == GT_COMMA) + { + return IsMonotonicallyIncreasing(expr->gtEffectiveVal(), rejectNegativeConst); + } JITDUMP("Unknown tree type\n"); return false; } @@ -729,7 +739,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreeLclVarCommon* lcl, ASSERT_VALARG_TP } // Merge assertions from the pred edges of the block, i.e., check for any assertions about "op's" value numbers for phi -// arguments. If not a phi argument, check if we assertions about local variables. +// arguments. If not a phi argument, check if we have assertions about local variables. void RangeCheck::MergeAssertion(BasicBlock* block, GenTree* op, Range* pRange DEBUGARG(int indent)) { JITDUMP("Merging assertions from pred edges of " FMT_BB " for op [%06d] " FMT_VN "\n", block->bbNum, @@ -1217,6 +1227,10 @@ Range RangeCheck::ComputeRange(BasicBlock* block, GenTree* expr, bool monIncreas JITDUMP("%s\n", range.ToString(m_pCompiler->getAllocatorDebugOnly())); } + else if (expr->OperGet() == GT_COMMA) + { + range = GetRange(block, expr->gtEffectiveVal(), monIncreasing DEBUGARG(indent + 1)); + } else { // The expression is not recognized, so the result is unknown.