public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] aarch64: fix warning emission for ABI break since GCC 9.1
@ 2022-06-17 12:20 Christophe Lyon
  2022-06-17 12:21 ` [PATCH 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
  0 siblings, 1 reply; 2+ messages in thread
From: Christophe Lyon @ 2022-06-17 12:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.sandiford, Christophe Lyon

While looking at PR 105549, which is about fixing the ABI break
introduced in GCC 9.1 in parameter alignment with bit-fields, I noticed
that the GCC 9.1 warning is not emitted in all the cases where it
should be.  This patch fixes that and the next patch in the series
fixes the GCC 9.1 break.

I split this into two patches since patch #2 introduces a new ABI
break starting with GCC 13.1.  This way, patch #1 can be back-ported to
release branches if needed to fix the GCC 9.1 warning issue.

The fix in aarch64_layout_arg highlights the bug fixed by patch #2:
GCC 9 should not have changed behavior for nregs==1, and this patch
makes it warn so as to be consistent.

The part of the fix in aarch64_function_arg_boundary (replacing & with
&&) looks like an oversight of a previous commit in this area which
changed 'abi_break' from a boolean to an integer.

2022-06-16  Christophe Lyon  <christophe.lyon@arm.com>

gcc/ChangeLog:

	* config/aarch64/aarch64.cc (aarch64_layout_arg): Fix warning
	emission.
	(aarch64_function_arg_boundary): Fix typo.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/bitfield-abi-warning-align16-O0.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning-align8-O0.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning.h: New test.
---
 gcc/config/aarch64/aarch64.cc                 |  20 ++-
 .../aarch64/bitfield-abi-warning-align16-O0.c |  81 ++++++++++++
 .../aarch64/bitfield-abi-warning-align16-O2.c |  86 ++++++++++++
 .../aarch64/bitfield-abi-warning-align8-O0.c  |   7 +
 .../aarch64/bitfield-abi-warning-align8-O2.c  |  16 +++
 .../gcc.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
 6 files changed, 329 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O0.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning.h

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index d049f9a9819..13984e3435b 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7453,23 +7453,31 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
   if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS))
     {
       gcc_assert (nregs == 0 || nregs == 1 || nregs == 2);
+      unsigned int alignment;
 
       /* C.8 if the argument has an alignment of 16 then the NGRN is
 	 rounded up to the next even number.  */
-      if (nregs == 2
-	  && ncrn % 2
+      alignment = aarch64_function_arg_alignment (mode, type, &abi_break);
+      if (ncrn % 2
 	  /* The == 16 * BITS_PER_UNIT instead of >= 16 * BITS_PER_UNIT
 	     comparison is there because for > 16 * BITS_PER_UNIT
 	     alignment nregs should be > 2 and therefore it should be
 	     passed by reference rather than value.  */
-	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
+	  && (alignment
 	      == 16 * BITS_PER_UNIT))
 	{
+	  /* We want to emit a warning even if nregs == 1, because
+	     although we do not round ncrn up in this case, the callee
+	     has a different (broken) expectation.  */
 	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
 	    inform (input_location, "parameter passing for argument of type "
 		    "%qT changed in GCC 9.1", type);
-	  ++ncrn;
-	  gcc_assert (ncrn + nregs <= NUM_ARG_REGS);
+
+	  if (ncrn % 2)
+	    {
+	      ++ncrn;
+	      gcc_assert (ncrn + nregs <= NUM_ARG_REGS);
+	    }
 	}
 
       /* If an argument with an SVE mode needs to be shifted up to the
@@ -7648,7 +7656,7 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
   unsigned int alignment = aarch64_function_arg_alignment (mode, type,
 							   &abi_break);
   alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
-  if (abi_break & warn_psabi)
+  if (abi_break && warn_psabi)
     {
       abi_break = MIN (MAX (abi_break, PARM_BOUNDARY), STACK_BOUNDARY);
       if (alignment != abi_break)
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
new file mode 100644
index 00000000000..0a1f54acb2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -save-temps" } */
+
+#define ALIGN 16
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+/* Bitfield parameter in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 47 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
new file mode 100644
index 00000000000..ce2e089588b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
@@ -0,0 +1,86 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps" } */
+
+#define ALIGN 16
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+/* In f1, f2, f4, f8, f16, f16p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 12 { xfail *-*-* } } } */
+/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+
+/* Bitfield parameter in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 47 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O0.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O0.c
new file mode 100644
index 00000000000..af0ae69e9a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O0.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -save-temps" } */
+
+#define ALIGN 8
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
new file mode 100644
index 00000000000..cb2a945a819
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps" } */
+
+#define ALIGN 8
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+/* In f1, f2, f4, f8, fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 18 } } */
+
+/* In f16, f16p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 4 } } */
+
+/* In f1, f2, f4, f8, f16, fp, f1p, f2p, f4p, f8p, f16p stack versions:  */
+/* { dg-final { scan-assembler-times "and\tw0, w0, 1" 11 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning.h b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning.h
new file mode 100644
index 00000000000..80428032fb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning.h
@@ -0,0 +1,125 @@
+#include <stdarg.h>
+
+typedef unsigned long long ull __attribute__((aligned(ALIGN)));
+
+#ifndef EXTRA
+#define EXTRA unsigned long long x;
+#endif
+
+struct S1  { __attribute__((aligned(1))) ull i : 1; EXTRA };
+struct S2  { __attribute__((aligned(2))) ull i : 1; EXTRA };
+struct S4  { __attribute__((aligned(4))) ull i : 1; EXTRA };
+struct S8  { __attribute__((aligned(8))) ull i : 1; EXTRA };
+struct S16 { __attribute__((aligned(16))) ull i : 1; EXTRA };
+
+struct Sp   { ull i : 1; EXTRA }__attribute__((packed));
+struct S1p  { __attribute__((packed, aligned(1))) ull i : 1; EXTRA };
+struct S2p  { __attribute__((packed, aligned(2))) ull i : 1; EXTRA };
+struct S4p  { __attribute__((packed, aligned(4))) ull i : 1; EXTRA };
+struct S8p  { __attribute__((packed, aligned(8))) ull i : 1; EXTRA };
+struct S16p { __attribute__((packed, aligned(16))) ull i : 1; EXTRA };
+
+/* Bitfield in registers.  */
+#define PARAMS(xx) int a0, struct S##xx s, ull a1
+/* Bitfield passed by the stack.  */
+#define PARAMS_STACK(xx) int a0, ull a1, ull a2, ull a3, ull a4, ull a5, ull a6, ull a7, struct S##xx t
+/* Bitfield passed via stdarg.  */
+#define PARAMS_STDARG(xx) int a0, ...
+
+#define CODE(xx)				\
+  return s.i;
+
+#define CODE_STACK(xx)				\
+  return t.i;
+
+#define CODE_STDARG(xx)				\
+  va_list ap;					\
+  struct S##xx arg;				\
+  __builtin_va_start(ap,a0);			\
+  arg = __builtin_va_arg(ap, struct S##xx);	\
+  return arg.i;
+
+#define ARGS(xx) x, (struct S##xx) { x }, x
+#define ARGS_STACK(xx) x, x, x, x, x, x, x, x, (struct S##xx) { x }
+#define ARGS_STDARG(xx) x, (struct S##xx) { x }
+
+/* Bitfield in registers.  */
+int __attribute__ ((noipa)) f1 (PARAMS(1))  { CODE(1) }
+int __attribute__ ((noipa)) f2 (PARAMS(2))  { CODE(2) }
+int __attribute__ ((noipa)) f4 (PARAMS(4))  { CODE(4) }
+int __attribute__ ((noipa)) f8 (PARAMS(8))  { CODE(8) }
+int __attribute__ ((noipa)) f16(PARAMS(16)) { CODE(16) }
+
+int __attribute__ ((noipa)) fp  (PARAMS(p))   { CODE(p) }
+int __attribute__ ((noipa)) f1p (PARAMS(1p))  { CODE(1p) }
+int __attribute__ ((noipa)) f2p (PARAMS(2p))  { CODE(2p) }
+int __attribute__ ((noipa)) f4p (PARAMS(4p))  { CODE(4p) }
+int __attribute__ ((noipa)) f8p (PARAMS(8p))  { CODE(8p) }
+int __attribute__ ((noipa)) f16p(PARAMS(16p)) { CODE(16p) }
+
+int g1 (int x) { return f1 (ARGS(1)); }
+int g2 (int x) { return f2 (ARGS(2)); }
+int g4 (int x) { return f4 (ARGS(4)); }
+int g8 (int x) { return f8 (ARGS(8)); }
+int g16(int x) { return f16 (ARGS(16)); }
+
+int gp  (int x) { return fp   (ARGS(p)); }
+int g1p (int x) { return f1p  (ARGS(1p)); }
+int g2p (int x) { return f2p  (ARGS(2p)); }
+int g4p (int x) { return f4p  (ARGS(4p)); }
+int g8p (int x) { return f8p  (ARGS(8p)); }
+int g16p(int x) { return f16p (ARGS(16p)); }
+
+/* Bitfield in the stack.  */
+int __attribute__ ((noipa)) f1_stack (PARAMS_STACK(1))  { CODE_STACK(1) }
+int __attribute__ ((noipa)) f2_stack (PARAMS_STACK(2))  { CODE_STACK(2) }
+int __attribute__ ((noipa)) f4_stack (PARAMS_STACK(4))  { CODE_STACK(4) }
+int __attribute__ ((noipa)) f8_stack (PARAMS_STACK(8))  { CODE_STACK(8) }
+int __attribute__ ((noipa)) f16_stack(PARAMS_STACK(16)) { CODE_STACK(16) }
+
+int __attribute__ ((noipa)) fp_stack  (PARAMS_STACK(p))   { CODE_STACK(p) }
+int __attribute__ ((noipa)) f1p_stack (PARAMS_STACK(1p))  { CODE_STACK(1p) }
+int __attribute__ ((noipa)) f2p_stack (PARAMS_STACK(2p))  { CODE_STACK(2p) }
+int __attribute__ ((noipa)) f4p_stack (PARAMS_STACK(4p))  { CODE_STACK(4p) }
+int __attribute__ ((noipa)) f8p_stack (PARAMS_STACK(8p))  { CODE_STACK(8p) }
+int __attribute__ ((noipa)) f16p_stack(PARAMS_STACK(16p)) { CODE_STACK(16p) }
+
+int g1_stack (int x) { return f1_stack (ARGS_STACK(1)); }
+int g2_stack (int x) { return f2_stack (ARGS_STACK(2)); }
+int g4_stack (int x) { return f4_stack (ARGS_STACK(4)); }
+int g8_stack (int x) { return f8_stack (ARGS_STACK(8)); }
+int g16_stack(int x) { return f16_stack (ARGS_STACK(16)); }
+
+int gp_stack  (int x) { return fp_stack (ARGS_STACK(p)); }
+int g1p_stack (int x) { return f1p_stack (ARGS_STACK(1p)); }
+int g2p_stack (int x) { return f2p_stack (ARGS_STACK(2p)); }
+int g4p_stack (int x) { return f4p_stack (ARGS_STACK(4p)); }
+int g8p_stack (int x) { return f8p_stack (ARGS_STACK(8p)); }
+int g16p_stack(int x) { return f16p_stack (ARGS_STACK(16p)); }
+
+/* Bitfield  via stdarg.  */
+int __attribute__ ((noipa)) f1_stdarg (PARAMS_STDARG(1))  { CODE_STDARG(1) }
+int __attribute__ ((noipa)) f2_stdarg (PARAMS_STDARG(2))  { CODE_STDARG(2) }
+int __attribute__ ((noipa)) f4_stdarg (PARAMS_STDARG(4))  { CODE_STDARG(4) }
+int __attribute__ ((noipa)) f8_stdarg (PARAMS_STDARG(8))  { CODE_STDARG(8) }
+int __attribute__ ((noipa)) f16_stdarg(PARAMS_STDARG(16)) { CODE_STDARG(16) }
+
+int __attribute__ ((noipa)) fp_stdarg  (PARAMS_STDARG(p))   { CODE_STDARG(p) }
+int __attribute__ ((noipa)) f1p_stdarg (PARAMS_STDARG(1p))  { CODE_STDARG(1p) }
+int __attribute__ ((noipa)) f2p_stdarg (PARAMS_STDARG(2p))  { CODE_STDARG(2p) }
+int __attribute__ ((noipa)) f4p_stdarg (PARAMS_STDARG(4p))  { CODE_STDARG(4p) }
+int __attribute__ ((noipa)) f8p_stdarg (PARAMS_STDARG(8p))  { CODE_STDARG(8p) }
+int __attribute__ ((noipa)) f16p_stdarg(PARAMS_STDARG(16p)) { CODE_STDARG(16p) }
+
+int g1_stdarg (int x) { return f1_stdarg (ARGS_STDARG(1)); }
+int g2_stdarg (int x) { return f2_stdarg (ARGS_STDARG(2)); }
+int g4_stdarg (int x) { return f4_stdarg (ARGS_STDARG(4)); }
+int g8_stdarg (int x) { return f8_stdarg (ARGS_STDARG(8)); }
+int g16_stdarg(int x) { return f16_stdarg (ARGS_STDARG(16)); }
+
+int gp_stdarg  (int x) { return fp_stdarg (ARGS_STDARG(p)); }
+int g1p_stdarg (int x) { return f1p_stdarg (ARGS_STDARG(1p)); }
+int g2p_stdarg (int x) { return f2p_stdarg (ARGS_STDARG(2p)); }
+int g4p_stdarg (int x) { return f4p_stdarg (ARGS_STDARG(4p)); }
+int g8p_stdarg (int x) { return f8p_stdarg (ARGS_STDARG(8p)); }
+int g16p_stdarg(int x) { return f16p_stdarg (ARGS_STDARG(16p)); }
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2022-06-17 12:20 [PATCH 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Christophe Lyon
@ 2022-06-17 12:21 ` Christophe Lyon
  0 siblings, 0 replies; 2+ messages in thread
