gcc -v output: Reading specs from /opt/gcc-3.4/lib/gcc/i686-pc-linux-gnu/3.4.3/specs Configured with: ./configure --prefix=/opt/gcc-3.4 --enable-languages=c,c++ Thread model: posix gcc version 3.4.3
See following preprocessed output: extern "C" { extern void __assert_fail (__const char *__assertion, __const char *__file, unsigned int __line, __const char *__function) throw () __attribute__ ((__noreturn__)); } static void DoTest() { double doubleOne = 1.0; float floatOne = 1.0F; unsigned int *intDptr = (unsigned int *) &doubleOne; unsigned int *intFptr = (unsigned int *) &floatOne; (static_cast<void> (__builtin_expect (!!((intDptr[1] == 0x3ff00000) && (intDptr[0] == 0)), 1)? 0 : (__assert_fail ("(intDptr[1] == 0x3ff00000) && (intDptr[0] == 0)", "fptest.cpp", 12, __PRETTY_FUNCTION__), 0))); (static_cast<void> (__builtin_expect (!!(*intFptr == 0x3f800000), 1) ? 0 : (__assert_fail ("*intFptr == 0x3f800000", "fptest.cpp", 13, __PRETTY_FUNCTION__), 0))); } int main() { DoTest(); } This compiles fine up to -O1, but with -O2 the test fails. When looking at the generated assembler it seems to me that the compiler first issues the compare before putting a value in it. Generated assembler: gcc -O2 -S -o fptest.S fptest.cpp main: .LFB3: pushl %ebp .LCFI0: fld1 movl %esp, %ebp .LCFI1: subl $24, %esp .LCFI2: andl $-16, %esp subl $16, %esp cmpl $1072693248, -4(%ebp) fstpl -8(%ebp) jne .L4 movl -8(%ebp), %eax testl %eax, %eax jne .L4 leave xorl %eax, %eax ret .p2align 4,,7 .L4: movl $.LC2, (%esp) movl $_ZZ6DoTestvE19__PRETTY_FUNCTION__, %ecx movl $12, %edx movl %ecx, 12(%esp) movl $.LC1, %eax movl %edx, 8(%esp) movl %eax, 4(%esp) call __assert_fail Specifying volatile for all the local variables fixes it. -- Summary: Optimizer problem with aliasing floating point variable Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bobm75 at gmail dot com CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20269