Skip to content

JIT: ensure magic divisors are always marked DONT_CSE for all targets#129856

Open
AndyAyersMS wants to merge 2 commits into
dotnet:mainfrom
AndyAyersMS:andyayersms/signed-div-dont-cse
Open

JIT: ensure magic divisors are always marked DONT_CSE for all targets#129856
AndyAyersMS wants to merge 2 commits into
dotnet:mainfrom
AndyAyersMS:andyayersms/signed-div-dont-cse

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

fgMorphSmpOpOptional calls CheckDivideByConstOptimized for GT_UDIV/GT_UMOD but the corresponding case GT_DIV: arm only checks for val / 1 and breaks. Signed integer divides with a constant divisor reach lowering without GTF_DONT_CSE on the divisor.

Magic-divide expansion in LowerSignedDivOrMod -> TryLowerConstIntDivOrMod bails at if (!divisor->IsCnsIntOrI()) return false; and falls back to idiv if CSE has rewritten the divisor to a LCL_VAR.

This is latent on x64 because the default JitConstCSE setting disables most integer-constant CSE there, so a full SPMI sweep on x64 shows zero asm diffs. It is observable on ARM64/RISC-V where constant CSE is enabled, and would also surface immediately on x64 if JitConstCSE is ever broadened.

Signed GT_MOD is already covered: fgMorphModToSubMulDiv transforms a % b into a - (a / b) * b and calls CheckDivideByConstOptimized on the inner DIV.

Note

This PR description was drafted with the assistance of GitHub Copilot.

fgMorphSmpOpOptional was calling CheckDivideByConstOptimized for
GT_UDIV/GT_UMOD but not for signed GT_DIV, leaving the constant
divisor unmarked. If CSE later rewrites it to a LCL_VAR, magic-divide
expansion in LowerSignedDivOrMod bails and falls back to idiv.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 25, 2026 14:55
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 25, 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.

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

This PR updates JIT morphing so GT_DIV nodes also call CheckDivideByConstOptimized, matching existing handling for GT_UDIV/GT_UMOD. The intent is to keep eligible constant divisors from being constant-CSE’d into locals so later lowering can still recognize and apply “magic divide” transformations.

Changes:

  • In fgMorphSmpOpOptional, call CheckDivideByConstOptimized for GT_DIV after the existing val / 1 fast-path.

Comment thread src/coreclr/jit/morph.cpp
…isors

Lowering's TryLowerConstIntDivOrMod generates magic-divide for any
non-pow2 signed divisor with |d| >= 3 and a shift+neg sequence for
negative pow2 divisors. Mirror that here so the corresponding DONT_CSE
marker is set on the divisor constant.

Addresses review feedback on dotnet#129856.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AndyAyersMS

Copy link
Copy Markdown
Member Author

Good catch. Pushed f11b2fa which extends UsesDivideByConstOptimized to accept negative magic divisors (|d| >= 3) and negative pow2 divisors, mirroring what TryLowerConstIntDivOrMod actually lowers.

Verified on the original repro (System.TimeOnly.AddTicks already uses positive divisors so unchanged), and a quick standalone test with x / -3, x / -2, x % -3 confirms the expected magic-divide / shift+neg sequences are emitted with no idiv fallback. Full x64 SPMI sweep still shows zero asm diffs (constant CSE is off by default there), as expected.

Note

Comment drafted with the assistance of GitHub Copilot.

@AndyAyersMS

Copy link
Copy Markdown
Member Author

@EgorBo PTAL
fyi @dotnet/jit-contrib

future-proofing so we can look into enabling const CSE for more platforms. Should be no diff.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants