[Bug target/96056] arm v6/v7: Missing acquire barrier for __atomic_compare_exchange(__ATOMIC_RELEASE, __ATOMIC_ACQUIRE)
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Sep 3 15:06:02 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96056
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Richard Earnshaw <rearnsha@gcc.gnu.org>:
https://gcc.gnu.org/g:a3b4c732f41fd627722df998ebb4c082ada20971
commit r17-3901-ga3b4c732f41fd627722df998ebb4c082ada20971
Author: Dominic P <gcc@gcc.dp11.uk>
Date: Sun Aug 2 11:56:04 2026 +0100
arm: Missing barrier for cmp_exch rel/acq [PR96056]
An __atomic_compare_exchange with a success memory order of RELEASE and
a failure memory order of ACQUIRE requires release ordering on the store
path and acquire ordering on the (load-only) fail path. This is a
well-formed combination: the two orders govern different sub-operations,
and since C++17 the failure order need only avoid RELEASE/ACQ_REL and is
otherwise unconstrained relative to the success order.
arm_expand_compare_and_swap promotes the success model to ACQ_REL for
this case so that both the release and the acquire orderings are
preserved, but the promotion was gated on TARGET_HAVE_LDACQ. On
ARMv6/ARMv7, which lack load-acquire/store-release instructions, the
ordering is instead provided by explicit DMB barriers derived solely
from the success memory model in arm_split_compare_and_swap. Without
the promotion the success model stayed RELEASE, so need_atomic_barrier_p
emitted only the pre (release) barrier and dropped the post (acquire)
barrier. The fail path was therefore left with no acquire barrier,
allowing later memory accesses to be reordered before the failed CAS
load and violating the requested acquire semantics.
For armv7-a the wrong sequence was:
dmb ish
.L2: ldrex r2, [r3]
cmp r2, r0
bne .L3
strex ip, r1, [r3]
cmp ip, #0
bne .L2
.L3: <- fall-through, no acquire barrier
Remove the TARGET_HAVE_LDACQ guard so the promotion, and hence the
trailing acquire barrier, is applied on all targets. ARMv8 LDACQ
targets are unaffected: they already promoted and continue to emit
ldaex/stlex with no DMB.
Assisted-by: Claude Opus 5 (Anthropic)
gcc/ChangeLog:
PR target/96056
* config/arm/arm.cc (arm_expand_compare_and_swap): Always promote
mod_s to ACQ_REL for the RELEASE/ACQUIRE combination.
gcc/testsuite/ChangeLog:
PR target/96056
* gcc.target/arm/atomic-comp-swap-release-acquire-4.c: New test.
Signed-off-by: Dominic P <gcc@gcc.dp11.uk>
More information about the Gcc-bugs
mailing list