Skip to content

[release/10.0] JIT: fix switch peeling stealing the wrong operand of its compare - #132631

Merged
JulieLeeMSFT merged 2 commits into
dotnet:release/10.0from
EgorBo:backport/pr-132395-to-release/10.0
Sep 1, 2026
Merged

JulieLeeMSFT merged 2 commits into
dotnet:release/10.0from
EgorBo:backport/pr-132395-to-release/10.0

Conversation

@EgorBo

@EgorBo EgorBo commented Aug 21, 2026

Copy link
Copy Markdown
Member

Backport of #132395 to release/10.0

Customer Impact

  • Customer reported
  • Found internally

Reported in #132370, with a standalone 71-line repro. Silent wrong code on a default installation — no configuration or environment variables needed.

fgPeelSwitch reattached the switch value via fgMakeMultiUse(&compare->gtOp1) after the compare was put into a statement. Creating the statement sequences the tree via gtSetEvalOrder, 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 true for (0, 0, 1).

Fix: build the compare fully before creating the statement.

Regression

  • Yes
  • No

.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_132370 from 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.cpp applies verbatim. Only the test wiring differs: main registers the test in the merged runner src/tests/JIT/Regression/Regression_ro_2.csproj, which does not exist on release/10.0, so the test gets its own Runtime_132370.csproj per this branch's JitBlue convention.

…tnet#132395)

Backport of dotnet#132395.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ec11ff08-3e62-4386-a86e-51f868acffe1
Copilot AI lite review requested due to automatic review settings August 21, 2026 15:43
@EgorBo EgorBo added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 21, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

@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.

Copilot AI 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

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 fgPeelSwitch to 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_132370 and wire it up with the needed Tiered Compilation / Tiered PGO environment variables.
  • Add a dedicated .csproj for 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.

Comment thread src/tests/JIT/Regression/JitBlue/Runtime_132370/Runtime_132370.cs
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 21, 2026 15:56

Copilot AI 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 no new comments.

@JulieLeeMSFT JulieLeeMSFT added the Servicing-consider Issue for next servicing release review label Aug 28, 2026
@JulieLeeMSFT JulieLeeMSFT added this to the 10.0.x milestone Aug 28, 2026
@rbhanda rbhanda added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Sep 1, 2026
@rbhanda rbhanda modified the milestones: 10.0.x, 10.0.13 Sep 1, 2026
@JulieLeeMSFT
JulieLeeMSFT merged commit 66037f1 into dotnet:release/10.0 Sep 1, 2026
122 of 124 checks passed
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).
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 Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants