[release/10.0] JIT: fix switch peeling stealing the wrong operand of its compare - #132631
Open
EgorBo wants to merge 2 commits into
Open
[release/10.0] JIT: fix switch peeling stealing the wrong operand of its compare#132631EgorBo wants to merge 2 commits into
EgorBo wants to merge 2 commits into
Conversation
…tnet#132395) Backport of dotnet#132395. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ec11ff08-3e62-4386-a86e-51f868acffe1
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Contributor
There was a problem hiding this comment.
Pull request overview
Backports the .NET 10 JIT fix for switch peeling in fgPeelSwitch, where sequencing the newly-created compare could swap operands and cause the switch to reuse the wrong value, leading to silent wrong-code in unrolled-switch scenarios. Adds a JIT regression test to reproduce the reported issue under Tiered PGO.
Changes:
- Fix
fgPeelSwitchto reattach the switch value to the switch before creating/sequencing the compare statement, preventing operand swapping from corrupting the switch value. - Add regression test
Runtime_132370and wire it up with the needed Tiered Compilation / Tiered PGO environment variables. - Add a dedicated
.csprojfor the test per release/10.0 JitBlue conventions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/fgopt.cpp | Reorders compare construction vs statement sequencing to avoid operand swapping and incorrect switch dispatch. |
| src/tests/JIT/Regression/JitBlue/Runtime_132370/Runtime_132370.csproj | Adds a standalone JitBlue test project and enables Tiered PGO via test environment variables. |
| src/tests/JIT/Regression/JitBlue/Runtime_132370/Runtime_132370.cs | Adds a regression repro that exercises unrolled switch peeling under Tiered PGO. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
jakobbotsch
approved these changes
Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #132395 to release/10.0
Customer Impact
Reported in #132370, with a standalone 71-line repro. Silent wrong code on a default installation — no configuration or environment variables needed.
fgPeelSwitchreattached the switch value viafgMakeMultiUse(&compare->gtOp1)after the compare was put into a statement. Creating the statement sequences the tree viagtSetEvalOrder, which swaps a compare's operands when op1 is a constant, so the switch ended up "stealing" the dominant case constant instead of the switch value.The switch value is a constant when the loop around the switch is unrolled, so every unrolled copy dispatched on case 0. In the reported case a method checking whether all three components of a vector are zero returned
truefor(0, 0, 1).Fix: build the compare fully before creating the statement.
Regression
.NET 10. The reporter verified every published .NET 10 runtime is affected (all 21, from preview.1 through 10.0.11, 10/10 runs each); .NET 8 and .NET 9 are not.
Testing
Regression test
Runtime_132370from the original PR is included. The original PR reported no asm diffs (benchmarks.run, libraries.pmi).Risk
Low. Pure ordering change within
fgPeelSwitch— the compare is now fully built before it is sequenced, so the operand it hands to the switch is the intended one. No behavior change beyond that.Notes on the backport
Nearly clean;
fgopt.cppapplies verbatim. Only the test wiring differs:mainregisters the test in the merged runnersrc/tests/JIT/Regression/Regression_ro_2.csproj, which does not exist on release/10.0, so the test gets its ownRuntime_132370.csprojper this branch's JitBlue convention.