Bug 8746 - [3.2 regression] gcc miscompiles Linux kernel ppa driver on x86
Summary: [3.2 regression] gcc miscompiles Linux kernel ppa driver on x86
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.1.1
: P3 normal
Target Milestone: ---
Assignee: Eric Botcazou
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2002-11-28 08:26 UTC by chaus
Modified: 2003-07-25 17:33 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
pr8746.c (221 bytes, text/x-c )
2003-05-21 15:17 UTC, chaus
Details

Note You need to log in before you can comment on or make changes to this bug.
Description chaus 2002-11-28 08:26:06 UTC
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
Comment 1 Eric Botcazou 2003-02-18 13:51:53 UTC
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
Comment 2 chaus 2003-02-28 17:26:26 UTC
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--
Comment 3 Eric Botcazou 2003-03-04 09:53:19 UTC
State-Changed-From-To: feedback->analyzed
State-Changed-Why: Confirmed on 3.2 branch. 3.3 and mainline are not affected.
Comment 4 Eric Botcazou 2003-03-19 08:51:31 UTC
Responsible-Changed-From-To: unassigned->ebotcazou
Responsible-Changed-Why: Investigating.
Comment 5 Eric Botcazou 2003-03-19 19:54:27 UTC
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
 
Comment 6 Eric Botcazou 2003-03-19 20:04:13 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed. See http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01726.html
Comment 7 Eric Botcazou 2003-03-25 10:18:48 UTC
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
 

Comment 8 Eric Botcazou 2003-03-25 10:30:30 UTC
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
 

Comment 9 Eric Botcazou 2003-03-25 10:42:14 UTC
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