This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
optimization/8746: gcc-3 miscompiles Linux kernel ppa driver on x86
- From: chaus at rz dot uni-potsdam dot de
- To: gcc-gnats at gcc dot gnu dot org
- Date: 28 Nov 2002 16:17:08 -0000
- Subject: optimization/8746: gcc-3 miscompiles Linux kernel ppa driver on x86
- Reply-to: chaus at rz dot uni-potsdam dot de
>Number: 8746
>Category: optimization
>Synopsis: gcc-3 miscompiles Linux kernel ppa driver on x86
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Thu Nov 28 08:26:06 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Carsten Haustein
>Release: gcc releases since 3.1.1 (at least)
>Organization:
>Environment:
i586-linux-gnu; kernel 2.4.19-SMP
>Description:
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).
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: