Skip to content

JIT: clear assertion input for unreachable blocks - #132898

Open
EgorBo wants to merge 5 commits into
mainfrom
egor/fix-rangecheck-stale-range
Open

JIT: clear assertion input for unreachable blocks#132898
EgorBo wants to merge 5 commits into
mainfrom
egor/fix-rangecheck-stale-range

Conversation

@EgorBo

@EgorBoEgorBo commented Aug 28, 2026

Copy link
Copy Markdown
Member

Assertion dataflow initializes every block's incoming and outgoing sets to all valid assertions, then computes the real sets only for blocks in the DFS tree. Blocks made unreachable by flow optimizations retain that initial lattice top.

RBO can leave an unreachable block in the block list with SSA definitions that range analysis still follows from reachable code. Assertion and range consumers could then read the block's uncomputed sets as if every tracked assertion held, producing an invalidly narrow range and folding the switch guard in #132879 incorrectly.

Clear bbAssertionIn, bbAssertionOut, and bbJtrueAssertionOut for blocks outside the DFS tree after assertion dataflow. This fixes the invariant at the producer and does not rely on finding contradictory assertions, so assertion-table budget overflow or unsupported assertion kinds cannot hide the problem. Reachable assertion sets and empty-range handling remain unchanged.

The reported repro now completes 500,000/500,000 calls successfully. SuperPMI replay has no failures or asserts; aggregate asmdiffs remain 0.00% for both benchmarks.run and libraries.pmi.

Fixes#132879

CopilotAI lite review requested due to automatic review settings August 28, 2026 17:40
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 28, 2026
@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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes an unsound RangeCheck range-tightening behavior where encountering contradictory assertions could leave a previously-tightened (stale) range in place, enabling incorrect assertion-prop folding in optimized JIT/crossgen2 scenarios. Adds a targeted JIT regression test for the reported miscompile involving an enum-backed switch.

Changes:

  • In RangeCheck::MergeEdgeAssertionsWorker, when tightening yields an empty range, explicitly bail out by setting *pRange to Unknown instead of leaving the prior range intact.
  • Add a new JitBlue regression test (Runtime_132879) exercising the miscompile shape under AggressiveOptimization.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/rangecheck.cppMakes contradictory assertion tightening conservative by resetting the output range to Unknown on empty intersections.
src/tests/JIT/Regression/JitBlue/Runtime_132879/Runtime_132879.csNew xUnit regression test covering the switch/enum miscompile scenario.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new regression test in the merged test project.

Comment threadsrc/coreclr/jit/rangecheck.cpp Outdated
CopilotAI review requested due to automatic review settings August 28, 2026 19:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

src/coreclr/jit/rangecheck.cpp:1686

  • assertedRange.IsValid() bail-out returns without resetting *pRange. Since assertedRange is accumulated across assertions in this loop, it can become invalid when assertions contradict each other; returning here can still leak a partially-tightened (stale) range to the caller, similar to the empty-range case fixed below. To keep range inference sound in the presence of self-contradictory assertion sets, set *pRange to Unknown before returning (same pattern as the copy.IsValid() failure path).
 JITDUMP("invalid range after tightening\n");
// The tightened range is empty, i.e. the assertions contradict the range we computed.
// If the assertion set really did hold here the block would be unreachable, but we get
// here with sets that do not hold at this point (e.g. assertions of a use block merged
// into the range of a definition that lives in another block). Returning while leaving
// the previously tightened range in place lets a fact that has just been disproven
// escape to the caller, which then folds branches with it. Bail out to Unknown instead.
*pRange = Range(Limit(Limit::keUnknown));

Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_132879/Runtime_132879.cs Outdated
CopilotAI review requested due to automatic review settings August 29, 2026 06:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Assertion dataflow initializes incoming sets to all assertions, but blocks outside the DFS tree are never visited and retain that lattice top. RBO can leave SSA definitions in those blocks reachable from range analysis, causing the uncomputed set to be treated as facts. Clear those incoming sets after dataflow so range analysis cannot consume them.
Fixes#132879
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ce554866-bacd-46ea-aac0-783dd4187ee0
@EgorBoEgorBo changed the title JIT: don't keep a stale range when assertion tightening yields an empty rangeJIT: clear assertion input for unreachable blocksSep 1, 2026
CopilotAI review requested due to automatic review settings September 1, 2026 12:21
@EgorBo
EgorBoforce-pushed the egor/fix-rangecheck-stale-range branch from 09b28ff to 92f1a5aCompareSeptember 1, 2026 12:21

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment threadsrc/coreclr/jit/assertionprop.cpp
Unreachable blocks also retain lattice-top outgoing assertion sets because dataflow never visits them. Clear both outgoing sets after dataflow so direct edge queries cannot treat the uncomputed sets as facts.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ce554866-bacd-46ea-aac0-783dd4187ee0
CopilotAI review requested due to automatic review settings September 1, 2026 12:40
CopilotAI reviewed Sep 1, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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.

Note

This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.

CopilotAI review requested due to automatic review settings September 1, 2026 14:45

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@build-analysisbuild-analysisBot mentioned this pull request Sep 1, 2026
CopilotAI review requested due to automatic review settings September 1, 2026 18:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment threadsrc/coreclr/jit/assertionprop.cpp
CopilotAI review requested due to automatic review settings September 2, 2026 20:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The change is a small, targeted correctness fix that conservatively clears assertion facts only for non-DFS (unreached-by-dataflow) blocks, with low regression risk.

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclrCLR 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.

[ReadyToRun/crossgen2] switch takes invalid default branch

2 participants

@EgorBo