This bug affects the ppa driver (used by Iomega Zip drive connected to parallel port) taken from Linux kernel 2.4.19 source tree (drivers/scsi/ppa.c) when compiled with optimization turned on. I can reproduce it with gcc versions 3.1.1, 3.2, 3.2.1 but not with version 2.95.3. I haven't tested other versions of gcc but I think any version newer than 2.95.3 is affected. Close to the end of function int ppa_completion(...) there is a check whether the zip drive is ready. This test fails always due to wrong code generation and causes the driver to spend a lot of time on waiting. Transfer rate drops down from >450 kB/s to ~50 kB/s. The affected code is: ... unsigned char r; ... /* Now check to see if the drive is ready to communicate */ r = (r_str(ppb) & 0xf0); /* If not, drop back down to the scheduler and wait a timer tick */ if (!(r & 0x80)) return 0; ... What actually happens is: 1.) Read state byte from parport. 2.) Mask out lower nibble. 3.) Check the MSB (ready bit) of the byte read. gcc translates this to: 1.) Read state byte into register al (8 bit). 2.) Apply bit-mask to register eax (32 bit, supersetting al). 3.) Check whether the processors sign-flag (which corresponds to the MSB) is set. Code generation for (r & 0x80) is omitted. But since 0xf0 is applied to eax the sign-flag depends on bit 31 (which will always be cleared) rather than on bit 7 (the bit of interest). Release: gcc releases since 3.1.1 (at least) Environment: i586-linux-gnu; kernel 2.4.19-SMP
State-Changed-From-To: open->feedback State-Changed-Why: Could you provide us with a minimal and compilable testcase? See http://gcc.gnu.org/bugs.html
From: Carsten Haustein <chaus@rz.uni-potsdam.de> To: <ebotcazou@gcc.gnu.org>, <chaus@rz.uni-potsdam.de>, <gcc-bugs@gcc.gnu.org>, <gcc-prs@gcc.gnu.org>, <nobody@gcc.gnu.org>, <gcc-gnats@gcc.gnu.org> Cc: Subject: Re: optimization/8746: gcc-3 miscompiles Linux kernel ppa driver on x86 Date: Fri, 28 Feb 2003 17:26:26 +0100 (MET) This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime@docserver.cac.washington.edu for more info. ---559023410-1804928587-1046449586=:26411 Content-Type: TEXT/PLAIN; charset=US-ASCII Compile the testcase with: gcc -O -march=i{345}86 -o check check.c Run the test with: check <number>, where <number> is an integer between 0 and 255 (without angle brackets). The program will "prove" that any number in this range is less than 128, which is obviously wrong. Some notes: 1. It is important to select one of the shown -march arguments. Only code generated for i{345}86 and K6 family is affected. Code generated for i686 family, Pentium 4 and Athlon family works fine. This code uses the al register for applying the bit-mask instead of eax and a different representation of the immediate 0xf0. 2. There must not be a statement between the "and" operation and the if-expression. Otherwise code is generated for both the "and" operation and for testing the MSB, since the extra statement may affect the cpu-flags. Such code works fine. 3. The value assigned to r must be examined in one or the other way. Otherwise code for the "and" operation will be omitted and code for testing the MSB will be generated, which leads to working code too. -- Carsten Haustein ---559023410-1804928587-1046449586=:26411 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="check.c" Content-Transfer-Encoding: BASE64 Content-ID: <Pine.GSO.4.30.0302281726260.26411@persius.rz.uni-potsdam.de> Content-Description: Content-Disposition: attachment; filename="check.c" I2luY2x1ZGUgPHN0ZGlvLmg+DQppbnQgbWFpbihpbnQgYXJnYywgY2hhciAq YXJndltdKSB7DQogICB1bnNpZ25lZCBjaGFyIHIgPSAoYXRvaShhcmd2WzFd KSkgJiAweGYwOw0KICAgaWYgKCEociAmIDB4ODApKSBwcmludGYoIiV1IDwg MTI4XG4iLCByKTsNCiAgICAgICAgICAgICAgIGVsc2UgcHJpbnRmKCIldSA+ PSAxMjhcbiIsIHIpOw0KICAgcmV0dXJuIDA7DQp9DQo= ---559023410-1804928587-1046449586=:26411--
State-Changed-From-To: feedback->analyzed State-Changed-Why: Confirmed on 3.2 branch. 3.3 and mainline are not affected.
Responsible-Changed-From-To: unassigned->ebotcazou Responsible-Changed-Why: Investigating.
From: ebotcazou@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/8746 Date: 19 Mar 2003 19:54:27 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_2-branch Changes by: ebotcazou@gcc.gnu.org 2003-03-19 19:54:27 Modified files: gcc : ChangeLog gcc/config/i386: i386.md gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: i386-signbit-1.c Log message: PR optimization/8746 Backport from mainline: Thu Jun 6 23:14:46 CEST 2002 Jan Hubicka<jh@suse.cz> * i386.md (and promoting splitters): Disable QI to SImode promoting when doing so changes immediate to be 32bit. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.268&r2=1.13152.2.657.2.269 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.md.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.339.2.13.2.8&r2=1.339.2.13.2.9 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1672.2.166.2.113&r2=1.1672.2.166.2.114 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.2.1
State-Changed-From-To: analyzed->closed State-Changed-Why: Fixed. See http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01726.html
From: ebotcazou@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/8746 Date: 25 Mar 2003 10:18:48 -0000 CVSROOT: /cvs/gcc Module name: gcc Changes by: ebotcazou@gcc.gnu.org 2003-03-25 10:18:47 Modified files: gcc : ChangeLog gcc/config/i386: i386.md gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: i386-signbit-1.c i386-signbit-2.c i386-signbit-3.c Log message: PR optimization/8746 * config/i386/i386.md (and promoting splitters): Disable HImode to SImode promoting when the sign bit matters and is not preserved, or when TARGET_FAST_PREFIX is true. Disable promoting when optimizing for size. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.17209&r2=1.17210 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.md.diff?cvsroot=gcc&r1=1.451&r2=1.452 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2538&r2=1.2539 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-1.c.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-2.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-3.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
From: ebotcazou@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/8746 Date: 25 Mar 2003 10:30:30 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: ebotcazou@gcc.gnu.org 2003-03-25 10:30:30 Modified files: gcc : ChangeLog gcc/config/i386: i386.md gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: i386-signbit-1.c i386-signbit-2.c i386-signbit-3.c Log message: PR optimization/8746 * config/i386/i386.md (and promoting splitters): Disable HImode to SImode promoting when the sign bit matters and is not preserved, or when TARGET_FAST_PREFIX is true. Disable promoting when optimizing for size. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.359&r2=1.16114.2.360 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.md.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.404.2.12&r2=1.404.2.13 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.2261.2.119&r2=1.2261.2.120 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.2.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-2.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-3.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1
From: ebotcazou@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/8746 Date: 25 Mar 2003 10:42:14 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_2-branch Changes by: ebotcazou@gcc.gnu.org 2003-03-25 10:42:14 Modified files: gcc : ChangeLog gcc/config/i386: i386.md gcc/testsuite : ChangeLog gcc/testsuite/gcc.dg: i386-signbit-1.c Added files: gcc/testsuite/gcc.dg: i386-signbit-2.c i386-signbit-3.c Log message: PR optimization/8746 * config/i386/i386.md (and promoting splitters): Disable HImode to SImode promoting when the sign bit matters and is not preserved. Disable promoting when optimizing for size. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.277&r2=1.13152.2.657.2.278 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.md.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.339.2.13.2.9&r2=1.339.2.13.2.10 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1672.2.166.2.116&r2=1.1672.2.166.2.117 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-2.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-3.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-signbit-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1.2.1&r2=1.1.2.2