https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95692
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|WAITING |RESOLVED --- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Doing this fixes the issue: int intercept_munmap(void *start, size_t length) { unsigned long toc_save; asm volatile ("std 2, %0" : "=m" (toc_save) :: "memory"); asm volatile ("nop; nop; nop; nop; nop" ::: "memory");; volatile MyFunction_t fn; fn = foo; fn(); int result = syscall( 91 , start, length); asm volatile ("ld 2, %0" : : "m" (toc_save) : "memory");; return result; } That is you need to also mark the asm as clobbering memory. Otherwise the asm can be moved. As mentioned in the manual volatile can still move inline-asm around with volatile: https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Extended-Asm.html#Volatile-1 : ``` 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 statement, as in the following PowerPC example, does not work reliably. ```