Skip to content

JIT: preference the operand of unary RMW nodes to the target reg on xarch - #132102

Closed
EgorBo wants to merge 3 commits into
dotnet:mainfrom
EgorBo:unary-rmw-tgtpref
Closed

EgorBo wants to merge 3 commits into
dotnet:mainfrom
EgorBo:unary-rmw-tgtpref

Conversation

@EgorBo

@EgorBo EgorBo commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

neg/not/bswap are two-address on xarch, but only binary nodes go through isRMWRegOper/getTgtPrefOperands, so LSRA never preferenced the operand of GT_NEG/GT_NOT/GT_BSWAP/GT_BSWAP16 to the destination and codegen had to emit a mov ahead of the instruction. Shifts already did this.

No delayRegFree is needed since there is no second operand that could be assigned the target register.

…arch

neg/not/bswap are two-address on x86, but only binary nodes went through
isRMWRegOper/getTgtPrefOperands, so LSRA never preferenced the operand of
GT_NEG/GT_NOT/GT_BSWAP/GT_BSWAP16 to the destination and codegen had to
emit a mov ahead of the instruction.

No delayRegFree is needed here since there is no second operand that could
be assigned the target register.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6be3190f-5600-40ef-b306-56b5aac40070
Copilot AI lite review requested due to automatic review settings August 11, 2026 01:12
@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 Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 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

This PR updates xarch LSRA’s operand preferencing so unary read-modify-write nodes (GT_NEG, GT_NOT, GT_BSWAP, GT_BSWAP16) preference their operand to the target register, allowing codegen to elide a pre-instruction mov in more cases.

Changes:

  • Switch unary op handling in LinearScan::BuildNode to use a new BuildUnaryRMWUses helper for RMW-form unary instructions.
  • Add LinearScan::BuildUnaryRMWUses to set tgtPrefUse for non-contained operands (mirroring the binary RMW preferencing behavior, without delayRegFree).
  • Declare the new helper in lsra.h under TARGET_XARCH.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/coreclr/jit/lsraxarch.cpp Prefer operand-to-dest for unary RMW nodes via new BuildUnaryRMWUses helper and extend handling to GT_BSWAP/GT_BSWAP16.
src/coreclr/jit/lsra.h Add BuildUnaryRMWUses declaration for xarch LSRA build logic.

Comment thread src/coreclr/jit/lsra.h
Comment thread src/coreclr/jit/lsraxarch.cpp
@EgorBo
EgorBo marked this pull request as ready for review September 1, 2026 12:12
Copilot AI review requested due to automatic review settings September 1, 2026 12:12
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +437 to 443
case GT_BSWAP:
case GT_BSWAP16:
// These are "bswap reg" / "ror reg.16, 8", which are RMW, unless the
// operand is contained, in which case we generate a "movbe reg, [mem]".
srcCount = BuildUnaryRMWUses(tree->gtGetOp1());
BuildDef(tree);
break;
Copilot AI review requested due to automatic review settings September 2, 2026 00:30

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.

🟢 Approval recommended

The change is small, xarch-scoped, and aligns LSRA operand preferencing with the two-address requirements of the affected unary instructions.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +843 to +846
// Unlike the binary case handled by BuildRMWUses, there is no second operand that
// could be assigned the target register, so no `delayRegFree` is needed here; we
// only preference the operand to the target so that codegen can elide the "mov"
// that emitIns_BASE_R_R() would otherwise emit ahead of the instruction.
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.

3 participants