2

I am studying glibc (The version is 2.32). As for memory barrier, read, write and full barrier for x86 are as follows:

#define atomic_full_barrier() \
    __asm __volatile (LOCK_PREFIX "orl $0, (%%" SP_REG ")" ::: "memory")
#define atomic_read_barrier() __asm ("" ::: "memory")
#define atomic_write_barrier() __asm ("" ::: "memory")

As cppreference and this answer say, volatile tells the compiler don't optimize and reorder this instruction.

Why do write and read barrier not use __asm __volatile, while full barrier uses it?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Zihe Liu
  • 159
  • 1
  • 12

1 Answers1

4

An asm statement with no output operands is implicitly volatile (GCC manual).
So they're actually all volatile, which is necessary for them to not be removed by the optimizer.

(non-volatile asm is assumed to be a pure function with no side effects, run only if needed to produce the outputs. The clobbers are only clobbered if / when the optimizer decides it needs to run the asm statement).

Different authors chose to be more or less explicit. If you git blame, I expect you'll see those were written at different times and/or by different people.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Thanks very much for your quick answer. Why is an `asm` statement without output operands implicitly `volatile`? If this statement doesn't have side effects and output operands, can the compiler discard it? – Zihe Liu Sep 29 '20 at 09:29
  • I'm a little confused about the effect of `volatile`. The [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile) says, GCC’s optimizers sometimes discard `asm` statements if they determine there is **no need for the output variables**. Does it means `volatile` only prevents the optimizers to discard the statement whose output doesn't need, but doesn't prevent them to discard the statement without side effects? – Zihe Liu Sep 29 '20 at 09:41
  • 1
    @ZiheLiu: If it had no outputs and wasn't `volatile`, the compiler would *always* be able to discard it. Like calling a pure function without assigning the return value to anything. It might have been better to force people to write `volatile` for that case when designing the syntax, but that makes it consistent with GNU C "Basic" asm statements (no constraints). However, you should pretty much never use Basic asm for anything (https://gcc.gnu.org/wiki/ConvertBasicAsmToExtended) – Peter Cordes Sep 29 '20 at 09:44
  • If it was `volatile` but had no side effects, could compliers discard it? In other words, if it had no outputs and wasn't `volatile`, but had side effects (e.g. change the input memory or register), could compilers discard it? – Zihe Liu Sep 29 '20 at 10:02
  • @ZiheLiu: Compilers only know what you tell them via volatile or not, and the constraints. Lack of `volatile` *means* it has no necessary side effects beyond writing the output operands. Using `volatile` effectively tells the compiler there are side effects. (Really it tells the compiler that this statement must run as many times as the C abstract machine would run it, and not reordered wrt. any other `volatile` accesses, including `volatile int` or whatever loads and stores.) – Peter Cordes Sep 29 '20 at 10:06