Bug 17581 - [3.4 Regression] Long long arithmetic fails inside a switch/case statement when compiled with -O2
Summary: [3.4 Regression] Long long arithmetic fails inside a switch/case statement wh...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 3.4.3
Assignee: Not yet assigned to anyone
URL:
Keywords: patch, wrong-code
: 18084 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-09-21 08:45 UTC by Avner Lottem
Modified: 2004-10-30 23:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.0.0
Known to fail: 3.4.0
Last reconfirmed: 2004-09-21 13:03:42


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Avner Lottem 2004-09-21 08:45:29 UTC
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
Comment 1 Andreas Schwab 2004-09-21 08:53:46 UTC
Note that the correct printf format for long long is "%llx", not "%x". 
Comment 2 Avner Lottem 2004-09-21 08:56:13 UTC
Oooops, right.  Thanks.
But the bug still holds, even with %llx.
Comment 3 Avner Lottem 2004-09-21 12:22:46 UTC
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.
Comment 4 Andrew Pinski 2004-09-21 13:03:41 UTC
Confirmed with the last example in 3.4.0.
Comment 5 Andrew Pinski 2004-10-29 02:12:14 UTC
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-10/msg02573.html>.
Comment 6 GCC Commits 2004-10-30 00:57:04 UTC
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

Comment 7 GCC Commits 2004-10-30 18:03:04 UTC
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

Comment 8 Andrew Pinski 2004-10-30 18:12:08 UTC
Fixed.
Comment 9 Andrew Pinski 2004-10-30 23:06:26 UTC
*** Bug 18084 has been marked as a duplicate of this bug. ***