Why are aggressive compiler optimizations dangerous?

decode

Member
Nov 12, 2003
28
0
0
I'll start out by saying that my experience is limited to SPARC assembly language and the SUN cc compiler. That said, why is it that aggressive compiler optimizations could cause instability or incorrect operation of programs?
I know that Gentoo turns off optimizations when compiling OpenOffice.org, because OOo is sensitive to optimizations and the OOo guys will not support it if aggressive optimizations are turned on. Also, most people don't compile with level 5 optimizations, they opt for 2 or 3 instead. So, it seems that programs can be affected adversely by optimization level.
However, having looked at some assembly created from C programs compiled with different optimization levels, I don't see how this could be the case. The main differences I've noticed between different levels of optimization are loop unrolling, using registers instead of main memory for holding intermediate values, and rearranging instructions to get rid of nops. I don't understand how any of this can change the reliability of execution. What am I missing?
 

CTho9305

Elite Member
Jul 26, 2000
9,214
1
81
Let's say you write code like this:
int i;
for(i=0; i<strlen(someString); i++)
{
doSomething();
}

If the compiler agressively optimizes, it could replace that code with:
int i;
int tmpLen = strlen(someString);
for(i=0; i<tmpLen; i++)
{
doSomething();
}

Now, strlen() is only called once. The result will be much faster, BUT... if instead of strlen() we called a function that had a side effect, the result would be different. In other situations, compilers can take shortcuts with floating point operations that reduce accuracy in favor of speed, but those are probably fine outside of scientific apps.

Take this:
void doSomething1(int *x, int *y)
{
*x += (*y);
*x += (*y);
*x += (*y);
}

void doSomething2(int *x, int *y)
{
*x = *x + 3*(*y)
}
At first glance, both functions appear to set x to x + 3y. But what if x and y point to the same thing? The first function sets x to 2x, then 4x, then 8x, whereas the second sets x to 4x. This is another optimization that a compiler cannot safely make, since it can't be sure you ALWAYS pass 2 different pointers. With agressive optimization however, it might decide to make the change, and if you DO end up hitting one of the corner cases (such as passing the same pointer twice), the result will be a broken program.

My CS textbook has a chapter on optimizations, but I can't remember any other examples.

If I remember correctly, gcc performs safe optimizations at -O2, but not at higher levels.