I noticed that when optimizations are turned off, GCC (version 13.1.1 20230714
) when asked to assemble the below C program, loads the address of the string (i.e., .string "HI"
in the assembler output) into rax
and then into rdi
before calling the function -
#include <stdio.h>
int main() {
printf("HI\n");
return 0;
}
The assembler output with optimizations turned off (-O0
) -
...
lea rax, .LC0[rip]
mov rdi, rax
call puts@PLT
....
And with optimizations turned on (for -O1
, -O2
, and -O3
) -
...
lea rdi, .LC0[rip]
call puts@PLT
mov eax, 0
...
I understand that I can expect the versions with optimizations to do things more...optimally. But, there is nothing about the C code that I wrote which makes the unoptimized assembly a more "one-to-one" mapping of assembly to C so I don't see why gcc should default to loading the address into rax
. In any case, it is already not the case that gcc is not optimizing anything since it replaced the call to printf
with a call to puts
.
Can someone help explain to me why gcc does this? Does it have any advantage or is it simply not worth making the -O0
compilation do something like this? If this is the default behaviour for all function calls (before optimization), what is the reason that gcc loads the first argument into rax
, shouldn't loading the first argument directly into rdi
be the sensible default?
GCC version - gcc (GCC) 13.1.1 20230714
Platform/OS - Linux 6.4.3-arch1-2 x86_64 GNU/Linux
Compilation command - gcc -O0/1/2/3 -S -masm=intel load.c