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: