x86 instructions: atomic vs non-atomic assignment in C
Martin Uecker
muecker@gwdg.de
Fri Sep 25 06:53:11 GMT 2026
Am Donnerstag, dem 24.09.2026 um 21:12 -0700 schrieb Andrey Tarasevich via Gcc:
> Hello
>
> I'm curious about the following x86-64 code generation peculiarity related to atomic variables. Consider a simple C program
>
> _Atomic unsigned x;
> volatile unsigned y;
>
> int main()
> {
> x = 42; /* 1 */
> y = 42; /* 2 */
> }
>
> The above assignments are translated by GCC as follows. Assignment 1 ("atomic") becomes
>
> mov eax, 42
> xchg eax, DWORD PTR x[rip]
>
> while assignment 2 ("non-atomic") becomes
>
> mov DWORD PTR y[rip], 42
>
> My question is: is there a tangible rationale/reason for the difference? I do understand that "memory-immediate operand" version of `mov` instruction is not atomic as a whole. But if I'm not mistaken, the store operation performed by such a `mov` is still perfectly atomic by itself (provided the memory location is aligned correctly). Which means that for the above purposes a plain `mov` would still satisfy the requirements of atomic behavior. Nevertheless, the code generator opts for a separate load into `eax` followed by an atomic `xchg`. Why? Is there a reason to prefer that latter approach? Am I missing something about the `mov` version?
>
> BTW, Clang is doing exactly the same thing.
I believe the xchg implies a memory barrier which is required for sequential
ordering while the store via mov only has release semantics.
Martin
More information about the Gcc
mailing list