PR102024 - IBM Z: Add psabi diagnostics
authorAndreas Krebbel <krebbel@linux.ibm.com>
Wed, 27 Apr 2022 07:20:41 +0000 (09:20 +0200)
committerAndreas Krebbel <krebbel@linux.ibm.com>
Wed, 27 Apr 2022 07:22:46 +0000 (09:22 +0200)
commitbc79f0d9048375e402497d5f2ef457c9500310e4
treecea01c4ed9ce8c0e2116e677cfc23ff993c4ec08
parent9715f10c0651c9549b479b69d67be50ac4bd98a6
PR102024 - IBM Z: Add psabi diagnostics

For IBM Z in particular there is a problem with structs like:

struct A { float a; int :0; };

Our ABI document allows passing a struct in an FPR only if it has
exactly one member. On the other hand it says that structs of 1,2,4,8
bytes are passed in a GPR. So this struct is expected to be passed in
a GPR. Since we don't return structs in registers (regardless of the
number of members) it is always returned in memory.

Situation is as follows:

All compiler versions tested return it in memory - as expected.

gcc 11, gcc 12, g++ 12, and clang 13 pass it in a GPR - as expected.

g++ 11 as well as clang++ 13 pass in an FPR

For IBM Z we stick to the current GCC 12 behavior, i.e. zero-width
bitfields are NOT ignored.  A struct as above will be passed in a
GPR. Rational behind this is that not affecting the C ABI is more
important here.

A patch for clang is in progress: https://reviews.llvm.org/D122388

In addition to the usual regression test I ran the compat and
struct-layout-1 testsuites comparing the compiler before and after the
patch.

gcc/ChangeLog:
PR target/102024
* config/s390/s390-protos.h (s390_function_arg_vector): Remove
prototype.
* config/s390/s390.cc (s390_single_field_struct_p): New function.
(s390_function_arg_vector): Invoke s390_single_field_struct_p.
(s390_function_arg_float): Likewise.

gcc/testsuite/ChangeLog:
PR target/102024
* g++.target/s390/pr102024-1.C: New test.
* g++.target/s390/pr102024-2.C: New test.
* g++.target/s390/pr102024-3.C: New test.
* g++.target/s390/pr102024-4.C: New test.
* g++.target/s390/pr102024-5.C: New test.
* g++.target/s390/pr102024-6.C: New test.
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.cc
gcc/testsuite/g++.target/s390/pr102024-1.C [new file with mode: 0644]
gcc/testsuite/g++.target/s390/pr102024-2.C [new file with mode: 0644]
gcc/testsuite/g++.target/s390/pr102024-3.C [new file with mode: 0644]
gcc/testsuite/g++.target/s390/pr102024-4.C [new file with mode: 0644]
gcc/testsuite/g++.target/s390/pr102024-5.C [new file with mode: 0644]
gcc/testsuite/g++.target/s390/pr102024-6.C [new file with mode: 0644]