Skip to content

Preserve range facts for unpromoted span lengths - #136865

Open
NinoFloris wants to merge 1 commit into
dotnet:mainfrom
NinoFloris:bounds-elimination/span-length-range-facts
Open

NinoFloris wants to merge 1 commit into
dotnet:mainfrom
NinoFloris:bounds-elimination/span-length-range-facts

Conversation

@NinoFloris

@NinoFloris NinoFloris commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Promoted span-length locals are marked as nonnegative and their VNs as checked bounds. Equivalent field loads don’t receive all the same annotations, leaving redundant Slice checks when the span remains in memory or is passed implicitly by reference.

Mark recognized span-length field and indirection VNs as checked bounds, and generate nonnegative assertions for local-field loads. This lets the existing range analysis eliminate the redundant unsigned check after a signed guard.

Add coverage with struct promotion disabled, including intervening writes that must prevent elimination.

Complements recently merged changes in: #136615

@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 2, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Nov 2, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

Mark nonnegative span-length field and indirection VNs as checked bounds,
matching promoted locals. Generate nonnegative assertions for local field
loads so existing symbolic range analysis can eliminate redundant Slice
checks.

Annotate in the local-field and indirection VN handlers so unrelated nodes
do not pay for the extra test. Keep ordinary local-variable assertion
handling on its original fast path, and skip nonnegative assertion
generation during local propagation.

Recognize the loads structurally with IntegralRange::ForNode, as the
existing indirection assertion already did. The VN-based half of
GenTree::IsNeverNegative cannot succeed for these load shapes in practice
and costs a VN walk on every int-typed load, which on 32-bit targets
includes pointer-sized loads. Replaying the windows x64 libraries PMI
collection with and without CSE of address-exposed locals produced no
differences between the two forms across 331,945 contexts, while both
change the same 14 methods relative to main.

Look up the value number's function once in IsVNNeverNegative. The array
length test, the hardware intrinsic test and the function switch each
fetched it separately.

Add an unpromoted-span regression covering the signed guard and writes
that invalidate the guarded length.
@NinoFloris
NinoFloris force-pushed the bounds-elimination/span-length-range-facts branch from 5876efe to 70defdd Compare November 3, 2026 02:40

This branch has not been deployed

No deployments
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 community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant