GCC does not seem to be able to trace and optimize programs that read/write global variables in C/C++, even if they're static
, which should allow it to guarantee that other compilation units won't change the variable.
When compiling the code
static int test = 0;
int abc() {
test++;
if (test > 100) \
return 123;
--test;
return 1;
}
int main() {
return abc();
}
with the flags -Os
(to produce shorter and more readable assembly) and -fwhole-program
or -flto
using GCC version 11.2 I would expect this to be optimized to return 1
, or the following assembly:
main:
mov eax, 1
ret
This is in fact what is produced if test
is a local variable. However, the following is produced instead:
main:
mov eax, DWORD PTR test[rip]
mov r8d, 1
inc eax
cmp eax, 100
jle .L1
mov DWORD PTR test[rip], eax
mov r8d, 123
.L1:
mov eax, r8d
ret
Example: https://godbolt.org/z/xzrPjanjd
This happens with both GGC and Clang, and every other compiler I tried. I would expect modern compilers to be able to trace the flow of the program and remove the check. Is there something I'm not considering that may allow something external to the program to affect the variable, or is this just not implemented in any compilers yet?
Related: Why gcc isn't optimizing the global variable? but the answer given there mentions external functions and threads, neither of which apply here