Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_target: Add more RISC-V atomic-related features #137417

Merged
merged 1 commit into from
Feb 25, 2025

Conversation

taiki-e
Copy link
Member

@taiki-e taiki-e commented Feb 22, 2025

This is a continuation of #130877 and adds a few target features, including zacas, which was experimental in LLVM 19 and marked non-experimental in LLVM 20.

This adds the following target features to unstable riscv_target_feature:

Btw, the question of whether zaamo is implied by zabha or not, which was discussed in #130877, has been resolved in LLVM 20, since LLVM now treats zaamo as implied by zabha/zacas (llvm/llvm-project#115694), just like GCC and rustc.

r? @Amanieu

@rustbot label +O-riscv +A-target-feature

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. O-riscv Target: RISC-V architecture labels Feb 22, 2025
@Amanieu
Copy link
Member

Amanieu commented Feb 24, 2025

@bors r+

@bors
Copy link
Contributor

bors commented Feb 24, 2025

📌 Commit a343dcb has been approved by Amanieu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 24, 2025
@RalfJung
Copy link
Member

Do any of these have ABI concerns? In particular, if I mix code built with and without those features, and those two parts of the program share some memory and use atomics to work on that, will everything still behave correctly? Or do some of these features change the way LLVM lowers atomic operations in such a way that it is no longer compatible with code built without the extension?

@taiki-e
Copy link
Member Author

taiki-e commented Feb 24, 2025

As far as I know, there are none at this time.

As of the past:

  • Zacas had a problem that it was incompatible with the atomic instruction mappings used in earlier LLVMs, and because of this problem it was marked as an experimental feature in LLVM 19 and older, but this has been resolved by adding fences when necessary in LLVM 20 (llvm/llvm-project@614aeda).

  • As mentioned in the PR description, if LLVM automatically use Zacas instruction for 64-bit/128-bit atomics on riscv32/riscv64 when Zacas is enabled, it will cause ABI incompatibility because it is not compatible with the existing fallback-based atomics that provided via atomic builtins. However, they are aware of this issue and have stated that they will not do this.

As for others:

  • Zawrs adds an instruction to wait for a memory location to be updated, but this is not used in the atomic operation itself and is therefore not relevant for atomic ABI.
  • Zama16b relaxes the alignment requirement of atomicity of existing instructions used in atomic operations a bit. Code built for more restrictive existing (i.e., no Zama16b) environments will work fine even with zama16b enabled.
  • I guess Za64rs and Za128rs may affect the size of C++ hardware_destructive_interference_size (although not a cache-related feature), but neither LLVM nor GCC guarantee stability on the size of hardware_destructive_interference_size in the first place, stating that it may be changed by CPU tuning flags.

@RalfJung
Copy link
Member

RalfJung commented Feb 24, 2025 via email

@beetrees
Copy link
Contributor

<llvm/llvm-project#101023> sounds like LLVM did change the ABI at some point, so mixing Rust (or C) code built with different versions of LLVM can cause UB. Amazing. But that seems to not depend on target features so it has no bearing on this PR.

AFAICT this shouldn't be an issue, as by default LLVM currently uses the A6S atomic ABI that is compatible with both other ABIs. RISC-V ELF files can be tagged with which atomic ABI is in use, and the linker will issue an error if incompatible objects are linked together. LLVM will emit Tag_RISCV_atomic_abi if the --riscv-abi-attributes argument is passed to LLVM (it is disabled by default due to segfaults in ld.bfd).

@compiler-errors
Copy link
Member

@bors rollup

bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 25, 2025
…mpiler-errors

Rollup of 11 pull requests

Successful merges:

 - rust-lang#136522 (Remove `feature(dyn_compatible_for_dispatch)` from the compiler)
 - rust-lang#137289 (Consolidate and improve error messaging for `CoerceUnsized` and `DispatchFromDyn`)
 - rust-lang#137321 (Correct doc about `temp_dir()` behavior on Android)
 - rust-lang#137417 (rustc_target: Add more RISC-V atomic-related features)
 - rust-lang#137489 (remove `#[rustc_intrinsic_must_be_overridde]`)
 - rust-lang#137530 (DWARF mixed versions with LTO on MIPS)
 - rust-lang#137543 (std: Fix another new symlink test on Windows)
 - rust-lang#137548 (Pass correct `TypingEnv` to `InlineAsmCtxt`)
 - rust-lang#137550 (Don't immediately panic if dropck fails without returning errors)
 - rust-lang#137552 (Update books)
 - rust-lang#137556 (rename simd_shuffle_generic → simd_shuffle_const_generic)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 828a3a4 into rust-lang:master Feb 25, 2025
