buggy optimization levels...
Chuck Swiger
cswiger at mac.com
Sat Aug 2 12:52:44 PDT 2003
Erik Trulsson wrote:
[ ... ]
> A somewhat contrived example that behaves differently when compiled
> with -O3 or when compiled with -O2 or lower optimization follows:
>
> static int f(int a)
> {
> return a/0;
> }
> int main(void)
> {
> int x;
> x = f(5);
> return 0;
> }
Contrived, but interesting and useful nonetheless; thanks for the response.
[ ... ]
>> Even if the code contains a bug, "cc -O" and "cc -O -fgcse" should produce
>> the same results. Excluding certain well-defined exceptions (-ffast-math
>> comes to mind), compiler optimizations likes -fgcse are not allowed to
>> change the meaning of compiled code, do we agree?
>
> Not quite. Compiler optimization flags (with a few exceptions like
> -ffast-math) are not allowed to change the semantics of the compiled
> code.
I really don't want to debate the use of "meaning" versus "semantics". :-)
> For buggy code that invokes undefined behaviour (divison by
> zero, accessing unallocated memory, etc.) there is no semantics to
> preserve and therefore the compiled code may well produce different
> results when compiled with different flags.
C code that permits a divide-by-zero condition will result in a runtime error,
but I disagree that this has "no semantics to preserve". If the code was using
floating point, IEEE 754 defines semantics for divide-by-zero one could also
have an 'Infinity' result, but that's not available with ints; your code results
in a SIGFPE being generated.
> (Undefined behaviour in the context of the C standard means the
> compiler is allowed to do whatever it damn well pleases, including, but
> not limited to, doing what you wanted and expected it to do, formatting
> your harddisk or making demons fly out of your nose.
Sure. I see and acknowledge the validity of your point: it's possible for a
programmer to write code which has different behavior depending on (say)
-finline-functions.
However, that being said, the fact that the C standard says such-and-such gives
"undefined behavior" does not preclude the implementation from defining the
behavior for such-and-such.
>> If there exists any lexically correct input source code (ie, which parses
>> validly) where compiling with -fgcse results in different behavior, that
>> optimization is unsafe and should not be enabled by -O2 in any circumstance.
>
> With that definition just about *all* optimizations would be unsafe.
>
> (And optimization is actually *supposed* to give different behaviour.
> The running time of a program is part of its behaviour and
> optimization is generally supposed to reduce the running time, thereby
> giving different behaviour.)
What you say is so obviously correct that one should instead conclude that my
use of the term 'behavior' with regard to compiler optimizations has a more
specific meaning.
Page 586 of _Compilers: Principles, Techniques, and Tools_ states:
First, a transformation must preserve the meaning of programs. That is, an
"optimization" must not change the output produced by a program for a given
input, or cause an error, such as a division by zero, that was not present in
the original program. The influence of this criterion prevades this chapter; at
all times we take the "safe" approach of missing an opportunity to apply a
transformation rather than risk changing what the program does.
--
Like your divide-by-zero example above, or this paragraph about "semantics" vs
"meaning", I'm not going to disagree if you want to state that the running time
of a program is part of the "behavior". However, using the terms in such a
fashion precludes you from understanding the intended meaning in this particular
context.
--
-Chuck
More information about the freebsd-questions
mailing list