From: Christophe Lyon @ 2022-06-17 12:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.sandiford, Christophe Lyon

While working on enabling DFP for AArch64, I noticed new failures in
gcc.dg/compat/struct-layout-1.exp (t028) which were not actually
caused by DFP types handling. These tests are generated during 'make
check' and enabling DFP made generation different (not sure if new
non-DFP tests are generated, or if existing ones are generated
differently, the tests in question are huge and difficult to compare).

Anyway, I reduced the problem to what I attach at the end of the new
gcc.target/aarch64/aapcs64/va_arg-17.c test and rewrote it in the same
scheme as other va_arg* AArch64 tests.  Richard Sandiford further
reduced this to a non-vararg function, added as a second testcase.

This is a tough case mixing bit-fields and alignment, where
aarch64_function_arg_alignment did not follow what its descriptive
comment says: we want to use the natural alignment of the bit-field
type only if the user didn't reduce the alignment for the bit-field
itself.

The fix would be very small, except that this introduces a new ABI
break, and we have to warn about that.  Since this actually fixes a
problem introduced in GCC 9.1, we keep the old computation to detect
when we now behave differently.

This patch adds two new tests (va_arg-17.c and
pr105549.c). va_arg-17.c contains the reduced offending testcase from
struct-layout-1.exp for reference.  We update some tests introduced by
the previous patch, where parameters with bit-fields and packed
attribute now emit a different warning.

We also take the opportunity to fix the comment above
aarch64_function_arg_alignment since the value of the abi_break
parameter was changed in a previous commit, no longer matching the
description.

2022-06-16  Christophe Lyon  <christophe.lyon@arm.com>

	gcc/
	PR target/105549
	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment):
	Check DECL_PACKED for bitfield.
	(aarch64_layout_arg): Warn when parameter passing ABI changes.
	(aarch64_function_arg_boundary): Likewise.
	(aarch64_gimplify_va_arg_expr): Likewise.

	gcc/testsuite/
	PR target/105549
	* gcc.target/aarch64/bitfield-abi-warning-align16-O0.c: Update.
	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: Update.
	* gcc.target/aarch64/aapcs64/va_arg-17.c: New test.
	* gcc.target/aarch64/pr105549.c: New test.
---
 gcc/config/aarch64/aarch64.cc                 |  87 ++++++++++++---
 .../gcc.target/aarch64/aapcs64/va_arg-17.c    | 105 ++++++++++++++++++
 .../aarch64/bitfield-abi-warning-align16-O0.c |  60 +++++-----
 .../aarch64/bitfield-abi-warning-align16-O2.c |  60 +++++-----
 gcc/testsuite/gcc.target/aarch64/pr105549.c   |  12 ++
 5 files changed, 249 insertions(+), 75 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr105549.c

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 13984e3435b..e7a6288d7a7 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7248,15 +7248,19 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
 /* Given MODE and TYPE of a function argument, return the alignment in
    bits.  The idea is to suppress any stronger alignment requested by
    the user and opt for the natural alignment (specified in AAPCS64 \S
-   4.1).  ABI_BREAK is set to true if the alignment was incorrectly
-   calculated in versions of GCC prior to GCC-9.  This is a helper
+   4.1).  ABI_BREAK is set to the old alignment if the alignment was
+   incorrectly calculated in versions of GCC prior to GCC-9.
+   ABI_BREAK_PACKED is set to the old alignment if it was incorrectly
+   calculated in versions between GCC-9 and GCC-13.  This is a helper
    function for local use only.  */
 
 static unsigned int
 aarch64_function_arg_alignment (machine_mode mode, const_tree type,
-				unsigned int *abi_break)
+				unsigned int *abi_break,
+				unsigned int *abi_break_packed)
 {
   *abi_break = 0;
+  *abi_break_packed = 0;
   if (!type)
     return GET_MODE_ALIGNMENT (mode);
 
@@ -7272,6 +7276,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
     return TYPE_ALIGN (TREE_TYPE (type));
 
   unsigned int alignment = 0;
+  unsigned int bitfield_alignment_with_packed = 0;
   unsigned int bitfield_alignment = 0;
   for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     if (TREE_CODE (field) == FIELD_DECL)
@@ -7290,12 +7295,32 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
 	   "s" contains only one Fundamental Data Type (the int field)
 	   but gains 8-byte alignment and size thanks to "e".  */
 	alignment = std::max (alignment, DECL_ALIGN (field));
+
 	if (DECL_BIT_FIELD_TYPE (field))
-	  bitfield_alignment
-	    = std::max (bitfield_alignment,
-			TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)));
+	  {
+	    /* Take the bit-field type's alignment into account only
+	       if the user didn't reduce this field's alignment with
+	       the packed attribute.  */
+	      if (!DECL_PACKED (field))
+		bitfield_alignment
+		  = std::max (bitfield_alignment,
+			      TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)));
+
+	      /* Compute the alignment even if the bit-field is
+		 packed, so that we can emit a warning in case the
+		 alignment changed between GCC versions.  */
+	      bitfield_alignment_with_packed
+		= std::max (bitfield_alignment_with_packed,
+			    TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)));
+	    }
       }
 
