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 <[email protected]>:

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]>

Reply via email to