Ping.
Normally we shouldn't ping a patch after only a few days, but we're
running out of time to catch GCC 12 milestone. And once GCC 12 is
released the patch will become far more complicated for a psABI warning.
And please note that the ABI difference between GCC and G++ should be
considered a bug, and it has to be fixed anyway. If you don't like the
idea of this patch, please develop another solution and apply it *before
GCC 12*.
On Wed, 2022-04-20 at 14:23 +0800, Xi Ruoyao via Gcc-patches wrote:
> Currently, LoongArch ELF psABI is not clear on the handling of zero-
> sized fields in aggregates arguments or return values [1]. The behavior
> of GCC trunk is puzzling considering the following cases:
>
> struct test1
> {
> double a[0];
> float x;
> };
>
> struct test2
> {
> float a[0];
> float x;
> };
>
> GCC trunk passes test1::x via GPR, but test2::x via FPR. I believe no
> rational Homo Sapiens can understand (or even expect) this.
>
> And, to make things even worse, test1 behaves differently in C and C++.
> GCC trunk passes test1::x via GPR, but G++ trunk passes test1::x via
> FPR.
>
> I've write a paragraph about current GCC behavior for the psABI [2], but
> I think it's cleaner to just ignore all zero-sized fields in the ABI.
> This will require only a two-line change in GCC (this patch), and an
> one-line change in the ABI doc.
>
> If there is not any better idea I'd like to see this reviewed and
> applied ASAP. If we finally have to apply this patch after GCC 12
> release, we'll need to add a lot more boring code to emit a -Wpsabi
> inform [3]. That will be an unnecessary burden for both us, and the
> users using the compiler (as the compiler will spend CPU time only for
> checking if a warning should be informed).
>
> [1]:https://github.com/loongson/LoongArch-Documentation/issues/48
> [2]:https://github.com/loongson/LoongArch-Documentation/pull/49
> [3]:https://gcc.gnu.org/PR102024
>
> gcc/
>
> * config/loongarch/loongarch.cc
> (loongarch_flatten_aggregate_field): Ignore empty fields for
> RECORD_TYPE.
>
> gcc/testsuite/
>
> * gcc.target/loongarch/zero-size-field-pass.c: New test.
> * gcc.target/loongarch/zero-size-field-ret.c: New test.
> ---
> gcc/config/loongarch/loongarch.cc | 3 ++
> .../loongarch/zero-size-field-pass.c | 30 +++++++++++++++++++
> .../loongarch/zero-size-field-ret.c | 28 +++++++++++++++++
> 3 files changed, 61 insertions(+)
> create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
> create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
>
> diff --git a/gcc/config/loongarch/loongarch.cc
> b/gcc/config/loongarch/loongarch.cc
> index f22150a60cc..57e4d9f82ce 100644
> --- a/gcc/config/loongarch/loongarch.cc
> +++ b/gcc/config/loongarch/loongarch.cc
> @@ -326,6 +326,9 @@ loongarch_flatten_aggregate_field (const_tree type,
> for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
> if (TREE_CODE (f) == FIELD_DECL)
> {
> + if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f)))
> + continue;
> +
> if (!TYPE_P (TREE_TYPE (f)))
> return -1;
>
> diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
> b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
> new file mode 100644
> index 00000000000..999dc913a71
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
> @@ -0,0 +1,30 @@
> +/* Test that LoongArch backend ignores zero-sized fields of aggregates in
> + argument passing. */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */
> +/* { dg-final { scan-assembler "\\\$f1" } } */
> +
> +struct test
> +{
> + int empty1[0];
> + double empty2[0];
> + int : 0;
> + float x;
> + long empty3[0];
> + long : 0;
> + float y;
> + unsigned : 0;
> + char empty4[0];
> +};
> +
> +extern void callee (struct test);
> +
> +void
> +caller (void)
> +{
> + struct test test;
> + test.x = 114;
> + test.y = 514;
> + callee (test);
> +}
> diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
> b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
> new file mode 100644
> index 00000000000..40137d97555
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
> @@ -0,0 +1,28 @@
> +/* Test that LoongArch backend ignores zero-sized fields of aggregates in
> + returning. */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */
> +/* { dg-final { scan-assembler-not "\\\$r4" } } */
> +
> +struct test
> +{
> + int empty1[0];
> + double empty2[0];
> + int : 0;
> + float x;
> + long empty3[0];
> + long : 0;
> + float y;
> + unsigned : 0;
> + char empty4[0];
> +};
> +
> +extern struct test callee (void);
> +
> +float
> +caller (void)
> +{
> + struct test test = callee ();
> + return test.x + test.y;
> +}
--
Xi Ruoyao <[email protected]>
School of Aerospace Science and Technology, Xidian University