+  /* Emit a warning if the alignment is different when taking the
+     'packed' attribute into account.  */
+  if (bitfield_alignment != bitfield_alignment_with_packed
+      && bitfield_alignment_with_packed > alignment)
+    *abi_break_packed = bitfield_alignment_with_packed;
+
   if (bitfield_alignment > alignment)
     {
       *abi_break = alignment;
@@ -7321,6 +7346,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
   bool allocate_ncrn, allocate_nvrn;
   HOST_WIDE_INT size;
   unsigned int abi_break;
+  unsigned int abi_break_packed;
 
   /* We need to do this once per argument.  */
   if (pcum->aapcs_arg_processed)
@@ -7457,15 +7483,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 
       /* C.8 if the argument has an alignment of 16 then the NGRN is
 	 rounded up to the next even number.  */
-      alignment = aarch64_function_arg_alignment (mode, type, &abi_break);
-      if (ncrn % 2
+      alignment = aarch64_function_arg_alignment (mode, type, &abi_break,
+						  &abi_break_packed);
+      if (ncrn % 2)
+	{
+	  /* Emit a warning if the alignment changed when taking the
+	     'packed' attribute into account.  */
+	  if (abi_break_packed && warn_psabi && currently_expanding_gimple_stmt)
+	    inform (input_location, "parameter passing for argument of type "
+		    "%qT changed in GCC 13.1", type);
+
 	  /* The == 16 * BITS_PER_UNIT instead of >= 16 * BITS_PER_UNIT
 	     comparison is there because for > 16 * BITS_PER_UNIT
 	     alignment nregs should be > 2 and therefore it should be
 	     passed by reference rather than value.  */
-	  && (alignment
-	      == 16 * BITS_PER_UNIT))
+	  if (alignment
+	      == 16 * BITS_PER_UNIT)
 	{
+
 	  /* We want to emit a warning even if nregs == 1, because
 	     although we do not round ncrn up in this case, the callee
 	     has a different (broken) expectation.  */
@@ -7479,6 +7514,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 	      gcc_assert (ncrn + nregs <= NUM_ARG_REGS);
 	    }
 	}
+	}
 
       /* If an argument with an SVE mode needs to be shifted up to the
 	 high part of the register, treat it as though it had an integer mode.
@@ -7530,7 +7566,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 on_stack:
   pcum->aapcs_stack_words = size / UNITS_PER_WORD;
 
-  if (aarch64_function_arg_alignment (mode, type, &abi_break)
+  unsigned int alignment =
+    aarch64_function_arg_alignment (mode, type, &abi_break, &abi_break_packed);
+
+  if (abi_break_packed && warn_psabi && currently_expanding_gimple_stmt)
+    inform (input_location, "parameter passing for argument of type "
+	    "%qT changed in GCC 13.1", type);
+
+  if (alignment
       == 16 * BITS_PER_UNIT)
     {
       int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
@@ -7653,10 +7696,19 @@ static unsigned int
 aarch64_function_arg_boundary (machine_mode mode, const_tree type)
 {
   unsigned int abi_break;
+  unsigned int abi_break_packed;
   unsigned int alignment = aarch64_function_arg_alignment (mode, type,
-							   &abi_break);
+							   &abi_break,
+							   &abi_break_packed);
   alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
-  if (abi_break && warn_psabi)
+  if (abi_break_packed && warn_psabi)
+    {
+      abi_break_packed = MIN (MAX (abi_break_packed, PARM_BOUNDARY), STACK_BOUNDARY);
+      if (alignment != abi_break_packed)
+	inform (input_location, "parameter passing for argument of type "
+		"%qT changed in GCC 13.1", type);
+    }
+  else if (abi_break && warn_psabi)
     {
       abi_break = MIN (MAX (abi_break, PARM_BOUNDARY), STACK_BOUNDARY);
       if (alignment != abi_break)
@@ -19528,8 +19580,10 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
   size = int_size_in_bytes (type);
 
   unsigned int abi_break;
+  unsigned int abi_break_packed;
   align
-    = aarch64_function_arg_alignment (mode, type, &abi_break) / BITS_PER_UNIT;
+    = aarch64_function_arg_alignment (mode, type, &abi_break, &abi_break_packed)
+    / BITS_PER_UNIT;
 
   dw_align = false;
   adjust = 0;
@@ -19572,7 +19626,10 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
       rsize = ROUND_UP (size, UNITS_PER_WORD);
       nregs = rsize / UNITS_PER_WORD;
 
-      if (align > 8)
+      if (align <= 8 && abi_break_packed && warn_psabi)
+	inform (input_location, "parameter passing for argument of type "
+		"%qT changed in GCC 13.1", type);
+      else if (align > 8)
 	{
 	  if (abi_break && warn_psabi)
 	    inform (input_location, "parameter passing for argument of type "
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c
new file mode 100644
index 00000000000..24895c3ab48
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c
@@ -0,0 +1,105 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test covers a corner case where a composite type parameter fits in one
+   register: we do not need a double-word alignment when accessing it in the
+   va_arg stack area.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-17.c"
+#include "type-def.h"
+
+enum E6 { e6_0, e6_1, e6_2, e6_3, e6_65533 = 65533, e6_65534, e6_65535 };
+typedef enum E6 Tal16E6 __attribute__((aligned (16)));
+typedef unsigned int Tuint;
+
+int fails;
+
+union S2844 {
+  Tuint a:((((10) - 1) & 31) + 1);
+  Tal16E6 __attribute__((aligned (2), packed)) b:31;
+  struct{}c[0];
+} ;
+union S2844 s2844;
+union S2844 a2844[5];
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  memset (&s2844, '\0', sizeof (s2844));
+  memset (a2844, '\0', sizeof (a2844));
+  s2844.a = 799U;
+  a2844[2].a = 586U;
+}
+
+#include "abitest.h"
+#else
+  ARG       (int          , 1        , W0 , LAST_NAMED_ARG_ID)
+  DOTS
+  ANON_PROMOTED  (float   , 1.0f, double, 1.0, D0, 1)
+  ANON      (union S2844  , s2844    , X1 , 2)
+  ANON      (long long    , 2LL      , X2 , 3)
+  ANON      (union  S2844 , a2844[2] , X3 , 4)
+  LAST_ANON (union  S2844 , a2844[2] , X4 , 5)
+#endif
+
+#if 0
+  /* This test is derived from a case generated by struct-layout-1.exp:  */
+
+enum E6 { e6_0, e6_1, e6_2, e6_3, e6_65533 = 65533, e6_65534, e6_65535 };
+typedef enum E6 Tal16E6 __attribute__((aligned (16)));
+typedef unsigned int Tuint;
+
+int fails;
+
+union S2844 {
+  Tuint a:((((10) - 1) & 31) + 1);
+  Tal16E6 __attribute__((aligned (2), packed)) b:31;
+  struct{}c[0];
+} ;
+union S2844 s2844;
+union S2844 a2844[5];
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+void check2844va (int z, ...) {
+  union S2844 arg, *p;
+  va_list ap;
+
+  __builtin_va_start(ap,z);
+  if (__builtin_va_arg(ap,double) != 1.0)
+    printf ("fail %d.%d\n", 2844, 0), ++fails;
+
+  p = &s2844;
+  arg = __builtin_va_arg(ap,union S2844);  /* This would fail.  */
+  if (p->a != arg.a)
+    printf ("fail %d.%d\n", 2844, 1), ++fails;
+
+  if (__builtin_va_arg(ap,long long) != 3LL)
+    printf ("fail %d.%d\n", 2844, 2), ++fails;
+
+  p = &a2844[2];
+  arg = __builtin_va_arg(ap,union S2844);  /* This would fail.  */
+  if (p->a != arg.a)
+    printf ("fail %d.%d\n", 2844, 3), ++fails;
+
+  arg = __builtin_va_arg(ap,union S2844);  /* This would fail.  */
+  if (p->a != arg.a)
+    printf ("fail %d.%d\n", 2844, 4), ++fails;
+
+  __builtin_va_end(ap);
+}
+
+int main (void) {
+  int i, j;
+  memset (&s2844, '\0', sizeof (s2844));
+  memset (a2844, '\0', sizeof (a2844));
+  s2844.a = 799U;
+  a2844[2].a = 586U;
+  check2844va (1, 1.0, s2844, 2LL, a2844[2], a2844[2]);
+  exit (fails != 0);
+}
+#endif /* 0 */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
index 0a1f54acb2d..e52e1ae6d80 100644
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O0.c
@@ -12,11 +12,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 53 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 54 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 55 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 56 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 57 } */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } */
@@ -24,11 +24,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 66 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 67 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 68 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 69 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 70 } */
 
 
 /* Bitfield parameter in stack.  */
