From: Mark Mentovai <mark@moxienet.com>
To: gcc-gnats@gcc.gnu.org
Cc:
Subject: Re: optimization/9414: Bad code with -mcpu=ultrasparc -O2, stx used where st was needed
Date: Thu, 23 Jan 2003 00:18:45 -0500
This is a regression, the output from 3.0.4 looks clean. The bug is
present in 3.1, 3.1.1, and 3.2.
Mark
Category: optimization
Optimizing at level 2 or higher while scheduling for the UltraSPARC CPU results in misscheduled instructions. The attached file, resolver.i, is preprocessed source generated from bind-9.2.1/lib/dns/resolver.c in the BIND 9.2.1 distribution available from ftp://ftp.isc.org/isc/bind9/9.2.1/bind-9.2.1.tar.gz. The misscheduled instructions are compiled from lines 4692 and 4693 of this file.
bind-9.2.1/lib/dns/resolver.c:4690: INSIST(res->priming);
bind-9.2.1/lib/dns/resolver.c:4691: res->priming = ISC_FALSE;
bind-9.2.1/lib/dns/resolver.c:4692: fetch = res->primefetch;
bind-9.2.1/lib/dns/resolver.c:4693: res->primefetch = NULL;
bind-9.2.1/lib/dns/resolver.c:4694:
bind-9.2.1/lib/dns/resolver.c:4695: UNLOCK(&res->lock);
When this source is compiled with -mcpu=ultrasparc -O2, the scheduling is incorrect.
gcc -S -O2 -g3 -mcpu=ultrasparc -Wall resolver.i -o resolver.s
resolver.s:12558: .stabn 68,0,4693,.LLM1694-prime_done
resolver.s:12559:.LLM1694:
resolver.s:12560:.LL1687:
resolver.s:12561: stx %g0, [%l0+104]
resolver.s:12562: .stabn 68,0,4692,.LLM1695-prime_done
resolver.s:12563:.LLM1695:
resolver.s:12564: ld [%l0+108], %o1
By the time we reach .LLM1695, [%lo+108] has been zeroed out by the preceding stx instruction, which unfortunately stored an extended word and trashed the data we were interested in. A word-store would have been fine. Instead (stepping back up a level), fetch is going to be zero and not the former value of res->primefetch. Oops.
In this case, the software will shortly detect the error and terminate, spewing this:
critical: resolver.c:5104: REQUIRE((((fetch) != 0) && (((const isc__magic_t *)(fetch))->magic == ((('F') << 24 | ('t') << 16 | ('c') << 8 | ('h')))))) failed
This will happen the first time the nameserver receives a query. I mention this only so that the resoluton can get the proper QA treatment once in place.
Workaround: use -O1 or -mcpu=v9.
Release:
3.2
Environment:
System: SunOS s7 5.8 Generic_108528-15 sun4u sparc SUNW,UltraAX-i2
Architecture: sun4
host: sparc-sun-solaris2.8
build: sparc-sun-solaris2.8
target: sparc-sun-solaris2.8
configured with: ../gcc-3.2/configure --enable-shared --with-gnu-as --with-gnu-ld --enable-threads --with-cpu=ultrasparc --enable-libgcj --with-system-zlib
How-To-Repeat:
The easy way:
> gcc -S -O2 -g3 -mcpu=ultrasparc -Wall resolver.i -o resolver.s
see resolver.s:12558 and on
The painful way:
(obtain bind-9.2.1.tar.gz, unpack it, and in its root directory:)
> env CC=gcc CFLAGS="-O2 -g3 -mcpu=ultrasparc" sh configure --with-openssl=/usr/local/ssl --with-libtool
> gcc -E -g3 -I. -Ilib/dns/include -Ilib/dns/sec/dst/include -Ilib/isc -Ilib/isc/include -Ilib/isc/unix/include -Ilib/isc/pthreads/include -D_REENTRANT -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -c lib/dns/resolver.c -fPIC -DPIC -o resolver.i
> gcc -S -O2 -g3 -mcpu=ultrasparc -Wall resolver.i -o resolver.s
see resolver.s:12558 and on
The painful way, trying the software:
(obtain bind-9.2.1.tar.gz, unpack it, and in its root directory:)
> env CC=gcc CFLAGS="-O2 -g3 -mcpu=ultrasparc" sh configure --with-libtool
> make
> cat > named.conf << _EOF_
? options {
? listen-on port 5353 {127.0.0.1;};
? directory ".";
? pid-file "/tmp/named.pid";
? };
? _EOF_
> bin/named/named -c named.conf -g &
(This starts named with the bare-bones minimal configuration just created, without forking and doing the usual daemon thing, and with logging channeled to stderr.)
> bin/dig/dig -p 5353 gnu.org @127.0.0.1
(This will cause named to exit on an assertion failure.)
> bin/named/named -c named.conf -g
^C
(This will cause named to exit on another assertion failure that I haven't yet fully analyzed but am assuming has the same cause.)