Skip to content

[RISC-V] Use fine-grained fence variants for memory barriers#126566

Merged
jakobbotsch merged 2 commits intodotnet:mainfrom
JamieMagee:dev/riscv64-fine-grained-barriers
Apr 17, 2026
Merged

[RISC-V] Use fine-grained fence variants for memory barriers#126566
jakobbotsch merged 2 commits intodotnet:mainfrom
JamieMagee:dev/riscv64-fine-grained-barriers

Conversation

@JamieMagee
Copy link
Copy Markdown
Member

@JamieMagee JamieMagee commented Apr 6, 2026

instGen_MemoryBarrier on RISC-V ignored the barrierKind parameter and always emitted fence rw,rw. The RISC-V fence instruction has per-bit control over predecessor and successor ordering (read, write, or both), so there's no reason to always use the heaviest option.

This maps BarrierKind to the matching fence variant:

BarrierKind Before After
BARRIER_FULL fence rw,rw fence rw,rw (unchanged)
BARRIER_LOAD_ONLY fence rw,rw fence r,rw (acquire)
BARRIER_STORE_ONLY fence rw,rw fence rw,w (release)

ARM64 does the same thing with DMB ISHLD for load-only and DMB ISH for full. The load/store variants use acquire/release semantics rather than just load-load or store-store ordering, since .NET's volatile semantics require it.

The two call sites that benefit today are GT_MEMORYBARRIER with GTF_MEMORYBARRIER_LOAD/GTF_MEMORYBARRIER_STORE flags, and the post-volatile-CpBlk load barrier.

Validated the encoding on QEMU (fence rw,rw = 0x0330000f, fence r,rw = 0x0230000f, fence rw,w = 0x0310000f).

Copilot AI review requested due to automatic review settings April 6, 2026 03:21
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Apr 6, 2026
@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 Apr 6, 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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 improves RISC-V64 JIT codegen for memory barriers by honoring BarrierKind and emitting a more specific fence variant instead of always using the heaviest fence rw,rw.

Changes:

  • Extends RISC-V64 insBarrier immediates to represent multiple fence predecessor/successor masks.
  • Updates CodeGen::instGen_MemoryBarrier (RISC-V64) to select the fence immediate based on BarrierKind.
  • Cleans up outdated comments that claimed only full barriers were supported.
Show a summary per file
File Description
src/coreclr/jit/instr.h Adds additional RISC-V64 insBarrier values intended to represent different fence masks.
src/coreclr/jit/codegenriscv64.cpp Uses BarrierKind to pick an insBarrier immediate when emitting INS_fence.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread src/coreclr/jit/instr.h Outdated
Comment thread src/coreclr/jit/codegenriscv64.cpp
The JIT always emitted fence rw,rw (full barrier) regardless of the
requested BarrierKind. RISC-V's fence instruction supports finer
predecessor/successor bits, so use them:

- BARRIER_FULL       -> fence rw,rw (0x33) - unchanged
- BARRIER_LOAD_ONLY  -> fence r,rw  (0x23) - acquire semantics
- BARRIER_STORE_ONLY -> fence rw,w  (0x31) - release semantics

Same idea as ARM64, which uses DMB ISHLD for load-only and DMB ISH
for full. Volatile reads and post-CpBlk barriers were paying for a
full fence when a lighter one is sufficient under RVWMO.
@JamieMagee JamieMagee force-pushed the dev/riscv64-fine-grained-barriers branch from 9414867 to 398c025 Compare April 6, 2026 03:36
@JamieMagee JamieMagee requested a review from Copilot April 6, 2026 03:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 refines RISC-V64 JIT memory barrier emission so instGen_MemoryBarrier(BarrierKind) uses the appropriate fence predecessor/successor mask instead of always emitting the heaviest fence rw,rw, aligning barrier strength with .NET volatile semantics.

Changes:

  • Add RISC-V-specific insBarrier encodings for full, load-only (acquire), and store-only (release) fences.
  • Update CodeGen::instGen_MemoryBarrier on RISC-V64 to select the correct fence variant based on BarrierKind.
  • Remove an outdated TODO that stated only full barriers were supported on RISC-V64.
Show a summary per file
File Description
src/coreclr/jit/instr.h Defines RISC-V64 fence immediate values for full/load-only/store-only barrier variants.
src/coreclr/jit/codegenriscv64.cpp Maps BarrierKind to the corresponding RISC-V64 fence variant during codegen.

Copilot's findings

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

Comment thread src/coreclr/jit/codegenriscv64.cpp
@jkotas jkotas added the arch-riscv Related to the RISC-V architecture label Apr 6, 2026
@am11 am11 requested a review from a team April 6, 2026 09:11
Copy link
Copy Markdown
Member

@tomeksowi tomeksowi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@jakobbotsch jakobbotsch merged commit a9b4274 into dotnet:main Apr 17, 2026
134 of 137 checks passed
@JamieMagee JamieMagee deleted the dev/riscv64-fine-grained-barriers branch April 17, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-riscv Related to the RISC-V architecture 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.

5 participants