[release/10.0] JIT: fix switch peeling stealing the wrong operand of its compare - #132631
Merged
JulieLeeMSFT merged 2 commits intoSep 1, 2026
Merged
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
AmauryTISSOT
added a commit
to AmauryTISSOT/microservice_rgpd
that referenced
this pull request
Sep 11, 2026
… (#342) Cause : un bug du JIT .NET 10 (dotnet/runtime#132370, symptôme dotnet/razor#13184). Une fois une partie du parseur Razor passée en Tier1 avec PGO, le JIT la recompile mal. Seul le VBCSCompiler persistant vit assez longtemps pour y arriver ; il lit alors le « < » d'un balisage dans un bloc de code comme du C#, lève RZ1021/RZ1000/RZ1026/RZ1009/RZ1034 sur des .cshtml valides, et recommence à chaque build jusqu'à son arrêt. L'hypothèse de l'issue (builds concurrents sous deux SDK) est réfutée : - le build 10.0.400 passe par un autre VBCSCompiler ; il n'agit que comme charge CPU ; - une charge CPU pure suffit à déclencher (rouge au 5e build) ; - 10.0.400 est touché aussi (11/15 builds rouges sous charge) : épingler le SDK ne corrige rien ; - arrêter le seul VBCSCompiler 10.0.401 suffit à revenir au vert. Correctif : UseSharedCompilation=false sur MicroserviceRgpd.Web, le seul projet Razor. Sous charge : 0/15 build rouge. Face à un serveur déjà empoisonné, le projet corrigé reste vert quand le témoin non corrigé échoue. Coût : environ 3 s de plus par recompilation du projet Web. À retirer quand le SDK retenu embarquera un runtime contenant dotnet/runtime#132631 (fusionné dans release/10.0 le 2026-09-01, absent de 10.0.12).
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.