https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96056
Bug ID: 96056 Summary: arm v6/v7: Missing acquire barrier for __atomic_compare_exchange(__ATOMIC_RELEASE, __ATOMIC_ACQUIRE) Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: izbyshev at ispras dot ru CC: amonakov at gcc dot gnu.org Target Milestone: --- $ cat test.c void foo(int x, int y, int z) { __atomic_compare_exchange(&x, &y, &z, 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE); } $ arm-linux-gnueabi-gcc-10 -O2 -march=armv7 -S -o - test.c [...] sub sp, sp, #8 str r0, [sp, #4] add r0, sp, #4 dmb ish .L2: ldrex r3, [r0] cmp r3, r1 bne .L3 strex ip, r2, [r0] cmp ip, #0 bne .L2 .L3: @ <=== missing dmb here add sp, sp, #8 [...] Changing __ATOMIC_RELEASE to __ATOMIC_ACQ_REL restores the missing barrier. The same problem applies to armv6 as well. I've checked that all GCC versions on gcc.godbolt.org since 5.4.0 behave in the same way. All Clang versions on godbolt don't have this problem.