It is known that asm volatile ("" ::: "memory")
can serve as a compiler barrier to prevent compiler from reordering assembly instructions across it. For example, it is mentioned in https://preshing.com/20120625/memory-ordering-at-compile-time/, section "Explicit Compiler Barriers".
However, all the articles I can find only mention the fact that asm volatile ("" ::: "memory")
can serve as a compiler barrier without giving a reason why the "memory"
clobber can effectively form a compiler barrier. The GCC online documentation only says that all the special clobber "memory"
does is tell the compiler that the assembly code may potentially perform memory reads or writes other than those specified in operands lists. But how does such a semantic cause compiler to stop any attempt to reorder memory instructions across it? I tried to answer myself but failed, so I ask here: why can asm volatile ("" ::: "memory")
serve as a compiler barrier, based on the semantics of "memory"
clobber? Please note that I am asking about "compiler barrier" (in effect at compile-time), not stronger "memory barrier" (in effect at run-time). For convenience, I excerpt the semantics of "memory"
clobber in GCC online doc below:
The
"memory"
clobber tells the compiler that the assembly code performs memory reads or writes to items other than those listed in the input and output operands (for example, accessing the memory pointed to by one of the input parameters). To ensure memory contains correct values, GCC may need to flush specific register values to memory before executing theasm
. Further, the compiler does not assume that any values read from memory before anasm
remain unchanged after thatasm
; it reloads them as needed. Using the"memory"
clobber effectively forms a read/write memory barrier for the compiler.