Uh oh!
There was an error while loading. Please reload this page.
JIT: Convert multi-target switches to branchless checks - #124567
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
JulieLeeMSFT
commented
Feb 18, 2026
@EgorBo, PTAL. |
There was a problem hiding this comment.
Pull request overview
This PR optimizes multi-target switches where all non-default cases target a single block (distinct from the default target) by converting them into unsigned range comparisons. This enables branchless code generation when both targets are simple return blocks, addressing the disparity between pattern matching and explicit equality comparisons noted in issue #123858.
Changes:
- Adds logic in
fgOptimizeSwitchBranchesto detect and optimize switches with exactly 2 unique successors - Transforms such switches into unsigned LE/GT comparisons, choosing the direction to favor fall-through
- Adds comprehensive test coverage for both zero-based and non-zero-based consecutive ranges
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/fgopt.cpp | Implements the switch-to-range-check optimization with edge weight/dup count fixup and profile weight updates |
| src/tests/JIT/opt/OptSwitchRecognition/optSwitchRecognition.cs | Adds tests for zero-based (0-4) and non-zero-based (10-14) consecutive value ranges with comprehensive boundary cases |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
2b0a347 to
8eae723CompareJulieLeeMSFT
commented
Feb 20, 2026
@EgorBo, I addressed all comments. It's ready to review. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Egor Bogatov <egorbo@gmail.com>
Co-authored-by: Egor Bogatov <egorbo@gmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
JulieLeeMSFT
commented
Feb 24, 2026
/ba-g Failures are timeouts in Android pipeline. Not related to this PR. |
Uh oh!
There was an error while loading. Please reload this page.
Fixesdotnet#123858. This PR improves JIT codegen for multi-target `switch`-style tests by converting eligible cases into branchless checks. The goal is to produce optimal codegen that matches the intent of C# pattern matching with `or` (e.g., `x is A or B or C`). When a switch has exactly 2 unique successors (all non-default cases target one block, default targets another), convert it from Switch to an unsigned range comparison (In `fgOptimizeSwitchBranches`). When both targets are simple return blocks, `fgFoldCondToReturnBlock` further folds this into branchless return. ## Example ```csharp private static bool IsLetterCategory(UnicodeCategory uc) { return uc == UnicodeCategory.UppercaseLetter || uc == UnicodeCategory.LowercaseLetter || uc == UnicodeCategory.TitlecaseLetter || uc == UnicodeCategory.ModifierLetter || uc == UnicodeCategory.OtherLetter; } ``` ## Before ```asm cmp ecx, 4 ja SHORT G_M22758_IG05 mov eax, 1 ret G_M22758_IG05: xor eax, eax ret ``` ## After ```asm cmp ecx, 4 setbe al movzx rax, al ret ``` ## Details - The comparison direction is chosen to GT_LT. - Edge dup counts are fixed up after conversion. - Added tests for zero-based and non-zero-based consecutive ranges. ## ASMDiffs - SPMI asmdiffs show code size improvements of 83 bytes. --------- Co-authored-by: Egor Bogatov <egorbo@gmail.com>
Fixes#123858.
This PR improves JIT codegen for multi-target
switch-style tests by converting eligible cases into branchless checks. The goal is to produce optimal codegen that matches the intent of C# pattern matching withor(e.g.,x is A or B or C).When a switch has exactly 2 unique successors (all non-default cases target one block, default targets another), convert it from Switch to an unsigned range comparison (In
fgOptimizeSwitchBranches).When both targets are simple return blocks,
fgFoldCondToReturnBlockfurther folds this into branchless return.Example
Before
After
Details
ASMDiffs