gcc with -O2 computes an expression incorrectly. gcc -O1 computes
it correctly. The core expression is the following function:
uint64 Function2(void)
{
uint64 value;
value = 0;
value |= 0x00000040;
value |= 0x8000000000000000ULL;
value |= 0x1000000000000000ULL;
if (gui) value = Function1(value);
return(value);
}
With -O2 the value is 0x1000000000000040; with -O1 the value is
0x9000000000000040 (as expected). Tests seem to suggest that the
function call (to Function1) is necessary (even tho Function1 simply
returns its value unchanged and gui is set to 0, so it isn't called).
Compiling with "gcc -O2 -g3 e.c -o e" produces an executable that prints
the incorrect value; "gcc -O1 -g3 e.c -o e" prints the correct answer.
The output of gcc -v -save-temps is
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)
/usr/libexec/gcc/i386-redhat-linux/3.4.2/cc1 -E -quiet -v -dD e.c
-fworking-directory -O2 -o e.i
ignoring nonexistent directory
"/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/3.4.2/include
/usr/include
End of search list.
/usr/libexec/gcc/i386-redhat-linux/3.4.2/cc1 -fpreprocessed e.i -quiet
-dumpbase e.c -auxbase e -g3 -O2 -version -o e.s
GNU C version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3) (i386-redhat-linux)
compiled by GNU C version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3).
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129215
as -V -Qy -o e.o e.s
GNU assembler version 2.15.92.0.2 (i386-redhat-linux) using BFD version
2.15.92.0.2 20040927
/usr/libexec/gcc/i386-redhat-linux/3.4.2/collect2 --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 -o e
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../crt1.o
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../crti.o
/usr/lib/gcc/i386-redhat-linux/3.4.2/crtbegin.o
-L/usr/lib/gcc/i386-redhat-linux/3.4.2 -L/usr/lib/gcc/i386-redhat-linux/3.4.2
-L/usr/lib/gcc/i386-redhat-linux/3.4.2/../../.. e.o -lgcc --as-needed -lgcc_s
--no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/i386-redhat-linux/3.4.2/crtend.o
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../crtn.o
Test program is:
#include <stdio.h>
typedef unsigned long long uint64;
int gui;
uint64 Function1(uint64 value)
{
return(value);
}
uint64 Function2(void)
{
uint64 value;
value = 0;
value |= 0x00000040;
value |= 0x8000000000000000ULL;
value |= 0x1000000000000000ULL;
if (gui) value = Function1(value);
return(value);
}
int main(int argc, char **argv)
{
unsigned long long int value = 0;
value = Function2();
fprintf(stdout,"0x%llX\n", value);
return(0);
}
--
Summary: Optimization computes wrong value for series of x = x |
constant;
Product: gcc
Version: 3.4.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: peterson at austin dot ibm dot com
GCC build triplet: x86/Linux
GCC host triplet: x86/Linux
GCC target triplet: x86/Linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24203