Skip to content

Passing long double args on 32-bit SPARC violates ABI #41838

Open
@rorth

Description

Bugzilla Link 42493
Version trunk
OS Solaris
CC @efriedma-quic

Extended Description

I'm current working to fix the remaining compiler-rt testsuite bugs on SPARC
(https://reviews.llvm.org/D40900). One of the failures is

Builtins-sparc-sunos :: divtc3_test.c
Builtins-sparcv9-sunos :: divtc3_test.c

While the sparcv9 failure is different, the sparc one boils down to incorrectly
passing long double arguments. Consider the following testcase:

$ cat caller.c
extern void callee (long double);

int
main (void)
{
long double ld = 1.0;

callee (ld);
return 0;
}
$ cat callee.c
extern void abort (void);

void
callee (long double ld)
{
if (ld != 1.0)
abort ();
}
$ clang -m32 -c caller.c -o caller.clang.o
$ clang -m32 -c callee.c -o callee.clang.o
$ gcc -m32 -c caller.c -o caller.gcc.o
$ gcc -m32 -c callee.c -o callee.gcc.o
$ gcc -m32 -o clang-gcc caller.clang.o callee.gcc.o
$ ./clang-gcc
Segmentation Fault (core dumped)
$ gcc -m32 -o gcc-clang caller.gcc.o callee.clang.o
$ ./gcc-clang
Abort (core dumped)

The SPARC psABI, p.3-15 (Structure, Union, and Quad-Precision Arguments)
requires long double args to be passed by reference, while clang passes
them by value (as is correct for SPARCv9).

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions