Red Hat Bugzilla – Bug 154987
-O2 optimizer produces bad code from casts, autoincrement and globals
Last modified: 2007-11-30 17:11:04 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.6) Gecko/20050323 Firefox/1.0.2 Fedora/1.0.2-1.3.1
Description of problem:
Attached program doesn't increment the global "cp" variable when compiled with gcc -O2. When compiled with -O or non-optimized, it works correctly. In the assembler code (also attached) which the compiler produces, the compiler is updating the global "cp" variable twice, 1st time correctly, 2nd time wrongly.
(This is a very highly cut down version of a virtual machine run-time: the global is the program counter (bytecode pointer))
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. compile attached program: "cc -o tst tst.c"
2. run with "./tst"
3. result is "cp change is 6" (correct behaviour)
4. compile again with "cc -O2 -o tst tst.c"
5. run with "./tst"
6. result is "cp change is 2" (incorrect behaviour)
Actual Results: prints "cp change is 2"
Expected Results: should print "cp change is 6"
also seen in gcc-3.4.2-6.fc3
Created attachment 113221 [details]
the C program which doesn't compile correctly under -O2
Created attachment 113222 [details]
assembler output from the compiler with "cc -S -g -dA -O2 tst.c"
search for "tst.c:10" (the code for source line 10). Notice that there are 2
movl instructions updating the global "cp". There should clearly only be one
under high optimization, and the 2nd update is wrong anyway.
Please consider using -Wall before reporting something as a bug.
Compiler tells you where the problem is. The testcase is buggy, you
violate ISO C99 aliasing rules, as you access the same object using
different types and the object is not a union of those different types.
If you turn off strict aliasing, with -O2 -fno-strict-aliasing, it will
output 6 as you expected.