Subject: toolchain/16678: gcc -O2 (-fgcse) generates wrong code by incorrect reordering
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 05/06/2002 04:19:42
>Number: 16678
>Category: toolchain
>Synopsis: gcc -O2 (-fgcse) generates wrong code by incorrect reordering
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: toolchain-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun May 05 12:20:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Izumi Tsutsui
>Release: NetBSD 1.5ZC 20020505
>Organization:
>Environment:
System: NetBSD/macppc on Apus2000/200
Architecture: powerpc
Machine: macppc
>Description:
sys/arch/macppc/dev/adb_direct.c:adb_read_date_time() returns
wrong date on cuda based macppc machines after powerpc ports
has switched to new toolchains.
The problem seems caused by wrong reordering on gcc optimization,
since kernels compiled with gcc -O, or gcc -O2 -fno-gcse work fine.
>How-To-Repeat:
make syssrc/sys/arch/macppc/dev/adb_direct.c rev 1.23 with gcc -O2.
source:
---
adb_read_date_time(unsigned long *time)
{
u_char output[ADB_MAX_MSG_LENGTH];
int result;
volatile int flag = 0;
u_long r1, r2, r3;
switch (adbHardware) {
[..snip..]
case ADB_HW_CUDA:
output[0] = 0x02; /* 2 byte message */
output[1] = 0x01; /* to pram/rtc device */
output[2] = 0x03; /* read date/time */
result = send_adb_cuda((u_char *)output, (u_char *)output,
(void *)adb_op_comprout, (void *)&flag, (int)0);
if (result != 0) /* exit if not sent */
return -1;
while (0 == flag) /* wait for result */
;
memcpy(time, output + 1, 4);
return 0;
---
Note flag and output[] will be updated in the interrupt handler,
and it does not help to mark output[] volatile.
generated asm by "gcc -O1":
---
1d60: 2c 03 00 00 cmpwi r3,0
1d64: 40 82 00 20 bne 1d84 <adb_read_date_time+0x108>
if (result != 0)
return -1;
1d68: 80 01 00 18 lwz r0,24(r1)
1d6c: 2c 00 00 00 cmpwi r0,0
1d70: 41 82 ff f8 beq 1d68 <adb_read_date_time+0xec>
while (0 == flag)
;
1d74: 80 01 00 09 lwz r0,9(r1)
1d78: 90 1f 00 00 stw r0,0(r31)
memcpy(time, output + 1, 4)
1d7c: 38 60 00 00 li r3,0
1d80: 48 00 00 08 b 1d88 <adb_read_date_time+0x10c>
return 0;
---
generated asm code by "gcc -O2":
---
1d10: 2c 03 00 00 cmpwi r3,0
1d14: 40 82 00 20 bne 1d34 <adb_read_date_time+0x10c>
if (result != 0)
return -1;
1d18: 81 21 00 09 lwz r9,9(r1)
XXX first half of "memcpy(time, output + 1, 4)" XXX
1d1c: 80 01 00 18 lwz r0,24(r1)
1d20: 2c 00 00 00 cmpwi r0,0
1d24: 41 82 ff f8 beq 1d1c <adb_read_date_time+0xf4>
while (0 == flag)
;
1d28: 91 3f 00 00 stw r9,0(r31)
XXX rest of "memcpy(time, output + 1, 4)" XXX
1d2c: 38 60 00 00 li r3,0
1d30: 48 00 00 08 b 1d38 <adb_read_date_time+0x110>
return 0;
---
generated asm code by "gcc -O2 -fno-gcse":
---
1cfc: 2c 03 00 00 cmpwi r3,0
1d00: 40 82 00 20 bne 1d20 <adb_read_date_time+0x108>
if (result != 0)
return -1;
1d04: 80 01 00 18 lwz r0,24(r1)
1d08: 2c 00 00 00 cmpwi r0,0
1d0c: 41 82 ff f8 beq 1d04 <adb_read_date_time+0xec>
while (0 == flag)
;
1d10: 80 01 00 09 lwz r0,9(r1)
1d14: 38 60 00 00 li r3,0
1d18: 90 1f 00 00 stw r0,0(r31)
1d1c: 48 00 00 08 b 1d24 <adb_read_date_time+0x10c>
memcpy(time, output + 1, 4)
return 0;
---
gcc version is:
% gcc -v
Using builtin specs.
gcc version 2.95.3 20010315 (release) (NetBSD nb2)
>Fix:
Workaround is to add a null asm statement to avoid wrong reordering
(which was done in rev 1.24), or to use "gcc -O2 -fno-gcse" to disable
GCSE optimization.
---
>Release-Note:
>Audit-Trail:
>Unformatted: