Skip to content

Mark additional commutative xarch and arm64 intrinsics and instructions#130984

Open
tannergooding wants to merge 2 commits into
dotnet:mainfrom
tannergooding:tannergooding-ubiquitous-tribble
Open

Mark additional commutative xarch and arm64 intrinsics and instructions#130984
tannergooding wants to merge 2 commits into
dotnet:mainfrom
tannergooding:tannergooding-ubiquitous-tribble

Conversation

@tannergooding

@tannergooding tannergooding commented Jul 17, 2026

Copy link
Copy Markdown
Member

Fixes commutativity-metadata gaps found while auditing the xarch and arm64 hwintrinsic/instruction tables.

xarch

AVX2 and AVX512 MultiplyAddAdjacent use the same instructions as the X86Base variant (pmaddubsw/pmaddwd) but were missing HW_Flag_MaybeCommutative. isCommutativeHWIntrinsic only special-cased NI_X86Base_MultiplyAddAdjacent, so the pmaddwd form of the AVX2/AVX512 intrinsics lost the operand-swap-for-containment opportunity the SSE path already gets. This adds the flag to both rows and the matching switch cases. The pmaddubsw form (base type short) correctly stays non-commutative since its operands are asymmetric (unsigned x signed); only the pmaddwd form (base type int) becomes commutative, matching the existing !varTypeIsShort(...) condition.


Several SSE4.1/SSSE3 integer instructions that are commutative were not marked INS_Flags_IsAvxCommutative, unlike their SSE2 siblings (pmaxsw, pminsw, pmuludq, etc.). This marks pcmpeqq, pmuldq, pmulld, pmaxsb, pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw, and pmulhrsw. These are all SSE38/SSE3A-encoded, so the emitter always forces a 3-byte VEX prefix and the emitIns_SIMD_R_R_R operand swap can't drop to the 2-byte form -- i.e. it's a no-op for code size here. Kept anyway for consistency with the SSE2 siblings: the flag correctly describes the instruction and avoids these rows looking like they're missing it. If the swap heuristic is ever tightened to skip SSE38/SSE3A, that's a single localized change.

arm64

AdvSimd_Arm64.AbsoluteDifference (fabd, double) and AbsoluteDifferenceScalar (fabd, float/double scalar) were missing HW_Flag_Commutative, even though the float32 AdvSimd.AbsoluteDifference sibling -- the same fabd instruction -- already carries it. fabd computes |a-b|, which is commutative and NaN/signed-zero safe. This enables constant-to-op2 reordering in morph and CSE canonicalization, matching the sibling.

The SVE commutativity gap (no Sve/Sve2 op carries HW_Flag_Commutative) is left out of scope -- those forms are predicated/RMW/embedded-mask and need separate investigation rather than a metadata one-liner.

Validation

  • clr+libs -rc checked baseline build succeeded; JIT rebuilt with 0 warnings / 0 errors. The arm64 altjit (clrjit_universal_arm64_x64) also builds clean, compiling the arm64 table change.
  • Ran a correctness test exercising the affected xarch intrinsics with commuted operand orders (128- and 256-bit) under the checked JIT: all cases pass with no assertion failures. The arm64 change relies on parity with the already-commutative float32 sibling; runtime behavior is covered by CI on arm64.
  • jitformat.py -r . -o windows -a x64 reports no formatting changes.

Note

This PR was authored by GitHub Copilot.

AVX2 and AVX512 MultiplyAddAdjacent used the same instructions as the
X86Base variant (pmaddubsw/pmaddwd) but were missing HW_Flag_MaybeCommutative,
so the pmaddwd form lost the operand-swap-for-containment the SSE path gets.
Add the flag and the matching isCommutativeHWIntrinsic cases; pmaddubsw stays
non-commutative since its operands are asymmetric (unsigned x signed).

Several SSE4.1/SSSE3 integer instructions that are commutative were also not
marked INS_Flags_IsAvxCommutative, unlike their SSE2 siblings. Mark pcmpeqq,
pmuldq, pmulld, pmaxsb/sd/ud/uw, pminsb/sd/ud/uw, and pmulhrsw so the emitter
can swap op1/op2 to enable the shorter 2-byte VEX prefix when op2 is an
extended register.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 17, 2026 17:36
@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 Jul 17, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 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 commutativity metadata in the JIT so operand swapping can be applied more consistently for containment / encoding decisions.

Changes:

  • Marks AVX2 and AVX512 MultiplyAddAdjacent as HW_Flag_MaybeCommutative in hwintrinsiclistxarch.h.
  • Extends GenTree::isCommutativeHWIntrinsic to treat NI_AVX2_MultiplyAddAdjacent and NI_AVX512_MultiplyAddAdjacent as conditionally commutative (non-short base types).
  • Marks additional xarch SIMD instructions as INS_Flags_IsAvxCommutative in instrsxarch.h.
Show a summary per file
File Description
src/coreclr/jit/instrsxarch.h Adds INS_Flags_IsAvxCommutative to more VEX/EVEX instructions.
src/coreclr/jit/hwintrinsiclistxarch.h Marks AVX2/AVX512 MultiplyAddAdjacent as maybe-commutative.
src/coreclr/jit/gentree.cpp Adds commutativity switch-cases for AVX2/AVX512 MultiplyAddAdjacent.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 1

Comment thread src/coreclr/jit/instrsxarch.h
The double and scalar fabd forms compute |a-b|, which is commutative and
NaN/signed-zero safe, matching the float32 AdvSimd.AbsoluteDifference sibling
that already carries the flag.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 17, 2026 22:35
@tannergooding tannergooding changed the title Mark additional commutative xarch intrinsics and instructions Mark additional commutative xarch and arm64 intrinsics and instructions Jul 17, 2026

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.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 1

Comment thread src/coreclr/jit/instrsxarch.h
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