Inside a case statement, the following code gives an incorrect result: case 21: ctl_bitvec |= 1; ctl_bitvec |= 2; ctl_bitvec |= 8; break; By the end of the calculation, ctl_bitvec contains 8 instead of 0xb. This is a complete listing that exhibits the problem: --------------------------------------- cut here -------------------------- #include <stdio.h> void f(long unsigned *x1) { int stack_ctl; unsigned long long ctl_bitvec; stack_ctl = *x1; ctl_bitvec = 0; switch(stack_ctl) { case 8: ctl_bitvec |= 1; ctl_bitvec |= 2; break; case 12: ctl_bitvec |= 1; ctl_bitvec |= 2; ctl_bitvec |= 0x10; break; case 15: ctl_bitvec |= 2; ctl_bitvec |= 0x10; break; case 16: ctl_bitvec |= 1; ctl_bitvec |= 0x20; ctl_bitvec |= 8; break; case 20: ctl_bitvec |= 1; ctl_bitvec |= 8; break; case 21: ctl_bitvec |= 1; ctl_bitvec |= 2; ctl_bitvec |= 8; break; case 22: ctl_bitvec |= 8; break; case 30: ctl_bitvec |= 0x40; break; default: break; } printf("%x\n", ctl_bitvec); (*x1) |= ((ctl_bitvec & 7) << 0); } main() { long unsigned i = 21; f(&i); } --------------------------------------- cut here -------------------------- This is the a sample compile and run: % make && make run /usr/intel/pkgs/gcc/3.4/bin/g++ -O2 -march=pentium3 test.c -o test_o2 /usr/intel/pkgs/gcc/3.4/bin/g++ -O -march=pentium3 test.c -o test_o ./test_o2 8 ./test_o b % /usr/intel/pkgs/gcc/3.4/bin/g++ -v Reading specs from /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/specs Configured with: ../gcc-3.4.0/configure --prefix=/usr/intel/pkgs/gcc/3.4 --with- gnu-as --with-as=/usr/intel/pkgs/gcc/3.4/bin/gas --with-gnu-ld --with- ld=/usr/intel/pkgs/gcc/3.4/bin/gld --enable-shared Thread model: posix gcc version 3.4.0 % /usr/intel/pkgs/gcc/3.4/bin/g++ -v -save-temps -O2 -march=pentium3 test.c -o test_o2 Reading specs from /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/specs Configured with: ../gcc-3.4.0/configure --prefix=/usr/intel/pkgs/gcc/3.4 --with- gnu-as --with-as=/usr/intel/pkgs/gcc/3.4/bin/gas --with-gnu-ld --with- ld=/usr/intel/pkgs/gcc/3.4/bin/gld --enable-shared Thread model: posix gcc version 3.4.0 /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../libexec/gcc/i686-pc-linux- gnu/3.4.0/cc1plus -E -quiet -v - iprefix /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc- linux-gnu/3.4.0/ -D_GNU_SOURCE test.c -march=pentium3 -O2 -o test.ii ignoring nonexistent directory "/a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc- linux-gnu/3.4.0/../../../../i686-pc-linux-gnu/include" ignoring duplicate directory "/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0" ignoring duplicate directory "/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0/i686-pc-linux-gnu" ignoring duplicate directory "/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0/backward" ignoring duplicate directory "/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/include" ignoring nonexistent directory "/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0 /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0/i686-pc-linux-gnu /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../include/c++/3.4.0/backward /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/include /usr/local/include /usr/intel/pkgs/gcc/3.4/include /usr/include End of search list. /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../libexec/gcc/i686-pc-linux- gnu/3.4.0/cc1plus -fpreprocessed test.ii -quiet -dumpbase test.c - march=pentium3 -auxbase test -O2 -version -o test.s GNU C++ version 3.4.0 (i686-pc-linux-gnu) compiled by GNU C version 3.4.0. GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128512 /usr/intel/pkgs/gcc/3.4/bin/gas -V -Qy -o test.o test.s GNU assembler version 2.14 (i686-pc-linux-gnu) using BFD version 2.14 20030612 /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../libexec/gcc/i686-pc-linux- gnu/3.4.0/collect2 -rpath=/usr/intel/pkgs/gcc/3.4/lib --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test_o2 /usr/lib/crt1.o /usr/lib/crti.o /a/nfs/iil/itools/i386_linux24/pkgs/gcc/ 3.4/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/crtbegin.o - L/a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0 -L/a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc - L/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux-gnu/3.4.0 - L/a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/../../../../i686-pc-linux-gnu/lib - L/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../i686-pc- linux-gnu/lib -L/a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686- pc-linux-gnu/3.4.0/../../.. -L/usr/intel/pkgs/gcc/3.4/lib/gcc/i686-pc-linux- gnu/3.4.0/../../.. test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s - lgcc /a/nfs/iil/itools/i386_linux24/pkgs/gcc/3.4/bin/../lib/gcc/i686-pc-linux- gnu/3.4.0/crtend.o /usr/lib/crtn.o
Note that the correct printf format for long long is "%llx", not "%x".
Oooops, right. Thanks. But the bug still holds, even with %llx.
The test case was further minimized to the following: ------------------------ cut here ------------------------ #include <stdio.h> int f(long unsigned x1) { unsigned long long ctl_bitvec = 0; switch(x1) { case 21: ctl_bitvec |= 1; ctl_bitvec |= 2; ctl_bitvec |= 8; break; default: break; } printf("%llx\n", ctl_bitvec); return ctl_bitvec; } main() { f(21); } ------------------------ cut here ------------------------ And running: % make && make run /usr/intel/pkgs/gcc/3.4/bin/g++ -O2 test.c -o test_o2 /usr/intel/pkgs/gcc/3.4/bin/g++ -O test.c -o test_o ./test_o2 8 ./test_o b It does not fail with gcc 3.3.2. unfortunately, I was not able to test with versions later than 3.4.
Confirmed with the last example in 3.4.0.
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-10/msg02573.html>.
Subject: Bug 17581 CVSROOT: /cvs/gcc Module name: gcc Changes by: sayle@gcc.gnu.org 2004-10-30 00:56:59 Modified files: gcc : ChangeLog cselib.c gcse.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: pr17581-1.c Log message: PR rtl-optimization/17581 * cselib.c (cselib_process_insn): The last instruction of a libcall block, with the REG_RETVAL note, should be considered in the libcall. * gcse.c (do_local_cprop): Allow constants to be propagated outside of libcall blocks. (adjust_libcall_notes): Use simplify_replace_rtx instead of replace_rtx to avoid creating invalid RTL in REG_RETVAL notes. * gcc.dg/pr17581-1.c: New test case. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6100&r2=2.6101 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cselib.c.diff?cvsroot=gcc&r1=1.52&r2=1.53 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/gcse.c.diff?cvsroot=gcc&r1=1.320&r2=1.321 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4519&r2=1.4520 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr17581-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Subject: Bug 17581 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: sayle@gcc.gnu.org 2004-10-30 18:02:59 Modified files: gcc : ChangeLog cselib.c gcse.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: pr17581-1.c Log message: PR rtl-optimization/17581 * cselib.c (cselib_process_insn): The last instruction of a libcall block, with the REG_RETVAL note, should be considered in the libcall. * gcse.c (do_local_cprop): Allow constants to be propagated outside of libcall blocks. (adjust_libcall_notes): Use simplify_replace_rtx instead of replace_rtx to avoid creating invalid RTL in REG_RETVAL notes. * gcc.dg/pr17581-1.c: New test case. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.677&r2=2.2326.2.678 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cselib.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.32.4.6&r2=1.32.4.7 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/gcse.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.288.2.8&r2=1.288.2.9 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.300&r2=1.3389.2.301 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr17581-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.2.2.1
Fixed.
*** Bug 18084 has been marked as a duplicate of this bug. ***