[v2] loongarch: ignore zero-size fields in calling convention

Message ID 4e6b1850a2cfdc05e8a27d5c2c8216a82302a104.camel@mengyan1223.wang
State Committed
Commit d1ee29fd7fb972fee141a0e475f780be4253758a
Headers
Series [v2] loongarch: ignore zero-size fields in calling convention |

Commit Message

Xi Ruoyao April 27, 2022, 11:45 a.m. UTC
  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
  

Comments

Lulu Cheng April 27, 2022, 11:53 a.m. UTC | #1
OK!

在 2022/4/27 下午7:45, Xi Ruoyao 写道:
> 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;
> +}
  
Lulu Cheng April 28, 2022, 1:24 a.m. UTC | #2
I have pushed upstream. Thanks. Lulu Cheng

在 2022/4/27 下午7:45, Xi Ruoyao 写道:
> 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;
> +}
  

Patch

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;
+}