I have a program that produces the wrong result when using -O to compile. My system is the latest fedora. "uname -a" output is
Linux pluto 4.15.14-300.fc27.x86_64 #1 SMP Thu Mar 29 16:13:44 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
"g++ -v" output is
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=
http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
The original program is big, but I have reduced the source code to the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include <cstdio>
namespace {
int p[48], v;
}
int main() {
p[32] = 1;
for (int i = 48; i--;) {
if (p[i]) {
printf("diff at %d\n", i);
if (i > 39 || (i > 7 && (i & 7) > 2)) break;
if (i < 8) {
v = 1;
} else if (!(i & 1)) {
v = 2;
} else {
v = 3;
}
}
}
printf("v = %d\n", v);
}
|
p is static so is init to all 0, but p[32] is set to 1. Inside non-zero test where i is 32, the first and second if should test to false, but the else if should be true, so the v should be set to 2. The program runs correctly when compiled with "g++ -Wall test.cc", but when adding either -O, -O2, or -O3, then v is set to 3. Can anyone spot any error in the code? Or is there a gcc bug here?