https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77436
Bug ID: 77436 Summary: Incorrect constant result for summing loop inserted Product: gcc Version: 6.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: gcc-bugzilla at lucaswerkmeister dot de Target Milestone: --- Created attachment 39529 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39529&action=edit Preprocessed version of a small C program that sums up all integers from -(INT_MAX-1) to INT_MAX-1 (including both limits). The attached program computes the sum of all integers from -(INT_MAX-1) and INT_MAX-1. Since the lower limit is the additive inverse of the upper limit, all summands must cancel each other out and the result must be zero (this is still true with overflow). When compiled with -O0, that result is indeed printed. With -O1 and -O2, gcc optimizes the constant calculation and fills in the printf() call with the known result (though the loop is only removed on -O2); however, the inserted result is incorrect: instead of 0x00000000, it is 0x80000000 – the highest bit has been flipped. The bug appears to depend on the width of the summation window. Starting at INT_MIN + 32768 + 8192 + 4096 + 1024 + 256 + 2 and summing up to INT_MAX - 1 still exhibits the same bug; starting one later (+ 1) no longer does. Subtracting the same constant value from start and end does not change the result (provided the “shift” doesn’t cause overflow at the start). Output of gcc -v -save-temps -O1 gcc-bug.c: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc-multilib/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release Thread model: posix gcc version 6.1.1 20160802 (GCC) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/cc1 -E -quiet -v gcc-bug.c -mtune=generic -march=x86-64 -O1 -fpch-preprocess -o gcc-bug.i ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../x86_64-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/include /usr/local/include /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/cc1 -fpreprocessed gcc-bug.i -quiet -dumpbase gcc-bug.c -mtune=generic -march=x86-64 -auxbase gcc-bug -O1 -version -o gcc-bug.s GNU C11 (GCC) version 6.1.1 20160802 (x86_64-pc-linux-gnu) compiled by GNU C version 6.1.1 20160802, GMP version 6.1.1, MPFR version 3.1.4-p1, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C11 (GCC) version 6.1.1 20160802 (x86_64-pc-linux-gnu) compiled by GNU C version 6.1.1 20160802, GMP version 6.1.1, MPFR version 3.1.4-p1, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 0344da0e3652e90e95fdb0223debdba9 COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-mtune=generic' '-march=x86-64' as -v --64 -o gcc-bug.o gcc-bug.s GNU assembler version 2.27 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.27 COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/lto-wrapper -plugin-opt=-fresolution=gcc-bug.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../.. gcc-bug.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crtn.o COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-mtune=generic' '-march=x86-64' I am running on Arch Linux, which ships gcc 6.1.1, release 5. Unfortunately, I have not been able to test this on gcc 6.2.0, so this might be fixed already; if that is the case, I’m sorry. (Debian’s 4.9.2-10 does not apply this optimization at all and prints the correct result.)