On Wed, 2022-04-27 at 14:57 +0800, Lulu Cheng wrote:

> I think the modification should be below.
> > > 
> > > >              if (!TYPE_P (TREE_TYPE (f))) 
> > > >                 return -1;

I think (!TYPE_P (TREE_TYPE (f)) will never be true (the code handling
calling convention of other ports does not has this check).  But "first
thing first" so I'll move the change below this for now.

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..80046b64006 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -329,6 +329,9 @@ loongarch_flatten_aggregate_field (const_tree type,
            if (!TYPE_P (TREE_TYPE (f)))
              return -1;
 
+           if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f)))
+             continue;
+
            HOST_WIDE_INT pos = offset + int_byte_position (f);
            n = loongarch_flatten_aggregate_field (TREE_TYPE (f), fields, n,
                                                   pos);
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;
+}
-- 
2.36.0


Reply via email to