Does gcc/g++ have flags to enable or disable arithmetic optimisations, e.g. where a+a+...+a
is replaced by n*a
when a
is an integer? In particular, can this be disabled when using -O2
or -O3
?
In the example below even with -O0
the add operations are replaced by a single multiplication:
$ cat add1.cpp
unsigned int multiply_by_22(unsigned int a)
{
return a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;
}
$ g++ -S -masm=intel -O0 add1.cpp
$ cat add1.s
...
imul eax, edi, 22
Even disabling all the flags used in -O0
(see g++ -c -Q -O0 --help=optimizers | grep enabled
) still produces the imul
operation.
When adding loops, it requires -O1
to simplify the repeated addition to a single multiplication:
$ cat add2.cpp
unsigned int multiply(unsigned int a, unsigned int b)
{
unsigned int sum=0;
for(unsigned int i=0; i<b; i++)
sum += a;
return sum;
}
$ g++ -S -masm=intel -O1 add2.cpp
$ cat add2.s
...
mov eax, 0
.L3:
add eax, 1
cmp esi, eax
jne .L3
imul eax, edi
ret
I.e. -O1
has moved the sum += a;
outside the loop and replaced it by a single multiplication. With -O2
it will also remove the dead loop.
I'm just asking out of interest as I was trying to time some basic integer operations and noticed that the compiler optimised my loops away and I couldn't find any flags to disable this.