https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65697
--- Comment #17 from mwahab at gcc dot gnu.org --- According to the GCC documentation, __atomic_compare_exchange(ptr, exp, des, ..) is: if (*ptr == *exp) *ptr = *exp; else *exp = *ptr; On Aarch64 the else (*ptr != *exp) branch is a store rather than a store-release. This doesn't appear in your example but with ---- int cas(int* barf, int* expected, int* desired) { return __atomic_compare_exchange_n(barf, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } ---- cas: ldr w3, [x1] .L3: ldaxr w4, [x0] cmp w4, w3 bne .L4 stlxr w5, w2, [x0] ; store-release cbnz w5, .L3 .L4: cset w0, eq cbz w0, .L6 ret .p2align 3 .L6: str w4, [x1] ; store, no barrier. ret ---- This looks odd to me but I'd need look into it more.