JIT: tighten IV range from "i != bound" assertions in rangecheck#129303
JIT: tighten IV range from "i != bound" assertions in rangecheck#129303AndyAyersMS wants to merge 1 commit into
Conversation
Follow-on to "JIT: clone i != arr.Length loops to eliminate bounds checks". The cloning change handles NE-loop BCE for loops the cloning heuristic accepts. This change extends NE-loop BCE to cases that fall outside loop cloning (e.g. loops with side-effecting calls in the body that the cloning heuristic rejects). Extend optCreateJTrueBoundsAssertion to create CompareCheckedBound assertions for EQ/NE against a checked bound, and teach RangeCheck::MergeAssertion to tighten ranges using `X != bound` / `X == bound`. For equality assertions where the non-bound side is a constant, defer to the existing LCLVAR-based equality assertion path to preserve downstream consumers that rely on it (e.g. proving `len > 0` after a `len != 0` check). Contributes to dotnet#84697.
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR extends CoreCLR JIT assertion generation and RangeCheck range-tightening to better exploit loop conditions of the form i != <checked-bound> (e.g., i != arr.Length) by creating/consuming checked-bound equality/inequality assertions to tighten IV ranges and enable more bounds-check elimination outside of loop cloning.
Changes:
- Teach
optCreateJTrueBoundsAssertionto generateCompareCheckedBoundassertions forEQ/NEagainst checked bounds (while deferring checked-bound-vs-constant equalities to existing equality assertion paths). - Extend
RangeCheck::MergeEdgeAssertionsWorkerto tighten ranges usingX != bound(when an existing limit is exactlybound) andX == bound. - Relax debug validation to allow
O2K_VN_ADD_CNSassertions that are equality/inequality (not only ordered relops).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/rangecheck.cpp | Tightens IV ranges based on checked-bound ==/!= assertions when limits match the bound. |
| src/coreclr/jit/assertionprop.cpp | Generates checked-bound ==/!= assertions for JTRUE relops and updates debug assertion validation accordingly. |
| // the bound. Tighten: | ||
| // [lo, bound] -> [lo, bound - 1] | ||
| // [bound, hi] -> [bound + 1, hi] | ||
| if (pRange->UpperLimit().IsBinOpArray() && (pRange->UpperLimit().vn == boundVN) && |
There was a problem hiding this comment.
I suspect [bound, ..] assertions aren't useful generally, but it's fine to keep
| // useful than a CompareCheckedBound form -- downstream consumers (folding bounds checks, | ||
| // proving "len > 0" after a "len != 0" test) only recognize the LCLVAR form. Skip the new | ||
| // assertion in that case and let the LCLVAR path produce it. | ||
| if (!(isEqualityRelop && vnStore->IsVNConstant(op2VN))) |
There was a problem hiding this comment.
This can be omitted if AssertionDsc::CreateCompareCheckedBound becomes smarter and switches automatically from O2K_VN_ADD_CNS to O2K_INT_CONST when the vn is a constant
Follow-on to "JIT: clone i != arr.Length loops to eliminate bounds checks". The cloning change handles NE-loop BCE for loops the cloning heuristic accepts. This change extends NE-loop BCE to cases that fall outside loop cloning (e.g. loops with side-effecting calls in the body that the cloning heuristic rejects).
Extend optCreateJTrueBoundsAssertion to create CompareCheckedBound assertions for EQ/NE against a checked bound, and teach RangeCheck::MergeAssertion to tighten ranges using
X != bound/X == bound. For equality assertions where the non-bound side is a constant, defer to the existing LCLVAR-based equality assertion path to preserve downstream consumers that rely on it (e.g. provinglen > 0after alen != 0check).Contributes to #84697.