[LangRef] No target-specific size limit for atomics (#136864)

According to the current LangRef, atomics of sizes larger than a
target-dependent limit are non-conformant IR. Presumably, that size
limit is `TargetLoweringBase::getMaxAtomicSizeInBitsSupported()`. As a
consequence, one would not even know whether IR is valid without
instantiating the Target backend.

To get around this, Clang's CGAtomic uses a constant "16 bytes" for the
maximally supported atomic. The verifier only checks the power-of-two
requirement.

In a discussion with jyknight, the intention is rather that the
AtomicExpandPass will just lower everything larger than the
target-supported atomic sizes to libcall (such as `__atomic_load`).
According to this interpretation, the size limit needs only be known by
the lowering and does not affect the IR specification.

The original "target-specific size limit" had been added in
59b66883eacbc62a09c09f08bcbfdce7af46cf31. The LangRef change is needed
for #134455 because otherwise frontends need to pass a TargetLowering
object to the helper functions just to know what the target-specific
limit is.

This also changes the LangRef for atomicrmw. Are there libatomic
fallbacks for these? If not, LLVM-IR validity still depends on
instantiating the actual backend. There are also some intrinsics such as
`llvm.memcpy.element.unordered.atomic` that have this constraint but do
not change in this PR.
This commit is contained in:
Michael Kruse 2025-07-14 20:36:09 +02:00 committed by GitHub
parent 7615503409
commit ec2e21a14d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -11281,7 +11281,7 @@ If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
Atomic loads produce :ref:`defined <memmodel>` results when they may see Atomic loads produce :ref:`defined <memmodel>` results when they may see
multiple atomic stores. The type of the pointee must be an integer, pointer, or multiple atomic stores. The type of the pointee must be an integer, pointer, or
floating-point type whose bit width is a power of two greater than or equal to floating-point type whose bit width is a power of two greater than or equal to
eight and less than or equal to a target-specific size limit. ``align`` must be eight. ``align`` must be
explicitly specified on atomic loads. Note: if the alignment is not greater or explicitly specified on atomic loads. Note: if the alignment is not greater or
equal to the size of the `<value>` type, the atomic operation is likely to equal to the size of the `<value>` type, the atomic operation is likely to
require a lock and have poor performance. ``!nontemporal`` does not have any require a lock and have poor performance. ``!nontemporal`` does not have any
@ -11422,7 +11422,7 @@ If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
Atomic loads produce :ref:`defined <memmodel>` results when they may see Atomic loads produce :ref:`defined <memmodel>` results when they may see
multiple atomic stores. The type of the pointee must be an integer, pointer, or multiple atomic stores. The type of the pointee must be an integer, pointer, or
floating-point type whose bit width is a power of two greater than or equal to floating-point type whose bit width is a power of two greater than or equal to
eight and less than or equal to a target-specific size limit. ``align`` must be eight. ``align`` must be
explicitly specified on atomic stores. Note: if the alignment is not greater or explicitly specified on atomic stores. Note: if the alignment is not greater or
equal to the size of the `<value>` type, the atomic operation is likely to equal to the size of the `<value>` type, the atomic operation is likely to
require a lock and have poor performance. ``!nontemporal`` does not have any require a lock and have poor performance. ``!nontemporal`` does not have any
@ -11567,8 +11567,8 @@ There are three arguments to the '``cmpxchg``' instruction: an address
to operate on, a value to compare to the value currently be at that to operate on, a value to compare to the value currently be at that
address, and a new value to place at that address if the compared values address, and a new value to place at that address if the compared values
are equal. The type of '<cmp>' must be an integer or pointer type whose are equal. The type of '<cmp>' must be an integer or pointer type whose
bit width is a power of two greater than or equal to eight and less bit width is a power of two greater than or equal to eight.
than or equal to a target-specific size limit. '<cmp>' and '<new>' must '<cmp>' and '<new>' must
have the same type, and the type of '<pointer>' must be a pointer to have the same type, and the type of '<pointer>' must be a pointer to
that type. If the ``cmpxchg`` is marked as ``volatile``, then the that type. If the ``cmpxchg`` is marked as ``volatile``, then the
optimizer is not allowed to modify the number or order of execution of optimizer is not allowed to modify the number or order of execution of
@ -11681,8 +11681,8 @@ operation. The operation must be one of the following keywords:
- usub_sat - usub_sat
For most of these operations, the type of '<value>' must be an integer For most of these operations, the type of '<value>' must be an integer
type whose bit width is a power of two greater than or equal to eight type whose bit width is a power of two greater than or equal to eight.
and less than or equal to a target-specific size limit. For xchg, this For xchg, this
may also be a floating point or a pointer type with the same size constraints may also be a floating point or a pointer type with the same size constraints
as integers. For fadd/fsub/fmax/fmin/fmaximum/fminimum, this must be a floating-point as integers. For fadd/fsub/fmax/fmin/fmaximum/fminimum, this must be a floating-point
or fixed vector of floating-point type. The type of the '``<pointer>``' or fixed vector of floating-point type. The type of the '``<pointer>``'