Skip to content

fix: expand GT_UMOD with constant divisor in morph to enable CSE#127694

Open
mad1081 wants to merge 1 commit intodotnet:mainfrom
mad1081:main
Open

fix: expand GT_UMOD with constant divisor in morph to enable CSE#127694
mad1081 wants to merge 1 commit intodotnet:mainfrom
mad1081:main

Conversation

@mad1081
Copy link
Copy Markdown

@mad1081 mad1081 commented May 3, 2026

Fixes #119131

Related:

On XARCH, fgMorphSmpOp expands a % b into a - (a / b) * b during morph so that CSE can recognize a shared divisor between a division and a modulo with the same operands. This expansion was gated on tree->OperIs(GT_MOD), so unsigned modulo (GT_UMOD) with a non-power-of-2 constant divisor was never expanded in morph — it was
left for lowering instead. Since CSE runs before lowering, patterns like:

uint arrIndex = index / 3;
uint bitIndex = index % 3;

produced two div instructions instead of one.

fgMorphModToSubMulDiv already handles GT_UMOD correctly (it switches the operator to GT_UDIV and calls CheckDivideByConstOptimized), so the fix is to include GT_UMOD in the condition. Power-of-2 unsigned divisors are unaffected — they are already handled earlier by fgMorphUModToAndSub.

Note: ulong UMOD on XARCH is still blocked by a separate early return that predates this fix and is not addressed here.

On XARCH, the transformation of `a % b` into `a - (a / b) * b` was
only applied for signed GT_MOD, not unsigned GT_UMOD. This prevented
CSE from recognizing the shared division in patterns like `x / 3` and
`x % 3`, causing two separate div instructions to be emitted.

Extends the existing else-if condition to include GT_UMOD so unsigned
modulo with a non-power-of-2 constant divisor is also expanded during
morph, matching the behavior already present for GT_MOD.
@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 May 3, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label May 3, 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.

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 community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSE seems to fail when writing x / cns and x % cns for unsigned integers

1 participant