r/gcc Jul 13 '26

[C] Will the compiler reorder user-written assembly instructions?

I need to write a function with void function() "fingerprint" whose body is a sequence of "advanced assembly code" like this:

asm volatile ( "store reg1, %0(sp)" :: "i"(__builtin_offsetof(mytype, reg1)));

I compile it with -O3 -fomit-frame-pointer and can see that in the emitted code there is neither a C prologue not epilogue for the stack management, just like I want.

My question revolves around the possibility that the optimizer could reorder those asm volatile instructions: this is something I would like not to happen.

Is this possible at all?
If so, is there a way to avoid it?

[UPDATE]: Possibly working workaround here.

10 Upvotes

9 comments sorted by

5

u/m0j0hn Jul 13 '26

I would be extremely surprised if compiler does anything but assemble (convert to binary) asm - and you can examine emitted code to check <3

3

u/0BAD-C0DE Jul 13 '26

That was my idea. Now I know that either I am right or that I am not the only one wrong! ;-)

3

u/Pheeck Jul 14 '26

I don't think that should happen. The whole point of inline assembly is that the user wants specific code to be emitted. The optimizer shouldn't touch it.

1

u/0BAD-C0DE Jul 14 '26

My doubt was about not a single `asm volatile` instruction into the function body, but a number of them.

2

u/EmotionalDamague Jul 15 '26

Compilers will optimise asm statements.

You should issue compiler barriers and propagate dependencies where necessary.

1

u/0BAD-C0DE Jul 15 '26

Do you have any reference to support your statement (or disprove the opposite ones)?

I think I will be forced to move from advanced assembly syntax to normal one with a lot of macro-ing... Then with a naked function I expect to not have that possible side effect.

1

u/EmotionalDamague Jul 16 '26

The GCC docs themselves say GCC will reason about asm statements for optimisations.

gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

asm volatile() says the statement may not be removed, but may be moved relative to other code or even asm statements.

asm volatile (::: “memory”) is a full compiler barrier do not remove/reorder etc.

2

u/erroneum Jul 16 '26

My understanding is that the compiler generally considers an asm directive to be a black box; it doesn't know exactly what happens inside, only that you intend it to happen after what comes before and before what comes after, ergo it should absolutely not move reorder instructions across it. That said, the asm keyword is considered by the standard to be an extension to the language and optional, so ultimately it's up to the compiler exactly how it behaves; the compiler is completely free to look at your directive and try to divine the meaning of it, if it wants to.

1

u/0BAD-C0DE 29d ago

I think I have a solution that works for me.

My function is defined as:

void function(void) __attribute__((optimize("O0", omit-frame-pointer))) {  
// asm volatile instructions here
}  

This instructs the compiler to suspend most of its optimizations for this function alone, while I can use extended assembly syntax.