Skip to content

enable 128-bit atomics on x86_64#154139

Draft
usamoi wants to merge 1 commit intorust-lang:mainfrom
usamoi:atomic-128
Draft

enable 128-bit atomics on x86_64#154139
usamoi wants to merge 1 commit intorust-lang:mainfrom
usamoi:atomic-128

Conversation

@usamoi
Copy link
Contributor

@usamoi usamoi commented Mar 20, 2026

tracking issue: #99069

This API is inconvenient to use. Because one can't just write

// -Ctarget-feature=+cmpxchg16b
pub fn f(atomic: &core::sync::atomic::AtomicI128) -> i128 {
    atomic.load(core::sync::atomic::Ordering::SeqCst)
}

The call must be in an unsafe block, otherwise rustc complains

  = help: in order for the call to be safe, the context requires the following additional target feature: cmpxchg16b
  = note: the cmpxchg16b target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`

blocked on llvm/llvm-project#187503

context: https://rust-lang.zulipchat.com/#narrow/channel/327149-t-libs-api.2Fapi-changes/topic/AtomicU128.20if.20cmpexch16b.20is.20enabled

r? @Amanieu

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 20, 2026
@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

This would also cause target_has_atomic="128" to be enabled as cfg even when cmpxchg16b is not enabled, right? That will break code that expects target_has_atomic="128" to imply that using AtomicU128/AtomicI128 can be used with safe code.

@usamoi
Copy link
Contributor Author

usamoi commented Mar 20, 2026

This would also cause target_has_atomic="128" to be enabled as cfg even when cmpxchg16b is not enabled, right?

Yes.

That will break code that expects target_has_atomic="128" to imply that using AtomicU128/AtomicI128 can be used with safe code.

128-bit atomics are not stabilized yet although it passed FCP.

@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

That will break code that expects target_has_atomic="128" to imply that using AtomicU128/AtomicI128 can be used with safe code.

128-bit atomics are not stabilized yet although it passed FCP.

It does mean either all code that wants to use 128-bit atomics has to special case x86_64 and only use it there is cmpxchg16b is also enabled, or if we want to keep the option open to also make it target feature dependent on other architectures, it isn't possible to use 128-bit atomics in architecture independent code at all.

@usamoi
Copy link
Contributor Author

usamoi commented Mar 20, 2026

all code that wants to use 128-bit atomics has to special case x86_64 and only use it there is cmpxchg16b is also enabled, or if we want to keep the option open to also make it target feature dependent on other architectures

The final goal is to do this for all architectures that support 128-bit atomics but require some target features.

it isn't possible to use 128-bit atomics in architecture independent code at all

True. Logically this is also impossible.

@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

Logically this is also impossible.

Before this PR #[cfg(target_has_atomic="128")] is enough for architecture independent code to only use 128bit atomics when supported. With this PR it would become

#[cfg(all(
    target_has_atomic = "128",
    any(
        all(target_arch = "x86_64", target_feature = "cmpxchg16b"),
        // other architecture+target feature pairs
    )
))]

at that point #[cfg(target_has_atomic = "128")] effectively becomes useless as you have to hard code every single architecture+target feature pair anyway.

I did much rather have target_has_atomic = "128" disabled for any target where 128bit atomics can't be used unconditionally and then require users to write something like:

#[cfg(any(
    target_has_atomic = "128", // 128bit atomics are always supported for this target
    all(target_arch = "x86_64", target_feature = "cmpxchg16b"), // x86_64 needs cmpxchg16b for 128bit atomics to be available
    // other architecture+target feature pairs for targets where 128bit atomics are conditionally supported
))]

@taiki-e
Copy link
Member

taiki-e commented Mar 20, 2026

128-bit atomics are not stabilized yet although it passed FCP.

all code that wants to use 128-bit atomics has to special case x86_64 and only use it there is cmpxchg16b is also enabled, or if we want to keep the option open to also make it target feature dependent on other architectures

The final goal is to do this for all architectures that support 128-bit atomics but require some target features.

FYI, AFAIK, riscv32/m68k/mips32r6 (64-bit atomics) and riscv64/powerpc64(be)/loongarch64/nvptx64/mips64r6 (128-bit atomics) are in a similar situation to x86_64’s cmpxchg16b (some CPUs support atomic operations with a larger width than what is available in the target's baseline).

In other words, it's not specific to 128-bit atomics. Also related to 64-bit atomics which already in stable.

@usamoi
Copy link
Contributor Author

usamoi commented Mar 20, 2026

at that point #[cfg(target_has_atomic = "128")] effectively becomes useless as you have to hard code every single architecture+target feature pair anyway.

For implementing traits for AtomicU128 / AtomicI128, there needs to be a cfg that indicates whether these types exist. We may need a new cfg.

@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

FYI, AFAIK, riscv32/m68k/mips32r6 (64-bit atomics) and riscv64/powerpc64(be)/loongarch64/nvptx64/mips64r6 (128-bit atomics) are in a similar situation to x86_64’s cmpxchg16b (some CPUs support atomic operations with a larger width than what is available in the target's baseline).

For those we set target_has_atomic = "32", not target_has_atomic = "64". Adding the latter for these targets is definitively a breaking change.

@Urgau
Copy link
Member

Urgau commented Mar 20, 2026

The reference defines target_has_atomic as:

Key-value option set for each bit width that the target supports atomic loads, stores, and compare-and-swap operations.
[cfg.target_has_atomic.stdlib]

When this cfg is present, all of the stable core::sync::atomic APIs are available for the relevant atomic width.

So, #[cfg(target_has_atomic = "128")] should be enough to know if one can use AtomicU128/AtomicI128 safely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants