https://gcc.gnu.org/g:a3b4c732f41fd627722df998ebb4c082ada20971

commit r17-3901-ga3b4c732f41fd627722df998ebb4c082ada20971
Author: Dominic P <[email protected]>
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 <[email protected]>

Diff:
---
 gcc/config/arm/arm.cc                                          |  4 +---
 .../gcc.target/arm/atomic-comp-swap-release-acquire-4.c        | 10 ++++++++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 0bc66abe238b..33b64995442f 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -31367,9 +31367,7 @@ arm_expand_compare_and_swap (rtx operands[])
   /* Normally the succ memory model must be stronger than fail, but in the
      unlikely event of fail being ACQUIRE and succ being RELEASE we need to
      promote succ to ACQ_REL so that we don't lose the acquire semantics.  */
-
-  if (TARGET_HAVE_LDACQ
-      && is_mm_acquire (memmodel_from_int (INTVAL (mod_f)))
+  if (is_mm_acquire (memmodel_from_int (INTVAL (mod_f)))
       && is_mm_release (memmodel_from_int (INTVAL (mod_s))))
     mod_s = GEN_INT (MEMMODEL_ACQ_REL);
 
diff --git a/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire-4.c 
b/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire-4.c
new file mode 100644
index 000000000000..b80242d640be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v7a_ok } */
+/* { dg-options "-O2 -fno-ipa-icf" } */
+/* { dg-add-options arm_arch_v7a } */
+
+#include "../aarch64/atomic-comp-swap-release-acquire.x"
+
+/* { dg-final { scan-assembler-not "ldaex" } } */
+/* { dg-final { scan-assembler-not "stlex" } } */
+/* { dg-final { scan-assembler-times "dmb\tish" 8 } } */

Reply via email to