https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63375
--- Comment #13 from Pranith Kumar <bobby.prani at gmail dot com> --- The main concern here is moving the read past the fence instruction irrespective of volatile semantics. The fence instruction guarantees that accesses before the fence will complete before the accesses coming after the fence. Consider the following case: #include<stdio.h> typedef struct { int counter; } atomic_t; static inline int atomic_read(atomic_t *v) { return (*(volatile int *)&(v)->counter); } static inline void atomic_write(atomic_t *v, int val) { v->counter = val; } #define smp_mb() asm volatile ("mfence":::"memory") atomic_t val2 = {1}; int main() { atomic_t val1 = {1}; int p, q; smp_mb(); p = atomic_read(&val1); smp_mb(); atomic_write(&val2, 2); smp_mb(); q = atomic_read(&val2); printf("%d %d\n", p, q); return 0; } Here, because of the bug the read from val1 is being generated after the write to val2 breaking the semantics of memory fences. What am I missing?