This is very interesting, I always thought myself that volatile acted as a code barrier. However the documentation [1] explicitely states that this is not the case:
"Note that the compiler can move even volatile asm instructions relative to other code, including across jump instructions. For example, on many targets there is a system register that controls the rounding mode of floating-point operations. Setting it with a volatile asm, as in the following PowerPC example, does not work reliably."
It is therefore not a bug since the compiler is working as intended, though I agree it is surprising. Worse of, the only solution I can propose is to write atomic sections into a single assembly block. I've looked into GCC atomic and synchronization primitives but couldn't find any that provide a code barrier, despite GCC having code barriers internally. I'll continue searching for a solution and will get back to you if I find one.
This is very interesting, I always thought myself that volatile acted as a code barrier. However the documentation [1] explicitely states that this is not the case:
"Note that the compiler can move even volatile asm instructions relative to other code, including across jump instructions. For example, on many targets there is a system register that controls the rounding mode of floating-point operations. Setting it with a volatile asm, as in the following PowerPC example, does not work reliably."
[1] https:/ /gcc.gnu. org/onlinedocs/ gcc/Extended- Asm.html# Volatile
It is therefore not a bug since the compiler is working as intended, though I agree it is surprising. Worse of, the only solution I can propose is to write atomic sections into a single assembly block. I've looked into GCC atomic and synchronization primitives but couldn't find any that provide a code barrier, despite GCC having code barriers internally. I'll continue searching for a solution and will get back to you if I find one.
Best regards.