6 checks passed
@rustbot rustbot added this to the 1.87.0 milestone Feb 25, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Feb 25, 2025
Rollup merge of rust-lang#137417 - taiki-e:riscv-atomic, r=Amanieu

rustc_target: Add more RISC-V atomic-related features

This is a continuation of rust-lang#130877 and adds a few target features, including `zacas`, which was experimental in LLVM 19 and marked non-experimental in LLVM 20.

This adds the following target features to unstable riscv_target_feature:

- `za64rs` (Za64rs Extension 1.0): Reservation Set Size of at Most 64 Bytes
  ([definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0-rc2/llvm/lib/Target/RISCV/RISCVFeatures.td#L227-L228), [available since LLVM 18](llvm/llvm-project@8649328))
- `za128rs` (Za128rs Extension 1.0): Reservation Set Size of at Most 128 Bytes
  ([definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0-rc2/llvm/lib/Target/RISCV/RISCVFeatures.td#L230-L231), [available since LLVM 18](llvm/llvm-project@8649328))
  - IIUC, `za*rs` can be referenced when implementing helpers to reduce contention in synchronization primitives, like [`crossbeam_utils::CachePadded`](https://docs.rs/crossbeam-utils/latest/crossbeam_utils/struct.CachePadded.html). (relevant discussion: riscv/riscv-profiles#79)
- `zacas` (Zacas Extension 1.0): Atomic Compare-And-Swap Instructions (`amocas.{w,d,q}{,.aq,.rl,.aqrl}` and `amocas.{b,h}{,.aq,.rl,.aqrl}` when `zabha` is also enabled)
  ([definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0-rc2/llvm/lib/Target/RISCV/RISCVFeatures.td#L240-L243), [available as non-experimental since LLVM 20](llvm/llvm-project@614aeda))
  - This implies `zaamo`.
  - This is used to optimize CAS in existing atomics and/or implement 64-bit/128-bit atomics on riscv32/riscv64 (e.g., taiki-e/portable-atomic#173).
  - Note that [LLVM does not automatically use this instruction for 64-bit/128-bit atomics on riscv32/riscv64 even if this feature is enabled, because doing it changes the ABI](https://github.com/llvm/llvm-project/blob/876174ffd7533dc220f94721173bb767b659fa7f/llvm/docs/RISCVUsage.rst#riscv-zacas-note). (If the ability to do that is provided by LLVM in the future, it should probably be controlled by another ABI feature similar to `forced-atomics`.)
- `zama16b` (Zama16b Extension 1.0): Atomic 16-byte misaligned loads, stores and AMOs
  ([definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0-rc2/llvm/lib/Target/RISCV/RISCVFeatures.td#L255-L256), [available since LLVM 19](llvm/llvm-project@b090569))
  - IIUC, unlike AArch64 FEAT_LSE2 which also makes 16-byte aligned ldp ({i,u}128 load) atomic, this extension only affects instructions that already considered atomic if they were naturally aligned. i.e., fld (f64 load) on riscv32 would not be atomic with or without this extension ([relevant QEMU code](https://github.com/qemu/qemu/blob/b69801dd6b1eb4d107f7c2f643adf0a4e3ec9124/target/riscv/insn_trans/trans_rvd.c.inc#L50-L62)).
- `zawrs` (Zawrs Extension 1.0): Wait on Reservation Set (`wrs.nto` and `wrs.sto`)
  ([definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0-rc2/llvm/lib/Target/RISCV/RISCVFeatures.td#L258), [available as non-experimental since LLVM 17](llvm/llvm-project@d41a73a))
  - This is used to optimize synchronization primitives (e.g., Linux uses this for spinlocks (torvalds/linux@b8ddb0d)).

Btw, the question of whether `zaamo` is implied by `zabha` or not, which was discussed in rust-lang#130877, has been resolved in LLVM 20, since LLVM now treats `zaamo` as implied by `zabha`/`zacas` (llvm/llvm-project#115694), just like GCC and rustc.

r? `@Amanieu`

`@rustbot` label +O-riscv +A-target-feature
@taiki-e taiki-e deleted the riscv-atomic branch February 25, 2025 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. O-riscv Target: RISC-V architecture S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants