This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

target/2062: -mcpu=ultrasparc (or -mv9) -O1 with long argument lists and doubles can produce bad code



>Number:         2062
>Category:       target
>Synopsis:       -mcpu=ultrasparc (or -mv9) -O1 with long argument lists and doubles can produce bad code
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 22 15:56:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Bill Clarke
>Release:        gcc version 2.95.2 19991024 (release)
>Organization:
>Environment:
SunOS kaffa.anu.edu.au 5.6 Generic_105181-17 sun4u sparc SUNW,Ultra-2
also on:
SunOS jokkmokk 5.8 Generic_108528-01 sun4u sparc SUNW,Ultra-1
>Description:
gcc -mcpu=ultrasparc -O1 (and -O2) for long parameter lists with double
args can produce poorly optimised code, indeed code which does not work on
Solaris (tested with 2.6 and 2.8: they generate a bus error):

this bug is like bugs 788 and 694 but i believe is more concrete
about the problem (694 occurs without optimisation though!). 

using gcc 2.95.2:
$ gcc --version
2.95.2
$ gcc -dumpmachine
sparc-sun-solaris2.6

see file bug.c

make and run it with:
$ make CC=gcc CFLAGS= bug
$ ./bug
calling bug 0
called bug 0!
$ ./bug 1
calling bug 1
called bug 1!
$

that's ok!

now try -O1:
rm bug
make CC=gcc CFLAGS=-O1 bug
./bug
./bug 1

that's ok too.

now try -mcpu=ultrasparc:
rm bug
make CC=gcc CFLAGS=-mcpu=ultrasparc bug
./bug
./bug 1

that's ok too!

now try -mcpu=ultrasparc -O1:
rm bug
make CC=gcc CFLAGS="-mcpu=ultrasparc -O1" bug
./bug
./bug 1

./bug gives me a bus error, on both solaris 2.6 and 2.8.  ./bug 1 is ok.

this is because -mcpu=ultrasparc -O1 produces "std %f#, [%sp + ...]" code
where the offset is word-aligned but not double-word-aligned.  i'm
presuming that the stack pointer is always double-word aligned, but i could
be wrong in this assumption.  

according to the UltraSPARC manual (p.249) this (an unaligned doubleword
stdf) will generate an STDF_mem_address_not_aligned trap, which ought to be
emulated by the operating system (Sparc V9 manual, page 226: "... in this
case, the trap handler software shall emulate the STDF instruction and
return.")  it seems that solaris does not emulate it!  i've attempted to
locate the trap handlers in the solaris source to no avail.  sparc-linux
seems to have a handler and the code works as is (tested only by copying
the object file to a sparc-linux machine and linking and running).

so we have a bug in solaris (how surprising! :-).

the following relies on my assumption that the stack pointer is always
doubleword aligned (according to the psABI p.3-12 that is the case).

this code should not be generated by the optimiser since it _knows_ that it
is unaligned and would generate a trap (on ultrasparc).  it's damn
inefficient to be producing traps, when it could be replaced with multiple
st's (which is what -O1 (without -mcpu=ultrasparc) does.

from SPARC-V9 manual, p226: "it is recommended that compilers issue sets of
single-precision stores only when they can determine that double- or
quadword operands are not properly aligned."  since we can determine that
they are or are not aligned in this case then gcc should follow that
advice.

note: "-mcpu=v9 -Wa,-xarch=v8plusa" (for solaris 2.6) produces similar
(but not the same) code that -mcpu=ultrasparc does.  the same behaviour
occurs.
>How-To-Repeat:
see description
>Fix:
-mcpu=ultrasparc and -mv9 with optimisation should not produce 
std's (ldd's) from (to) floating-point registers when it knows 
that they are word-aligned (required!) but not doubleword-aligned.

with the fact that solaris does not seem to handle LDDF/STDF_mem_address_not_aligned
exceptions properly, then perhaps gcc needs a special option to work around
that bug.  sparc-linux handles them okay.

workaround: this generally occurs with printf's in our programs.
workaround is to use shorter argument lists in the printfs (i.e.,
fully contained within registers)
>Release-Note:
>Audit-Trail:
>Unformatted:
 
----gnatsweb-attachment----
Content-Type: application/octet-stream; name="bug.c"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="bug.c"

I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCnZvaWQKY2FsbF9idWdfMChk
b3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUpIHsKICBwcmlu
dGYoImNhbGxlZCBidWcgMCFcbiIpOwp9Cgp2b2lkCmNhbGxfYnVnXzEoaW50IGEsIGRvdWJsZSBi
LCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlKSB7CiAgcHJpbnRmKCJjYWxsZWQgYnVnIDEh
XG4iKTsKfQoKdm9pZApidWcoaW50IGRvYnVnKSB7CiAgaW50IGEgPSByYW5kKCk7CiAgZG91Ymxl
IGIgPSAoZG91YmxlKXJhbmQoKTsKICBkb3VibGUgYyA9IChkb3VibGUpcmFuZCgpOwogIGRvdWJs
ZSBkID0gKGRvdWJsZSlyYW5kKCk7CiAgZG91YmxlIGUgPSAoZG91YmxlKXJhbmQoKTsKICBkb3Vi
bGUgZiA9IChkb3VibGUpcmFuZCgpOwoKICBpZiAoZG9idWcpCiAgICBjYWxsX2J1Z18xKGEsYixj
LGQsZSk7CiAgZWxzZQogICAgY2FsbF9idWdfMChiLGMsZCxlLGYpOwp9CgppbnQKbWFpbihpbnQg
YXJnYywgY2hhciogYXJndltdKSB7CiAgaWYgKGFyZ2MgPCAyKSB7CiAgICBwcmludGYoImNhbGxp
bmcgYnVnIDBcbiIpOwogICAgYnVnKDApOwogIH0KICBlbHNlIHsKICAgIHByaW50ZigiY2FsbGlu
ZyBidWcgMVxuIik7CiAgICBidWcoMSk7CiAgfQogIHJldHVybigwKTsKfQo=


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]