@@ -37,11 +37,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 80 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } */
@@ -49,11 +49,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 93 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } */
 
 
 /* Bitfield parameter in stdarg.  */
@@ -62,11 +62,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 107 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 108 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 109 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 110 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 111 } */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } */
@@ -74,8 +74,8 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 120 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 121 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 122 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 123 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 124 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
index ce2e089588b..72bba44ba94 100644
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
@@ -17,11 +17,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 53 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 54 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 55 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 56 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 57 } */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } */
@@ -29,11 +29,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 66 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 67 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 68 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 69 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 70 } */
 
 
 /* Bitfield parameter in stack.  */
@@ -42,11 +42,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 80 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } */
@@ -54,11 +54,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 93 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } */
 
 
 /* Bitfield parameter in stdarg.  */
@@ -67,11 +67,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 107 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 108 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 109 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 110 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 111 } */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } */
@@ -79,8 +79,8 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 } */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } */ 
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 120 } */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 121 } */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 122 } */ 
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 123 } */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 124 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr105549.c b/gcc/testsuite/gcc.target/aarch64/pr105549.c
new file mode 100644
index 00000000000..55a91ed6bc4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr105549.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-save-temps" } */
+
+enum e { E1 };
+typedef enum e e __attribute__((aligned(16)));
+union u {
+    __attribute__((aligned(2), packed)) e a : 1;
+    int x[4];
+};
+union u g(int a, union u u2) { return u2; }
+
+/* { dg-final { scan-assembler "stp\tx1, x2, \\\[sp, 8\\\]" } } */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-06-17 12:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-17 12:20 [PATCH 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Christophe Lyon
2022-06-17 12:21 ` [PATCH 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).