Skip to content

RangeCheck: Don't create invalid ranges #113935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 13, 2025
Merged

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Mar 26, 2025

Fixes a bug @amanasifkhalid hit in #113709

It is possible to create ranges where their lower limit is greater than the upper in MergeEdgeAssertions. E.g.

if (i > 10 && i < 5)
{
    arr[i] = 0; // never reachable in fact.
}

Some of our range operations (RangeOps::Merge specifically) do invalid operations on such ranges, so instead of fixing such places, I propose we don't create them in the first place (give up on them).

Normally, this should not cause issues as such array accesses likely will never be accessible anyway, but we now use range analysis in assertprop

@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 26, 2025
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@EgorBo
Copy link
Member Author

EgorBo commented Mar 27, 2025

/azp list

This comment was marked as resolved.

@EgorBo
Copy link
Member Author

EgorBo commented Mar 27, 2025

/azp run runtime-coreclr outerloop, runtime-coreclr jitstress, runtime-coreclr pgo, runtime-coreclr libraries-pgo, runtime-coreclr pgostress

Copy link

Azure Pipelines successfully started running 5 pipeline(s).

Copy link
Contributor

Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it.

@github-actions github-actions bot locked and limited conversation to collaborators May 27, 2025
@EgorBo EgorBo reopened this Jun 6, 2025
@EgorBo EgorBo marked this pull request as ready for review June 9, 2025 12:20
@Copilot Copilot AI review requested due to automatic review settings June 9, 2025 12:20
@EgorBo
Copy link
Member Author

EgorBo commented Jun 9, 2025

@dotnet/jit-contrib @amanasifkhalid PTAL

In theory, invalid ranges are fine to have e.g.:

if (i > 10 && i < 5)
{
    arr[i] = 0; // never reachable in fact.
}

and we still may extract useful info from that, but looks like many existing Range operations do not expect them so it's safer to just give up on them. They used to be not a problem when we used Range only for bounds checks, but we now use it for actual transformations in AssertProp as well.

@dotnet dotnet unlocked this conversation Jun 9, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@am11
Copy link
Member

am11 commented Jun 9, 2025

Were we expecting regressions? e.g. linux arm64 seeing +1.22% in

private static void InsertionSort(Span<T> keys, Comparison<T> comparer)

@tannergooding
Copy link
Member

In theory, invalid ranges are fine to have e.g.:

Are we currently dead code eliminating these cases?

@amanasifkhalid
Copy link
Member

@EgorBo have you had a chance to look at the insertion sort regression?

@EgorBo
Copy link
Member Author

EgorBo commented Jun 12, 2025

Sorry for the delayed response.

Are we currently dead code eliminating these cases?

RangeCheck uses a powerful and slow "Assertions + SSA-based analysis" mechanism and we don't use the same thing to fold unreachable branches. We re-use a limited form of it in the Global Assertion prop, but we don't use SSA-based analysis there because it's too slow (adds >1% TP regression), we only use assertions.

Were we expecting regressions?

I've looked at those and while they look unfortunate (just a few functions), JIT had no right to optimize them based on what it analyzed: https://www.diffchecker.com/53WlCbZL/
e.g.

Tightening pRange: [<Dependent, -1>] with assertedRange: [<0, -1>] into [<0, -1>]

private static void InsertionSort(Span<TKey> keys, Span<TValue> values)
{
for (int i = 0; i < keys.Length - 1; i++)
{
TKey t = keys[i + 1];
TValue tValue = values[i + 1];
int j = i;
while (j >= 0 && (t == null || LessThan(ref t, ref keys[j])))
{
keys[j + 1] = keys[j];
values[j + 1] = values[j];
j--;
}
keys[j + 1] = t!;
values[j + 1] = tValue;
}
}

This is just too complex flow for current jit's BCE to properly analyze it.

Given that this PR unlocks @amanasifkhalid PR and fixes access violation in #116571 I think we should just accept it.

I might still allow these functions to report "invalid" ranges like this, but at the moment I think various RangeOps:: simply don't expect them and produce invalid results.

Also, for e.g. [10..-10] assertprop might assume that the value is never negative since the lower bound is > 0.

Copy link
Member

@amanasifkhalid amanasifkhalid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. CI is in pretty rough shape, so we might want to wait for the next run before merging. Thanks!

@EgorBo EgorBo merged commit a1eb855 into dotnet:main Jun 13, 2025
109 checks passed
@EgorBo EgorBo deleted the fix-invalid-ranges branch June 13, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants