public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1
@ 2023-01-11 14:18 Christophe Lyon
  2023-01-11 14:18 ` [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
  2023-01-12 13:03 ` [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Richard Sandiford
  0 siblings, 2 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-11 14:18 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, we
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.

We 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 main idea is to add a new global boolean that indicates whether
we're expanding the start of a function, so that aarch64_layout_arg
can emit warnings for callees as well as callers.  This removes the
need for aarch64_function_arg_boundary to warn (with its incomplete
information).  However, in the first patch there are still cases where
we emit warnings were we should not; this is fixed in patch #2 where
we can distinguish between GCC 9.1 and GCC.13.1 ABI breaks properly.

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.

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.

v2->v3: removed a bogus comment, added C++ tests (copied from the C
ones)

2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
	    Richard Sandiford  <richard.sandiford@arm.com>

gcc/ChangeLog:

	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Fix
	comment.
	(aarch64_layout_arg): Factorize warning conditions.
	(aarch64_function_arg_boundary): Fix typo.
	* function.cc (currently_expanding_function_start): New variable.
	(expand_function_start): Handle
	currently_expanding_function_start.
	* function.h (currently_expanding_function_start): Declare.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: New
	test.
	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: New
	test.
	* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: New test.
	* gcc.target/aarch64/bitfield-abi-warning.h: New test.
	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: New test.
	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: New
	test.
	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: New test.
	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: New
	test.
	* g++.target/aarch64/bitfield-abi-warning-align8-O2.C: New test.
	* g++.target/aarch64/bitfield-abi-warning.h: New test.
---
 gcc/config/aarch64/aarch64.cc                 |  28 +++-
 gcc/function.cc                               |   5 +
 gcc/function.h                                |   2 +
 .../bitfield-abi-warning-align16-O2-extra.C   |  86 ++++++++++++
 .../aarch64/bitfield-abi-warning-align16-O2.C |  87 ++++++++++++
 .../bitfield-abi-warning-align32-O2-extra.C   | 119 +++++++++++++++++
 .../aarch64/bitfield-abi-warning-align32-O2.C | 119 +++++++++++++++++
 .../aarch64/bitfield-abi-warning-align8-O2.C  |  16 +++
 .../g++.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
 .../bitfield-abi-warning-align16-O2-extra.c   |  86 ++++++++++++
 .../aarch64/bitfield-abi-warning-align16-O2.c |  87 ++++++++++++
 .../bitfield-abi-warning-align32-O2-extra.c   | 119 +++++++++++++++++
 .../aarch64/bitfield-abi-warning-align32-O2.c | 119 +++++++++++++++++
 .../aarch64/bitfield-abi-warning-align8-O2.c  |  16 +++
 .../gcc.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
 15 files changed, 1132 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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-align32-O2-extra.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.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 ab78b11b158..3623df5bd94 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7264,9 +7264,9 @@ 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
-   function for local use only.  */
+   4.1).  ABI_BREAK is set to the old alignment if the alignment was
+   incorrectly calculated in versions of GCC prior to GCC-9.  This is
+   a helper function for local use only.  */
 
 static unsigned int
 aarch64_function_arg_alignment (machine_mode mode, const_tree type,
@@ -7342,11 +7342,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
   if (pcum->aapcs_arg_processed)
     return;
 
+  bool warn_pcs_change
+    = (warn_psabi
+       && !pcum->silent_p
+       && (currently_expanding_function_start
+	   || currently_expanding_gimple_stmt));
+
+  unsigned int alignment
+    = aarch64_function_arg_alignment (mode, type, &abi_break);
+  gcc_assert (!alignment || abi_break < alignment);
+
   pcum->aapcs_arg_processed = true;
 
   pure_scalable_type_info pst_info;
   if (type && pst_info.analyze_registers (type))
     {
+      /* aarch64_function_arg_alignment has never had an effect on
+	 this case.  */
+
       /* The PCS says that it is invalid to pass an SVE value to an
 	 unprototyped function.  There is no ABI-defined location we
 	 can return in this case, so we have no real choice but to raise
@@ -7417,6 +7430,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
      and homogenous short-vector aggregates (HVA).  */
   if (allocate_nvrn)
     {
+      /* aarch64_function_arg_alignment has never had an effect on
+	 this case.  */
       if (!pcum->silent_p && !TARGET_FLOAT)
 	aarch64_err_no_fpadvsimd (mode);
 
@@ -7481,7 +7496,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
 	      == 16 * BITS_PER_UNIT))
 	{
-	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
+	  if (warn_pcs_change && abi_break)
 	    inform (input_location, "parameter passing for argument of type "
 		    "%qT changed in GCC 9.1", type);
 	  ++ncrn;
@@ -7544,7 +7559,7 @@ on_stack:
       int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
       if (pcum->aapcs_stack_size != new_size)
 	{
-	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
+	  if (warn_pcs_change && abi_break)
 	    inform (input_location, "parameter passing for argument of type "
 		    "%qT changed in GCC 9.1", type);
 	  pcum->aapcs_stack_size = new_size;
@@ -7664,14 +7679,13 @@ 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)
 	inform (input_location, "parameter passing for argument of type "
 		"%qT changed in GCC 9.1", type);
     }
-
   return alignment;
 }
 
diff --git a/gcc/function.cc b/gcc/function.cc
index d5ed51a6a66..b037e7de31a 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -5049,9 +5049,12 @@ stack_protect_epilogue (void)
    PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
    the function's parameters, which must be run at any return statement.  */
 
+bool currently_expanding_function_start;
 void
 expand_function_start (tree subr)
 {
+  currently_expanding_function_start = true;
+
   /* Make sure volatile mem refs aren't considered
      valid operands of arithmetic insns.  */
   init_recog_no_volatile ();
@@ -5244,6 +5247,8 @@ expand_function_start (tree subr)
   /* If we are doing generic stack checking, the probe should go here.  */
   if (flag_stack_check == GENERIC_STACK_CHECK)
     stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
+
+  currently_expanding_function_start = false;
 }
 \f
 void
diff --git a/gcc/function.h b/gcc/function.h
index 098613766be..19abc5e7e6e 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -719,4 +719,6 @@ extern const char *current_function_name (void);
 
 extern void used_types_insert (tree);
 
+extern bool currently_expanding_function_start;
+
 #endif  /* GCC_FUNCTION_H */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
new file mode 100644
index 00000000000..c45be832d5b
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
@@ -0,0 +1,86 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
+
+#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
new file mode 100644
index 00000000000..61d12ec22eb
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
@@ -0,0 +1,87 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
+
+#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) (because the argument fits in a single register).  Should not
+   warn, but aarch64_function_arg_boundary would need to take the argument size
+   into account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
+
+/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
+   in the callee, but not in the caller.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
new file mode 100644
index 00000000000..04b183af697
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
+
+#define ALIGN 32
+//#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+
+/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
+
+/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+
+/* In f16p (and stdarg version):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+
+/* In fp_stack, f1p_stack:  */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+
+/* In f2p_stack:  */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f4p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f16p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+
+/* Bitfield parameter in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) because the argument fits in a single register.  Should not warn,
+   but aarch64_function_arg_boundary would need to take the argument size into
+   account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+
+
+/* Bitfield call argument in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+
+
+/* Bitfield parameter in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
+   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* Changed in GCC 9.1.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
+   the overall alignment is >= 16.  No warning expected.  */
+
+
+/* Bitfield call argument in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
+   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
+   warning expected.  */
+
+
+/* Bitfield parameter in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
+   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
+   Should not warn.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
+   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
new file mode 100644
index 00000000000..cdb5b4df774
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
+
+#define ALIGN 32
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
+
+/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+
+/* In f16p (and stdarg version):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+
+/* In fp_stack, f1p_stack:  */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+
+/* In f2p_stack:  */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f4p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f16p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+
+/* Bitfield parameter in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) because the argument fits in a single register.  Should not warn,
+   but aarch64_function_arg_boundary would need to take the argument size into
+   account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+
+
+/* Bitfield call argument in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+
+
+/* Bitfield parameter in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
+   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
+   the overall alignment is >= 16.  No warning expected.  */
+
+/* Bitfield call argument in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
+   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
+   warning expected.  */
+
+
+/* Bitfield parameter in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
+   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
+   in the callee, but not in the caller.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
+   Should not warn.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
+   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
new file mode 100644
index 00000000000..b1764d97ea0
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
+
+#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/g++.target/aarch64/bitfield-abi-warning.h b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
new file mode 100644
index 00000000000..3940b714ef8
--- /dev/null
+++ b/gcc/testsuite/g++.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, ull a8, 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, 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)); }
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
new file mode 100644
index 00000000000..3e38cac149d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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 } f1 */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
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..39c5f9228ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
@@ -0,0 +1,87 @@
+/* { 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 } f1 */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) (because the argument fits in a single register).  Should not
+   warn, but aarch64_function_arg_boundary would need to take the argument size
+   into account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Bitfield call argument in registers.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+
+/* Bitfield parameter in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* Bitfield call argument in stack.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* Bitfield parameter in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
+
+/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
+   in the callee, but not in the caller.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
new file mode 100644
index 00000000000..70671ceda09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps" } */
+
+#define ALIGN 32
+//#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+
+/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
+
+/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+
+/* In f16p (and stdarg version):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+
+/* In fp_stack, f1p_stack:  */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+
+/* In f2p_stack:  */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f4p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f16p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+
+/* Bitfield parameter in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) because the argument fits in a single register.  Should not warn,
+   but aarch64_function_arg_boundary would need to take the argument size into
+   account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+
+
+/* Bitfield call argument in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+
+
+/* Bitfield parameter in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
+   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* Changed in GCC 9.1.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
+   the overall alignment is >= 16.  No warning expected.  */
+
+
+/* Bitfield call argument in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
+   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
+   warning expected.  */
+
+
+/* Bitfield parameter in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
+   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
+   Should not warn.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
+   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
new file mode 100644
index 00000000000..757a2f1543c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps" } */
+
+#define ALIGN 32
+#define EXTRA
+
+#include "bitfield-abi-warning.h"
+
+/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
+
+/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+
+/* In f16p (and stdarg version):  */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+
+/* In fp_stack, f1p_stack:  */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+
+/* In f2p_stack:  */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f4p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+
+/* In f16p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+
+/* Bitfield parameter in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
+   f4p, f8p) because the argument fits in a single register.  Should not warn,
+   but aarch64_function_arg_boundary would need to take the argument size into
+   account as well as whether it's passed via registers or the stack.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+
+/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+
+
+/* Bitfield call argument in registers.  */
+/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
+   because the overall alignment is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
+   g4p, g8p), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+
+
+/* Bitfield parameter in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
+   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+
+/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
+   the overall alignment is >= 16.  No warning expected.  */
+
+/* Bitfield call argument in stack.  */
+/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
+   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
+   16.  No warning expected.  */
+
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+
+
+/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
+   warning expected.  */
+
+
+/* Bitfield parameter in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
+   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
+   in the callee, but not in the caller.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
+   Should not warn.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+
+/* Bitfield call argument in stdarg.  */
+/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
+   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
+   is > 16.  No warning expected.  */
+
+/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
+   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+
+/* Changed in GCC 9.1, but we fail to emit a warning.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
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..3940b714ef8
--- /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, ull a8, 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, 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] 14+ messages in thread

* [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-11 14:18 [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Christophe Lyon
@ 2023-01-11 14:18 ` Christophe Lyon
  2023-01-12 13:19   ` Richard Sandiford
  2023-01-13 15:38   ` Jakub Jelinek
  2023-01-12 13:03 ` [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Richard Sandiford
  1 sibling, 2 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-11 14:18 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 patch also adds a comment and assert that would help someone who
has to look at this area again.

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.

v2->v3: testcase update

2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
	    Richard Sandiford  <richard.sandiford@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): Do not warn here.
	(aarch64_gimplify_va_arg_expr): Warn when parameter passing ABI
	changes.

	gcc/testsuite/
	PR target/105549
	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: Update.
	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: Update.
	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: Update.
	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: Update.
	* gcc.target/aarch64/aapcs64/va_arg-17.c: New test.
	* gcc.target/aarch64/pr105549.c: New test.
	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: Update.
	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: Update.
	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: Update.
	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: Update.
---
 gcc/config/aarch64/aarch64.cc                 | 148 ++++++++++++++----
 .../bitfield-abi-warning-align16-O2-extra.C   |  64 ++++----
 .../aarch64/bitfield-abi-warning-align16-O2.C |  48 +++---
 .../bitfield-abi-warning-align32-O2-extra.C   | 131 +++++++---------
 .../aarch64/bitfield-abi-warning-align32-O2.C | 132 ++++++++--------
 .../gcc.target/aarch64/aapcs64/va_arg-17.c    | 105 +++++++++++++
 .../bitfield-abi-warning-align16-O2-extra.c   |  64 ++++----
 .../aarch64/bitfield-abi-warning-align16-O2.c |  48 +++---
 .../bitfield-abi-warning-align32-O2-extra.c   | 131 +++++++---------
 .../aarch64/bitfield-abi-warning-align32-O2.c | 132 ++++++++--------
 gcc/testsuite/gcc.target/aarch64/pr105549.c   |  12 ++
 11 files changed, 587 insertions(+), 428 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 3623df5bd94..a6d95dd85bf 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7265,14 +7265,18 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
    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 the old alignment if the alignment was
-   incorrectly calculated in versions of GCC prior to GCC-9.  This is
-   a helper function for local use only.  */
+   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);
 
@@ -7288,6 +7292,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)
@@ -7307,11 +7312,30 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
 	   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;
@@ -7337,6 +7361,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)
@@ -7348,9 +7373,57 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
        && (currently_expanding_function_start
 	   || currently_expanding_gimple_stmt));
 
+  /* There are several things to note here:
+
+     - Both the C and AAPCS64 interpretations of a type's alignment should
+       give a value that is no greater than the type's size.
+
+     - Types bigger than 16 bytes are passed indirectly.
+
+     - If an argument of type T is passed indirectly, TYPE and MODE describe
+       a pointer to T rather than T iself.
+
+     It follows that the AAPCS64 alignment of TYPE must be no greater
+     than 16 bytes.
+
+     Versions prior to GCC 9.1 ignored a bitfield's underlying type
+     and so could calculate an alignment that was too small.  If this
+     happened for TYPE then ABI_BREAK is this older, too-small alignment.
+
+     Although GCC 9.1 fixed that bug, it introduced a different one:
+     it would consider the alignment of a bitfield's underlying type even
+     if the field was packed (which should have the effect of overriding
+     the alignment of the underlying type).  This was fixed in GCC 13.1.
+
+     As a result of this bug, GCC 9 to GCC 12 could calculate an alignment
+     that was too big.  If this happened for TYPE, ABI_BREAK_PACKED is
+     this older, too-big alignment.
+
+     Also, the fact that GCC 9 to GCC 12 considered irrelevant
+     alignments meant they could calculate type alignments that were
+     bigger than the type's size, contrary to the assumption above.
+     The handling of register arguments was nevertheless (and justifiably)
+     written to follow the assumption that the alignment can never be
+     greater than the size.  The same was not true for stack arguments;
+     their alignment was instead handled by MIN bounds in
+     aarch64_function_arg_boundary.
+
+     The net effect is that, if GCC 9 to GCC 12 incorrectly calculated
+     an alignment of more than 16 bytes for TYPE then:
+
+     - If the argument was passed in registers, these GCC versions
+       would treat the alignment as though it was *less than* 16 bytes.
+
+     - If the argument was passed on the stack, these GCC versions
+       would treat the alignment as though it was *equal to* 16 bytes.
+
+     Both behaviors were wrong, but in different cases.  */
   unsigned int alignment
-    = aarch64_function_arg_alignment (mode, type, &abi_break);
-  gcc_assert (!alignment || abi_break < alignment);
+    = aarch64_function_arg_alignment (mode, type, &abi_break,
+				      &abi_break_packed);
+  gcc_assert (alignment <= 16 * BITS_PER_UNIT
+	      && (!alignment || abi_break < alignment)
+	      && (!abi_break_packed || alignment < abi_break_packed));
 
   pcum->aapcs_arg_processed = true;
 
@@ -7488,19 +7561,29 @@ 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.  */
       if (nregs == 2
-	  && ncrn % 2
+	  && ncrn % 2)
+	{
+	  /* Emit a warning if the alignment changed when taking the
+	     'packed' attribute into account.  */
+	  if (warn_pcs_change
+	      && abi_break_packed
+	      && ((abi_break_packed == 16 * BITS_PER_UNIT)
+		  != (alignment == 16 * BITS_PER_UNIT)))
+	    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.  */
-	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
-	      == 16 * BITS_PER_UNIT))
-	{
-	  if (warn_pcs_change && abi_break)
-	    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 (alignment == 16 * BITS_PER_UNIT)
+	    {
+	      if (warn_pcs_change && abi_break)
+		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 an argument with an SVE mode needs to be shifted up to the
@@ -7553,8 +7636,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)
-      == 16 * BITS_PER_UNIT)
+  if (warn_pcs_change
+      && abi_break_packed
+      && ((abi_break_packed >= 16 * BITS_PER_UNIT)
+	  != (alignment >= 16 * BITS_PER_UNIT)))
+    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);
       if (pcum->aapcs_stack_size != new_size)
@@ -7676,16 +7765,13 @@ 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);
+  /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr
+     to emit warnings about ABI incompatibility.  */
   alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
-  if (abi_break && warn_psabi)
-    {
-      abi_break = MIN (MAX (abi_break, PARM_BOUNDARY), STACK_BOUNDARY);
-      if (alignment != abi_break)
-	inform (input_location, "parameter passing for argument of type "
-		"%qT changed in GCC 9.1", type);
-    }
   return alignment;
 }
 
@@ -19544,8 +19630,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;
@@ -19588,6 +19676,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 && abi_break_packed && warn_psabi)
+	inform (input_location, "parameter passing for argument of type "
+		"%qT changed in GCC 13.1", type);
+
       if (align > 8)
 	{
 	  if (abi_break && warn_psabi)
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
index c45be832d5b..443cd458b4c 100644
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
@@ -7,9 +7,9 @@
 #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 *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 12 } } */
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* Bitfield parameter in registers.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
@@ -17,11 +17,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 57 } f8p */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
@@ -29,11 +29,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 66 }  gp */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 67 } g1p */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 68 } g2p */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 69 } g4p */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 70 } g8p */
 
 
 /* Bitfield parameter in stack.  */
@@ -42,11 +42,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
@@ -54,11 +54,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
 /* Bitfield parameter in stdarg.  */
@@ -67,11 +67,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 111 } f8p_stdarg */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
@@ -79,8 +79,8 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 120 }  gp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 121 } g1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 122 } g2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 123 } g4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 124 } g8p_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
index 61d12ec22eb..1359cc6eb49 100644
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
@@ -7,9 +7,9 @@
 #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 *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 12 } } */
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* Bitfield parameter in registers.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
@@ -17,15 +17,9 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) (because the argument fits in a single register).  Should not
-   warn, but aarch64_function_arg_boundary would need to take the argument size
-   into account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the argument fits in a single register.
+   No warning expected.  */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
@@ -43,11 +37,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
@@ -55,11 +49,11 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
 /* Bitfield parameter in stdarg.  */
@@ -68,14 +62,14 @@
 /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
 /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
 
-/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+/* FIXME Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
    Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
    in the callee, but not in the caller.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 111 } f8p_stdarg */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
index 04b183af697..6f8f54f41ff 100644
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
@@ -11,109 +11,96 @@
 /* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
 
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* In f16p (and stdarg version):  */
-/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 } } */
 
-/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
-
-/* In fp_stack, f1p_stack:  */
-/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
-
-/* In f2p_stack:  */
-/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
-
-/* In f4p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, fp_stack,
+   f1p_stack, f2p_stack, f4p_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 10 } } */
 
 /* In f16p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 16\\\]" 1 } } */
 
 /* Bitfield parameter in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 47-51 (f1,
+   f2, f4, f8, f16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) because the argument fits in a single register.  Should not warn,
-   but aarch64_function_arg_boundary would need to take the argument size into
-   account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the alignment that GCC 9.1 calculated for the
+   underlying type was 32 bytes (above the maximum expected of 16).  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 58 } f16p */
 
 
 /* Bitfield call argument in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 60-64 (g1,
+   g2, g4, g8, g16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
-   g4p, g8p), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 66-70 (gp,
+   g1p, g2p, g4p, g8p), no warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 71 } g16p */
 
 
 /* Bitfield parameter in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
-   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 74-78
+   (f1_stack, f2_stack, f4_stack, f8_stack, f16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* Changed in GCC 9.1.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
-/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
-   the overall alignment is >= 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 85
+   (f16p_stack).  No warning expected.  */
 
 
 /* Bitfield call argument in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
-   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC13.1 for lines 87-91
+   (g1_stack, g2_stack, g4_stack, g8_stack, g16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
-/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
-   warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 98
+   (g16p_stack).  No warning expected.  */
 
 
 /* Bitfield parameter in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
-   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 101-105
+   (f1_stdarg, f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1}  "" { target *-*-* } 111 } f8p_stdarg */
 
-/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
-   Should not warn.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 112 (f16p_stdarg).
+   No warning expected.  */
 
 /* Bitfield call argument in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
-   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 114-118
+   (g1_stdarg, g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
-   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 120-124
+   (gp_stdarg, g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning
+   expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 125 } g16p_stdarg */
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
index cdb5b4df774..6b8ad5fbea1 100644
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
@@ -10,110 +10,104 @@
 /* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
 
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* In f16p (and stdarg version):  */
-/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 } } */
 
 /* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 } } */
 
 /* In fp_stack, f1p_stack:  */
-/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 } } */
 
 /* In f2p_stack:  */
-/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 } } */
 
 /* In f4p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 } } */
 
 /* In f16p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 } } */
 
 /* Bitfield parameter in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 47-51 (f1,
+   f2, f4, f8, f16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) because the argument fits in a single register.  Should not warn,
-   but aarch64_function_arg_boundary would need to take the argument size into
-   account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the argument fits in a single register.
+   No warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+/* Changes in GCC 13.1, we restore the same codegen as before GCC 9.1 .  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 58 } f16p */
 
 
 /* Bitfield call argument in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 60-64 (g1,
+   g2, g4, g8, g16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
-   g4p, g8p), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 66-70 (gp,
+   g1p, g2p, g4p, g8p), no warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 71 } g16p */
 
 
 /* Bitfield parameter in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
-   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 74-78
+   (f1_stack, f2_stack, f4_stack, f8_stack, f16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
-/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
-   the overall alignment is >= 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 85
+   (f16p_stack).  No warning expected.  */
 
 /* Bitfield call argument in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
-   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 87-91
+   (g1_stack, g2_stack, g4_stack, g8_stack, g16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
-/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
-   warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 98
+   (g16p_stack).  No warning expected.  */
 
 
 /* Bitfield parameter in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
-   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
-
-/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
-   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
-   in the callee, but not in the caller.  */
-/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
-
-/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
-   Should not warn.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 101-105
+   (f1_stdarg, f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
+
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 13.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 13.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 13.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 13.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 13.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change for line 112 (f16p_stdarg), no warning.  */
 
 /* Bitfield call argument in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
-   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 114-118
+   (g1_stdarg, g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
-   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 120-124
+   (gp_stdarg, g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning
+   expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 13.1} "" { target *-*-* } 125 } g16p_stdarg */
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-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
index 3e38cac149d..f248a129509 100644
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
@@ -7,9 +7,9 @@
 #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 *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 12 } } */
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* Bitfield parameter in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
@@ -17,11 +17,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 53 }  fp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 54 } f1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 55 } f2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 56 } f4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 57 } f8p */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
@@ -29,11 +29,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 66 }  gp */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 67 } g1p */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 68 } g2p */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 69 } g4p */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 70 } g8p */
 
 
 /* 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 } f4_stack */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
@@ -54,11 +54,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
 /* 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 } f4_stdarg */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 111 } f8p_stdarg */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
@@ -79,8 +79,8 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 120 }  gp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 121 } g1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 122 } g2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 123 } g4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 124 } g8p_stdarg */
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 39c5f9228ee..268c7aa90cb 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
@@ -7,9 +7,9 @@
 #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 *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 12 } } */
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* Bitfield parameter in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
@@ -17,15 +17,9 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) (because the argument fits in a single register).  Should not
-   warn, but aarch64_function_arg_boundary would need to take the argument size
-   into account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the argument fits in a single register.
+   No warning expected.  */
 
 /* Bitfield call argument in registers.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
@@ -43,11 +37,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 80 }  fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
 /* Bitfield call argument in stack.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
@@ -55,11 +49,11 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 93 }  gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
 /* Bitfield parameter in stdarg.  */
@@ -68,14 +62,14 @@
 /* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
 /* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
 
-/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
+/* FIXME Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
    Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
    in the callee, but not in the caller.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1} "" { target *-*-* } 107 }  fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 111 } f8p_stdarg */
 
 /* Bitfield call argument in stdarg.  */
 /* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
index 70671ceda09..a8a50b35e8e 100644
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
@@ -11,109 +11,96 @@
 /* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
 
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* In f16p (and stdarg version):  */
-/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 } } */
 
-/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
-
-/* In fp_stack, f1p_stack:  */
-/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
-
-/* In f2p_stack:  */
-/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
-
-/* In f4p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, fp_stack,
+   f1p_stack, f2p_stack, f4p_stack, f8p_stack:  */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 10 } } */
 
 /* In f16p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 16\\\]" 1 } } */
 
 /* Bitfield parameter in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 47-51 (f1,
+   f2, f4, f8, f16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) because the argument fits in a single register.  Should not warn,
-   but aarch64_function_arg_boundary would need to take the argument size into
-   account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the alignment that GCC 9.1 calculated for the
+   underlying type was 32 bytes (above the maximum expected of 16).  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 58 } f16p */
 
 
 /* Bitfield call argument in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 60-64 (g1,
+   g2, g4, g8, g16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
-   g4p, g8p), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 66-70 (gp,
+   g1p, g2p, g4p, g8p), no warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 71 } g16p */
 
 
 /* Bitfield parameter in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
-   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 74-78
+   (f1_stack, f2_stack, f4_stack, f8_stack, f16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* Changed in GCC 9.1.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
-/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
-   the overall alignment is >= 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 85
+   (f16p_stack).  No warning expected.  */
 
 
 /* Bitfield call argument in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
-   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC13.1 for lines 87-91
+   (g1_stack, g2_stack, g4_stack, g8_stack, g16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
-/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
-   warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 98
+   (g16p_stack).  No warning expected.  */
 
 
 /* Bitfield parameter in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
-   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 101-105
+   (f1_stdarg, f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1}  "" { target *-*-* } 111 } f8p_stdarg */
 
-/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
-   Should not warn.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 112 (f16p_stdarg).
+   No warning expected.  */
 
 /* Bitfield call argument in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
-   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 114-118
+   (g1_stdarg, g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
-   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 120-124
+   (gp_stdarg, g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning
+   expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
+/* Changed again in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 125 } g16p_stdarg */
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
index 757a2f1543c..e872de3dbe0 100644
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
@@ -10,110 +10,104 @@
 /* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
 
 /* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
-/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 } } */
 
 /* In f16p (and stdarg version):  */
-/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 } } */
 
 /* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 } } */
 
 /* In fp_stack, f1p_stack:  */
-/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 } } */
 
 /* In f2p_stack:  */
-/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 } } */
 
 /* In f4p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 } } */
 
 /* In f16p_stack:  */
-/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 } } */
 
 /* Bitfield parameter in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 47-51 (f1,
+   f2, f4, f8, f16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
-   f4p, f8p) because the argument fits in a single register.  Should not warn,
-   but aarch64_function_arg_boundary would need to take the argument size into
-   account as well as whether it's passed via registers or the stack.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 53-57 (fp,
+   f1p, f2p, f4p, f8p) because the argument fits in a single register.
+   No warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
+/* Changes in GCC 13.1, we restore the same codegen as before GCC 9.1 .  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 58 } f16p */
 
 
 /* Bitfield call argument in registers.  */
-/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
-   because the overall alignment is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 60-64 (g1,
+   g2, g4, g8, g16) because the overall alignment is > 16.  No warning
+   expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
-   g4p, g8p), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 66-70 (gp,
+   g1p, g2p, g4p, g8p), no warning expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 71 } g16p */
 
 
 /* Bitfield parameter in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
-   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 74-78
+   (f1_stack, f2_stack, f4_stack, f8_stack, f16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}  "" { target *-*-* } 80 } fp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 81 } f1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 82 } f2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 83 } f4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 84 } f8p_stack */
 
-/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
-   the overall alignment is >= 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 85
+   (f16p_stack).  No warning expected.  */
 
 /* Bitfield call argument in stack.  */
-/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
-   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
-   16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 87-91
+   (g1_stack, g2_stack, g4_stack, g8_stack, g16_stack) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}  "" { target *-*-* } 93 } gp_stack */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1} "" { target *-*-* } 94 } g1p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1} "" { target *-*-* } 95 } g2p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1} "" { target *-*-* } 96 } g4p_stack */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1} "" { target *-*-* } 97 } g8p_stack */
 
 
-/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
-   warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for line 98
+   (g16p_stack).  No warning expected.  */
 
 
 /* Bitfield parameter in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
-   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
-
-/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
-   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
-   in the callee, but not in the caller.  */
-/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
-/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
-
-/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
-   Should not warn.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 101-105
+   (f1_stdarg, f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
+
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 13.1}   "" { target *-*-* } 107 } fp_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 13.1}  "" { target *-*-* } 108 } f1p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 13.1}  "" { target *-*-* } 109 } f2p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 13.1}  "" { target *-*-* } 110 } f4p_stdarg */
+/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 13.1}  "" { target *-*-* } 111 } f8p_stdarg */
+
+/* No change for line 112 (f16p_stdarg), no warning.  */
 
 /* Bitfield call argument in stdarg.  */
-/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
-   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
-   is > 16.  No warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 114-118
+   (g1_stdarg, g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall
+   alignment is > 16.  No warning expected.  */
 
-/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
-   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
+/* No change in parameter passing in GCC 9.1 nor GCC 13.1 for lines 120-124
+   (gp_stdarg, g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning
+   expected.  */
 
-/* Changed in GCC 9.1, but we fail to emit a warning.  */
-/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
+/* Changed in GCC 13.1.  */
+/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 13.1} "" { target *-*-* } 125 } g16p_stdarg */
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] 14+ messages in thread

* Re: [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1
  2023-01-11 14:18 [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Christophe Lyon
  2023-01-11 14:18 ` [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
@ 2023-01-12 13:03 ` Richard Sandiford
  2023-01-12 13:39   ` Christophe Lyon
  2023-01-25 14:30   ` Christophe Lyon
  1 sibling, 2 replies; 14+ messages in thread
From: Richard Sandiford @ 2023-01-12 13:03 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc-patches

Christophe Lyon <christophe.lyon@arm.com> writes:
> While looking at PR 105549, which is about fixing the ABI break
> introduced in GCC 9.1 in parameter alignment with bit-fields, we
> 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.
>
> We 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 main idea is to add a new global boolean that indicates whether
> we're expanding the start of a function, so that aarch64_layout_arg
> can emit warnings for callees as well as callers.  This removes the
> need for aarch64_function_arg_boundary to warn (with its incomplete
> information).  However, in the first patch there are still cases where
> we emit warnings were we should not; this is fixed in patch #2 where
> we can distinguish between GCC 9.1 and GCC.13.1 ABI breaks properly.
>
> 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.
>
> 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.
>
> v2->v3: removed a bogus comment, added C++ tests (copied from the C
> ones)
>
> 2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
> 	    Richard Sandiford  <richard.sandiford@arm.com>
>
> gcc/ChangeLog:
>
> 	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Fix
> 	comment.
> 	(aarch64_layout_arg): Factorize warning conditions.
> 	(aarch64_function_arg_boundary): Fix typo.
> 	* function.cc (currently_expanding_function_start): New variable.
> 	(expand_function_start): Handle
> 	currently_expanding_function_start.
> 	* function.h (currently_expanding_function_start): Declare.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: New test.
> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: New
> 	test.
> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: New test.
> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: New
> 	test.
> 	* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: New test.
> 	* gcc.target/aarch64/bitfield-abi-warning.h: New test.
> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: New test.
> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: New
> 	test.
> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: New test.
> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: New
> 	test.
> 	* g++.target/aarch64/bitfield-abi-warning-align8-O2.C: New test.
> 	* g++.target/aarch64/bitfield-abi-warning.h: New test.

OK for trunk, and for backports after a while.  Thanks for doing this,
and for your patience through it all.

Richard

> ---
>  gcc/config/aarch64/aarch64.cc                 |  28 +++-
>  gcc/function.cc                               |   5 +
>  gcc/function.h                                |   2 +
>  .../bitfield-abi-warning-align16-O2-extra.C   |  86 ++++++++++++
>  .../aarch64/bitfield-abi-warning-align16-O2.C |  87 ++++++++++++
>  .../bitfield-abi-warning-align32-O2-extra.C   | 119 +++++++++++++++++
>  .../aarch64/bitfield-abi-warning-align32-O2.C | 119 +++++++++++++++++
>  .../aarch64/bitfield-abi-warning-align8-O2.C  |  16 +++
>  .../g++.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>  .../bitfield-abi-warning-align16-O2-extra.c   |  86 ++++++++++++
>  .../aarch64/bitfield-abi-warning-align16-O2.c |  87 ++++++++++++
>  .../bitfield-abi-warning-align32-O2-extra.c   | 119 +++++++++++++++++
>  .../aarch64/bitfield-abi-warning-align32-O2.c | 119 +++++++++++++++++
>  .../aarch64/bitfield-abi-warning-align8-O2.c  |  16 +++
>  .../gcc.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>  15 files changed, 1132 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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-align32-O2-extra.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.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 ab78b11b158..3623df5bd94 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -7264,9 +7264,9 @@ 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
> -   function for local use only.  */
> +   4.1).  ABI_BREAK is set to the old alignment if the alignment was
> +   incorrectly calculated in versions of GCC prior to GCC-9.  This is
> +   a helper function for local use only.  */
>  
>  static unsigned int
>  aarch64_function_arg_alignment (machine_mode mode, const_tree type,
> @@ -7342,11 +7342,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>    if (pcum->aapcs_arg_processed)
>      return;
>  
> +  bool warn_pcs_change
> +    = (warn_psabi
> +       && !pcum->silent_p
> +       && (currently_expanding_function_start
> +	   || currently_expanding_gimple_stmt));
> +
> +  unsigned int alignment
> +    = aarch64_function_arg_alignment (mode, type, &abi_break);
> +  gcc_assert (!alignment || abi_break < alignment);
> +
>    pcum->aapcs_arg_processed = true;
>  
>    pure_scalable_type_info pst_info;
>    if (type && pst_info.analyze_registers (type))
>      {
> +      /* aarch64_function_arg_alignment has never had an effect on
> +	 this case.  */
> +
>        /* The PCS says that it is invalid to pass an SVE value to an
>  	 unprototyped function.  There is no ABI-defined location we
>  	 can return in this case, so we have no real choice but to raise
> @@ -7417,6 +7430,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>       and homogenous short-vector aggregates (HVA).  */
>    if (allocate_nvrn)
>      {
> +      /* aarch64_function_arg_alignment has never had an effect on
> +	 this case.  */
>        if (!pcum->silent_p && !TARGET_FLOAT)
>  	aarch64_err_no_fpadvsimd (mode);
>  
> @@ -7481,7 +7496,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>  	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
>  	      == 16 * BITS_PER_UNIT))
>  	{
> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
> +	  if (warn_pcs_change && abi_break)
>  	    inform (input_location, "parameter passing for argument of type "
>  		    "%qT changed in GCC 9.1", type);
>  	  ++ncrn;
> @@ -7544,7 +7559,7 @@ on_stack:
>        int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
>        if (pcum->aapcs_stack_size != new_size)
>  	{
> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
> +	  if (warn_pcs_change && abi_break)
>  	    inform (input_location, "parameter passing for argument of type "
>  		    "%qT changed in GCC 9.1", type);
>  	  pcum->aapcs_stack_size = new_size;
> @@ -7664,14 +7679,13 @@ 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)
>  	inform (input_location, "parameter passing for argument of type "
>  		"%qT changed in GCC 9.1", type);
>      }
> -
>    return alignment;
>  }
>  
> diff --git a/gcc/function.cc b/gcc/function.cc
> index d5ed51a6a66..b037e7de31a 100644
> --- a/gcc/function.cc
> +++ b/gcc/function.cc
> @@ -5049,9 +5049,12 @@ stack_protect_epilogue (void)
>     PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
>     the function's parameters, which must be run at any return statement.  */
>  
> +bool currently_expanding_function_start;
>  void
>  expand_function_start (tree subr)
>  {
> +  currently_expanding_function_start = true;
> +
>    /* Make sure volatile mem refs aren't considered
>       valid operands of arithmetic insns.  */
>    init_recog_no_volatile ();
> @@ -5244,6 +5247,8 @@ expand_function_start (tree subr)
>    /* If we are doing generic stack checking, the probe should go here.  */
>    if (flag_stack_check == GENERIC_STACK_CHECK)
>      stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
> +
> +  currently_expanding_function_start = false;
>  }
>  \f
>  void
> diff --git a/gcc/function.h b/gcc/function.h
> index 098613766be..19abc5e7e6e 100644
> --- a/gcc/function.h
> +++ b/gcc/function.h
> @@ -719,4 +719,6 @@ extern const char *current_function_name (void);
>  
>  extern void used_types_insert (tree);
>  
> +extern bool currently_expanding_function_start;
> +
>  #endif  /* GCC_FUNCTION_H */
> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
> new file mode 100644
> index 00000000000..c45be832d5b
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
> @@ -0,0 +1,86 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
> +
> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Bitfield call argument in registers.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* Bitfield call argument in stack.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
> new file mode 100644
> index 00000000000..61d12ec22eb
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
> @@ -0,0 +1,87 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
> +
> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) (because the argument fits in a single register).  Should not
> +   warn, but aarch64_function_arg_boundary would need to take the argument size
> +   into account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Bitfield call argument in registers.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* Bitfield call argument in stack.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
> +
> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
> +   in the callee, but not in the caller.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
> new file mode 100644
> index 00000000000..04b183af697
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
> @@ -0,0 +1,119 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
> +
> +#define ALIGN 32
> +//#define EXTRA
> +
> +#include "bitfield-abi-warning.h"
> +
> +
> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
> +
> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
> +
> +/* In f16p (and stdarg version):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
> +
> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
> +
> +/* In fp_stack, f1p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
> +
> +/* In f2p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f4p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f16p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
> +
> +/* Bitfield parameter in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
> +   but aarch64_function_arg_boundary would need to take the argument size into
> +   account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
> +
> +
> +/* Bitfield call argument in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* Changed in GCC 9.1.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
> +   the overall alignment is >= 16.  No warning expected.  */
> +
> +
> +/* Bitfield call argument in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
> +   warning expected.  */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
> +   Should not warn.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
> new file mode 100644
> index 00000000000..cdb5b4df774
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
> @@ -0,0 +1,119 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
> +
> +#define ALIGN 32
> +#define EXTRA
> +
> +#include "bitfield-abi-warning.h"
> +
> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
> +
> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
> +
> +/* In f16p (and stdarg version):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
> +
> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
> +
> +/* In fp_stack, f1p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
> +
> +/* In f2p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f4p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f16p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
> +
> +/* Bitfield parameter in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
> +   but aarch64_function_arg_boundary would need to take the argument size into
> +   account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
> +
> +
> +/* Bitfield call argument in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
> +   the overall alignment is >= 16.  No warning expected.  */
> +
> +/* Bitfield call argument in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
> +   warning expected.  */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
> +   in the callee, but not in the caller.  */
> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
> +   Should not warn.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
> new file mode 100644
> index 00000000000..b1764d97ea0
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
> +
> +#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/g++.target/aarch64/bitfield-abi-warning.h b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
> new file mode 100644
> index 00000000000..3940b714ef8
> --- /dev/null
> +++ b/gcc/testsuite/g++.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, ull a8, 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, 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)); }
> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
> new file mode 100644
> index 00000000000..3e38cac149d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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 } f1 */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Bitfield call argument in registers.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* Bitfield call argument in stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
> 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..39c5f9228ee
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
> @@ -0,0 +1,87 @@
> +/* { 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 } f1 */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) (because the argument fits in a single register).  Should not
> +   warn, but aarch64_function_arg_boundary would need to take the argument size
> +   into account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Bitfield call argument in registers.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* Bitfield call argument in stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
> +
> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
> +   in the callee, but not in the caller.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
> new file mode 100644
> index 00000000000..70671ceda09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
> @@ -0,0 +1,119 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps" } */
> +
> +#define ALIGN 32
> +//#define EXTRA
> +
> +#include "bitfield-abi-warning.h"
> +
> +
> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
> +
> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
> +
> +/* In f16p (and stdarg version):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
> +
> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
> +
> +/* In fp_stack, f1p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
> +
> +/* In f2p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f4p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f16p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
> +
> +/* Bitfield parameter in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
> +   but aarch64_function_arg_boundary would need to take the argument size into
> +   account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
> +
> +
> +/* Bitfield call argument in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* Changed in GCC 9.1.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
> +   the overall alignment is >= 16.  No warning expected.  */
> +
> +
> +/* Bitfield call argument in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
> +   warning expected.  */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
> +   Should not warn.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
> new file mode 100644
> index 00000000000..757a2f1543c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
> @@ -0,0 +1,119 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -save-temps" } */
> +
> +#define ALIGN 32
> +#define EXTRA
> +
> +#include "bitfield-abi-warning.h"
> +
> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
> +
> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
> +
> +/* In f16p (and stdarg version):  */
> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
> +
> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
> +
> +/* In fp_stack, f1p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
> +
> +/* In f2p_stack:  */
> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f4p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
> +
> +/* In f16p_stack:  */
> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
> +
> +/* Bitfield parameter in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
> +   but aarch64_function_arg_boundary would need to take the argument size into
> +   account as well as whether it's passed via registers or the stack.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
> +
> +
> +/* Bitfield call argument in registers.  */
> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
> +   because the overall alignment is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
> +   g4p, g8p), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
> +
> +
> +/* Bitfield parameter in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
> +
> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
> +   the overall alignment is >= 16.  No warning expected.  */
> +
> +/* Bitfield call argument in stack.  */
> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
> +   16.  No warning expected.  */
> +
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
> +
> +
> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
> +   warning expected.  */
> +
> +
> +/* Bitfield parameter in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
> +   in the callee, but not in the caller.  */
> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
> +
> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
> +   Should not warn.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
> +
> +/* Bitfield call argument in stdarg.  */
> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
> +   is > 16.  No warning expected.  */
> +
> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
> +
> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
> 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..3940b714ef8
> --- /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, ull a8, 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, 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)); }

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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-11 14:18 ` [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
@ 2023-01-12 13:19   ` Richard Sandiford
  2023-01-12 13:38     ` Christophe Lyon
  2023-01-13 15:38   ` Jakub Jelinek
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2023-01-12 13:19 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc-patches

Christophe Lyon <christophe.lyon@arm.com> writes:
> 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 patch also adds a comment and assert that would help someone who
> has to look at this area again.
>
> 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.
>
> v2->v3: testcase update
>
> 2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
> 	    Richard Sandiford  <richard.sandiford@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): Do not warn here.
> 	(aarch64_gimplify_va_arg_expr): Warn when parameter passing ABI
> 	changes.
>
> 	gcc/testsuite/
> 	PR target/105549
> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: Update.
> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: Update.
> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: Update.
> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: Update.
> 	* gcc.target/aarch64/aapcs64/va_arg-17.c: New test.
> 	* gcc.target/aarch64/pr105549.c: New test.
> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: Update.
> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: Update.
> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: Update.
> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: Update.
> ---
>  gcc/config/aarch64/aarch64.cc                 | 148 ++++++++++++++----
>  .../bitfield-abi-warning-align16-O2-extra.C   |  64 ++++----
>  .../aarch64/bitfield-abi-warning-align16-O2.C |  48 +++---
>  .../bitfield-abi-warning-align32-O2-extra.C   | 131 +++++++---------
>  .../aarch64/bitfield-abi-warning-align32-O2.C | 132 ++++++++--------
>  .../gcc.target/aarch64/aapcs64/va_arg-17.c    | 105 +++++++++++++
>  .../bitfield-abi-warning-align16-O2-extra.c   |  64 ++++----
>  .../aarch64/bitfield-abi-warning-align16-O2.c |  48 +++---
>  .../bitfield-abi-warning-align32-O2-extra.c   | 131 +++++++---------
>  .../aarch64/bitfield-abi-warning-align32-O2.c | 132 ++++++++--------
>  gcc/testsuite/gcc.target/aarch64/pr105549.c   |  12 ++
>  11 files changed, 587 insertions(+), 428 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/pr105549.c
> [...]
> @@ -68,14 +62,14 @@
>  /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>  /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>  
> -/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
> +/* FIXME Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>     Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>     in the callee, but not in the caller.  */

Looks like a stray change.  Same for the C test.

OK otherwise, thanks.

Richard

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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-12 13:19   ` Richard Sandiford
@ 2023-01-12 13:38     ` Christophe Lyon
  0 siblings, 0 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-12 13:38 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford



On 1/12/23 14:19, Richard Sandiford wrote:
> Christophe Lyon <christophe.lyon@arm.com> writes:
>> 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 patch also adds a comment and assert that would help someone who
>> has to look at this area again.
>>
>> 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.
>>
>> v2->v3: testcase update
>>
>> 2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
>> 	    Richard Sandiford  <richard.sandiford@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): Do not warn here.
>> 	(aarch64_gimplify_va_arg_expr): Warn when parameter passing ABI
>> 	changes.
>>
>> 	gcc/testsuite/
>> 	PR target/105549
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: Update.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: Update.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: Update.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: Update.
>> 	* gcc.target/aarch64/aapcs64/va_arg-17.c: New test.
>> 	* gcc.target/aarch64/pr105549.c: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: Update.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: Update.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: Update.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: Update.
>> ---
>>   gcc/config/aarch64/aarch64.cc                 | 148 ++++++++++++++----
>>   .../bitfield-abi-warning-align16-O2-extra.C   |  64 ++++----
>>   .../aarch64/bitfield-abi-warning-align16-O2.C |  48 +++---
>>   .../bitfield-abi-warning-align32-O2-extra.C   | 131 +++++++---------
>>   .../aarch64/bitfield-abi-warning-align32-O2.C | 132 ++++++++--------
>>   .../gcc.target/aarch64/aapcs64/va_arg-17.c    | 105 +++++++++++++
>>   .../bitfield-abi-warning-align16-O2-extra.c   |  64 ++++----
>>   .../aarch64/bitfield-abi-warning-align16-O2.c |  48 +++---
>>   .../bitfield-abi-warning-align32-O2-extra.c   | 131 +++++++---------
>>   .../aarch64/bitfield-abi-warning-align32-O2.c | 132 ++++++++--------
>>   gcc/testsuite/gcc.target/aarch64/pr105549.c   |  12 ++
>>   11 files changed, 587 insertions(+), 428 deletions(-)
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-17.c
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/pr105549.c
>> [...]
>> @@ -68,14 +62,14 @@
>>   /* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>>   /* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>>   
>> -/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +/* FIXME Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>>      Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>>      in the callee, but not in the caller.  */
> 
> Looks like a stray change.  Same for the C test.

Ha yes, thanks for catching this!

> 
> OK otherwise, thanks.
> 
> Richard

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

* Re: [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1
  2023-01-12 13:03 ` [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Richard Sandiford
@ 2023-01-12 13:39   ` Christophe Lyon
  2023-01-25 14:30   ` Christophe Lyon
  1 sibling, 0 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-12 13:39 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford



On 1/12/23 14:03, Richard Sandiford wrote:
> Christophe Lyon <christophe.lyon@arm.com> writes:
>> While looking at PR 105549, which is about fixing the ABI break
>> introduced in GCC 9.1 in parameter alignment with bit-fields, we
>> 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.
>>
>> We 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 main idea is to add a new global boolean that indicates whether
>> we're expanding the start of a function, so that aarch64_layout_arg
>> can emit warnings for callees as well as callers.  This removes the
>> need for aarch64_function_arg_boundary to warn (with its incomplete
>> information).  However, in the first patch there are still cases where
>> we emit warnings were we should not; this is fixed in patch #2 where
>> we can distinguish between GCC 9.1 and GCC.13.1 ABI breaks properly.
>>
>> 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.
>>
>> 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.
>>
>> v2->v3: removed a bogus comment, added C++ tests (copied from the C
>> ones)
>>
>> 2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
>> 	    Richard Sandiford  <richard.sandiford@arm.com>
>>
>> gcc/ChangeLog:
>>
>> 	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Fix
>> 	comment.
>> 	(aarch64_layout_arg): Factorize warning conditions.
>> 	(aarch64_function_arg_boundary): Fix typo.
>> 	* function.cc (currently_expanding_function_start): New variable.
>> 	(expand_function_start): Handle
>> 	currently_expanding_function_start.
>> 	* function.h (currently_expanding_function_start): Declare.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: New
>> 	test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: New
>> 	test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning.h: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: New
>> 	test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: New
>> 	test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align8-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning.h: New test.
> 
> OK for trunk, and for backports after a while.  Thanks for doing this,
> and for your patience through it all.

Great, and thanks for your help & patience too :-)

Christophe

> 
> Richard
> 
>> ---
>>   gcc/config/aarch64/aarch64.cc                 |  28 +++-
>>   gcc/function.cc                               |   5 +
>>   gcc/function.h                                |   2 +
>>   .../bitfield-abi-warning-align16-O2-extra.C   |  86 ++++++++++++
>>   .../aarch64/bitfield-abi-warning-align16-O2.C |  87 ++++++++++++
>>   .../bitfield-abi-warning-align32-O2-extra.C   | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align32-O2.C | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align8-O2.C  |  16 +++
>>   .../g++.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>>   .../bitfield-abi-warning-align16-O2-extra.c   |  86 ++++++++++++
>>   .../aarch64/bitfield-abi-warning-align16-O2.c |  87 ++++++++++++
>>   .../bitfield-abi-warning-align32-O2-extra.c   | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align32-O2.c | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align8-O2.c  |  16 +++
>>   .../gcc.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>>   15 files changed, 1132 insertions(+), 7 deletions(-)
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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-align32-O2-extra.c
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.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 ab78b11b158..3623df5bd94 100644
>> --- a/gcc/config/aarch64/aarch64.cc
>> +++ b/gcc/config/aarch64/aarch64.cc
>> @@ -7264,9 +7264,9 @@ 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
>> -   function for local use only.  */
>> +   4.1).  ABI_BREAK is set to the old alignment if the alignment was
>> +   incorrectly calculated in versions of GCC prior to GCC-9.  This is
>> +   a helper function for local use only.  */
>>   
>>   static unsigned int
>>   aarch64_function_arg_alignment (machine_mode mode, const_tree type,
>> @@ -7342,11 +7342,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>     if (pcum->aapcs_arg_processed)
>>       return;
>>   
>> +  bool warn_pcs_change
>> +    = (warn_psabi
>> +       && !pcum->silent_p
>> +       && (currently_expanding_function_start
>> +	   || currently_expanding_gimple_stmt));
>> +
>> +  unsigned int alignment
>> +    = aarch64_function_arg_alignment (mode, type, &abi_break);
>> +  gcc_assert (!alignment || abi_break < alignment);
>> +
>>     pcum->aapcs_arg_processed = true;
>>   
>>     pure_scalable_type_info pst_info;
>>     if (type && pst_info.analyze_registers (type))
>>       {
>> +      /* aarch64_function_arg_alignment has never had an effect on
>> +	 this case.  */
>> +
>>         /* The PCS says that it is invalid to pass an SVE value to an
>>   	 unprototyped function.  There is no ABI-defined location we
>>   	 can return in this case, so we have no real choice but to raise
>> @@ -7417,6 +7430,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>        and homogenous short-vector aggregates (HVA).  */
>>     if (allocate_nvrn)
>>       {
>> +      /* aarch64_function_arg_alignment has never had an effect on
>> +	 this case.  */
>>         if (!pcum->silent_p && !TARGET_FLOAT)
>>   	aarch64_err_no_fpadvsimd (mode);
>>   
>> @@ -7481,7 +7496,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>   	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
>>   	      == 16 * BITS_PER_UNIT))
>>   	{
>> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
>> +	  if (warn_pcs_change && abi_break)
>>   	    inform (input_location, "parameter passing for argument of type "
>>   		    "%qT changed in GCC 9.1", type);
>>   	  ++ncrn;
>> @@ -7544,7 +7559,7 @@ on_stack:
>>         int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
>>         if (pcum->aapcs_stack_size != new_size)
>>   	{
>> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
>> +	  if (warn_pcs_change && abi_break)
>>   	    inform (input_location, "parameter passing for argument of type "
>>   		    "%qT changed in GCC 9.1", type);
>>   	  pcum->aapcs_stack_size = new_size;
>> @@ -7664,14 +7679,13 @@ 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)
>>   	inform (input_location, "parameter passing for argument of type "
>>   		"%qT changed in GCC 9.1", type);
>>       }
>> -
>>     return alignment;
>>   }
>>   
>> diff --git a/gcc/function.cc b/gcc/function.cc
>> index d5ed51a6a66..b037e7de31a 100644
>> --- a/gcc/function.cc
>> +++ b/gcc/function.cc
>> @@ -5049,9 +5049,12 @@ stack_protect_epilogue (void)
>>      PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
>>      the function's parameters, which must be run at any return statement.  */
>>   
>> +bool currently_expanding_function_start;
>>   void
>>   expand_function_start (tree subr)
>>   {
>> +  currently_expanding_function_start = true;
>> +
>>     /* Make sure volatile mem refs aren't considered
>>        valid operands of arithmetic insns.  */
>>     init_recog_no_volatile ();
>> @@ -5244,6 +5247,8 @@ expand_function_start (tree subr)
>>     /* If we are doing generic stack checking, the probe should go here.  */
>>     if (flag_stack_check == GENERIC_STACK_CHECK)
>>       stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
>> +
>> +  currently_expanding_function_start = false;
>>   }
>>   \f
>>   void
>> diff --git a/gcc/function.h b/gcc/function.h
>> index 098613766be..19abc5e7e6e 100644
>> --- a/gcc/function.h
>> +++ b/gcc/function.h
>> @@ -719,4 +719,6 @@ extern const char *current_function_name (void);
>>   
>>   extern void used_types_insert (tree);
>>   
>> +extern bool currently_expanding_function_start;
>> +
>>   #endif  /* GCC_FUNCTION_H */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>> new file mode 100644
>> index 00000000000..c45be832d5b
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>> @@ -0,0 +1,86 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>> new file mode 100644
>> index 00000000000..61d12ec22eb
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>> @@ -0,0 +1,87 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) (because the argument fits in a single register).  Should not
>> +   warn, but aarch64_function_arg_boundary would need to take the argument size
>> +   into account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>> new file mode 100644
>> index 00000000000..04b183af697
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#define ALIGN 32
>> +//#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* Changed in GCC 9.1.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>> new file mode 100644
>> index 00000000000..cdb5b4df774
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#define ALIGN 32
>> +#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>> new file mode 100644
>> index 00000000000..b1764d97ea0
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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/g++.target/aarch64/bitfield-abi-warning.h b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
>> new file mode 100644
>> index 00000000000..3940b714ef8
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.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, ull a8, 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, 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)); }
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
>> new file mode 100644
>> index 00000000000..3e38cac149d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
>> 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..39c5f9228ee
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
>> @@ -0,0 +1,87 @@
>> +/* { 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 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) (because the argument fits in a single register).  Should not
>> +   warn, but aarch64_function_arg_boundary would need to take the argument size
>> +   into account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
>> new file mode 100644
>> index 00000000000..70671ceda09
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps" } */
>> +
>> +#define ALIGN 32
>> +//#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* Changed in GCC 9.1.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
>> new file mode 100644
>> index 00000000000..757a2f1543c
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps" } */
>> +
>> +#define ALIGN 32
>> +#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> 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..3940b714ef8
>> --- /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, ull a8, 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, 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)); }

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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-11 14:18 ` [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
  2023-01-12 13:19   ` Richard Sandiford
@ 2023-01-13 15:38   ` Jakub Jelinek
  2023-01-13 19:25     ` Jakub Jelinek
  2023-01-15 16:54     ` Christophe Lyon
  1 sibling, 2 replies; 14+ messages in thread
From: Jakub Jelinek @ 2023-01-13 15:38 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc-patches, richard.sandiford

On Wed, Jan 11, 2023 at 03:18:06PM +0100, Christophe Lyon via Gcc-patches wrote:
> 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 patch also adds a comment and assert that would help someone who
> has to look at this area again.
> 
> 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.

I'm seeing
+FAIL: g++.target/aarch64/bitfield-abi-warning-align16-O2.C scan-assembler-times and\\tw0, w1, 1 10
+FAIL: g++.target/aarch64/bitfield-abi-warning-align32-O2.C scan-assembler-times and\\tw0, w1, 1 10
+FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w0, 1 11
+FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w1, 1 18
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (test for excess errors)
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (test for excess errors)
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
+FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (test for excess errors)
regressions with this change.

aarch64.cc:7696 is for me the newly added:

> +  gcc_assert (alignment <= 16 * BITS_PER_UNIT
> +	      && (!alignment || abi_break < alignment)
> +	      && (!abi_break_packed || alignment < abi_break_packed));

assert.
Details in
https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
(configure line etc.), plus if you
wget https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
sed -n '/^begin /,/^end/p' build.log | uuencode
you get a compressed tarball with the testsuite *.log files.

	Jakub


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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-13 15:38   ` Jakub Jelinek
@ 2023-01-13 19:25     ` Jakub Jelinek
  2023-01-13 19:50       ` Jakub Jelinek
  2023-01-15 16:54     ` Christophe Lyon
  1 sibling, 1 reply; 14+ messages in thread
From: Jakub Jelinek @ 2023-01-13 19:25 UTC (permalink / raw)
  To: Christophe Lyon, gcc-patches, richard.sandiford

On Fri, Jan 13, 2023 at 04:38:00PM +0100, Jakub Jelinek via Gcc-patches wrote:
> I'm seeing
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align16-O2.C scan-assembler-times and\\tw0, w1, 1 10
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align32-O2.C scan-assembler-times and\\tw0, w1, 1 10
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w0, 1 11
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w1, 1 18

The above seems only because I'm testing with 

> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (test for excess errors)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (test for excess errors)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (test for excess errors)
> regressions with this change.

But these I can reproduce using a cross compiler on current trunk:
#0  fancy_abort (file=0x2da73c0 "../../gcc/config/aarch64/aarch64.cc", line=7710, function=0x2da8917 "aarch64_layout_arg") at ../../gcc/diagnostic.cc:2219
#1  0x0000000001a8756b in aarch64_layout_arg (pcum_v=..., arg=...) at ../../gcc/config/aarch64/aarch64.cc:7710
#2  0x0000000001a88477 in aarch64_function_arg_advance (pcum_v=..., arg=...) at ../../gcc/config/aarch64/aarch64.cc:8023
#3  0x000000000107cb17 in gimplify_parameters (cleanup=0x7fffffffd8c0) at ../../gcc/function.cc:3929
#4  0x0000000001156366 in gimplify_body (fndecl=<function_decl 0x7fffe985b900 sel2_pst_uniform4>, do_parms=true) at ../../gcc/gimplify.cc:17619
#5  0x0000000001156ca0 in gimplify_function_tree (fndecl=<function_decl 0x7fffe985b900 sel2_pst_uniform4>) at ../../gcc/gimplify.cc:17822
#6  0x0000000000ea2402 in cgraph_node::analyze (this=<cgraph_node * const 0x7fffe985f220 "sel2_pst_uniform4"/39>) at ../../gcc/cgraphunit.cc:676
#7  0x0000000000ea4489 in analyze_functions (first_time=true) at ../../gcc/cgraphunit.cc:1240
#8  0x0000000000ea7a06 in symbol_table::finalize_compilation_unit (this=0x7fffea38b000) at ../../gcc/cgraphunit.cc:2547
#9  0x0000000001572df1 in compile_file () at ../../gcc/toplev.cc:471
#10 0x0000000001575caf in do_compile (no_backend=false) at ../../gcc/toplev.cc:2125
#11 0x0000000001576078 in toplev::main (this=0x7fffffffdc6a, argc=14, argv=0x7fffffffdd98) at ../../gcc/toplev.cc:2277
#12 0x0000000002a81c6a in main (argc=14, argv=0x7fffffffdd98) at ../../gcc/main.cc:39

alignment is 256, which is not <= 16 * BITS_PER_UNIT.
type is pst_uniform4 with user alignment of 32 bytes:
struct pst_uniform4
{
  fixed_int32_t a __attribute__((aligned(SVE_BYTES * 2)));
  fixed_int32_t b[3] __attribute__((aligned(SVE_BYTES * 2)));
  fixed_int32_t c __attribute__((aligned(SVE_BYTES * 2)));
};
and with -march=armv8.2-a+sve -msve-vector-bits=128
__ARM_FEATURE_SVE_BITS and therefore SVE_BYTES is 128 and so
the alignment seems requested.

	Jakub


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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-13 19:25     ` Jakub Jelinek
@ 2023-01-13 19:50       ` Jakub Jelinek
  0 siblings, 0 replies; 14+ messages in thread
From: Jakub Jelinek @ 2023-01-13 19:50 UTC (permalink / raw)
  To: Christophe Lyon, gcc-patches, richard.sandiford

On Fri, Jan 13, 2023 at 08:25:01PM +0100, Jakub Jelinek via Gcc-patches wrote:
> alignment is 256, which is not <= 16 * BITS_PER_UNIT.
> type is pst_uniform4 with user alignment of 32 bytes:
> struct pst_uniform4
> {
>   fixed_int32_t a __attribute__((aligned(SVE_BYTES * 2)));
>   fixed_int32_t b[3] __attribute__((aligned(SVE_BYTES * 2)));
>   fixed_int32_t c __attribute__((aligned(SVE_BYTES * 2)));
> };
> and with -march=armv8.2-a+sve -msve-vector-bits=128
> __ARM_FEATURE_SVE_BITS and therefore SVE_BYTES is 128 and so
> the alignment seems requested.

typedef __SVInt32_t fixed_int32_t __attribute__ ((arm_sve_vector_bits (128)));
struct A { fixed_int32_t a[3] __attribute__((aligned((128 / 8) * 2))); };
void foo (struct A x) {}

-march=armv8.2-a+sve -O -msve-vector-bits=128

reproduces it too.

	Jakub


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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-13 15:38   ` Jakub Jelinek
  2023-01-13 19:25     ` Jakub Jelinek
@ 2023-01-15 16:54     ` Christophe Lyon
  2023-01-17 12:43       ` Christophe Lyon
  1 sibling, 1 reply; 14+ messages in thread
From: Christophe Lyon @ 2023-01-15 16:54 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, richard.sandiford

Hi!


On 1/13/23 16:38, Jakub Jelinek wrote:
> On Wed, Jan 11, 2023 at 03:18:06PM +0100, Christophe Lyon via Gcc-patches wrote:
>> 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 patch also adds a comment and assert that would help someone who
>> has to look at this area again.
>>
>> 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.
> 
> I'm seeing
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align16-O2.C scan-assembler-times and\\tw0, w1, 1 10
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align32-O2.C scan-assembler-times and\\tw0, w1, 1 10
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w0, 1 11
> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C scan-assembler-times and\\tw0, w1, 1 18
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve (test for excess errors)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve (test for excess errors)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (internal compiler error: in aarch64_layout_arg, at config/aarch64/aarch64.cc:7696)
> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve (test for excess errors)
> regressions with this change.
> 

Really deeply sorry for this :-(


> aarch64.cc:7696 is for me the newly added:
> 
>> +  gcc_assert (alignment <= 16 * BITS_PER_UNIT
>> +	      && (!alignment || abi_break < alignment)
>> +	      && (!abi_break_packed || alignment < abi_break_packed));
> 
> assert.
> Details in
> https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
> (configure line etc.), plus if you
> wget https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
> sed -n '/^begin /,/^end/p' build.log | uuencode > you get a compressed tarball with the testsuite *.log files.

Thanks I managed to download this (you meant uudecode rather than 
uuencode ;-) )

I see the scan-assembler-times are also failing in gcc.target, I guess 
you just forgot to paste them?

 From your other message, it seems you are building with stack-protector 
enabled by default, but I can't see that in the configure lines?

Indeed I just checked the generated code with/without 
-fstack-protector-all, and it obviously changes a lot, thus breaking the 
fragile scan-assembler directives. As you said, it's easy to avoid with 
-fno-stack-protector.

I'll check the problem with the assert.

Thanks and sorry,

Christophe

> 
> 	Jakub
> 

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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-15 16:54     ` Christophe Lyon
@ 2023-01-17 12:43       ` Christophe Lyon
  2023-01-17 12:48         ` Jakub Jelinek
  0 siblings, 1 reply; 14+ messages in thread
From: Christophe Lyon @ 2023-01-17 12:43 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, richard.sandiford

Hi Jakub,

On 1/15/23 17:54, Christophe Lyon via Gcc-patches wrote:
> Hi!
> 
> 
> On 1/13/23 16:38, Jakub Jelinek wrote:
>> On Wed, Jan 11, 2023 at 03:18:06PM +0100, Christophe Lyon via 
>> Gcc-patches wrote:
>>> 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 patch also adds a comment and assert that would help someone who
>>> has to look at this area again.
>>>
>>> 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.
>>
>> I'm seeing
>> +FAIL: g++.target/aarch64/bitfield-abi-warning-align16-O2.C 
>> scan-assembler-times and\\tw0, w1, 1 10
>> +FAIL: g++.target/aarch64/bitfield-abi-warning-align32-O2.C 
>> scan-assembler-times and\\tw0, w1, 1 10
>> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C 
>> scan-assembler-times and\\tw0, w0, 1 11
>> +FAIL: g++.target/aarch64/bitfield-abi-warning-align8-O2.C 
>> scan-assembler-times and\\tw0, w1, 1 18
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve 
>> (internal compiler error: in aarch64_layout_arg, at 
>> config/aarch64/aarch64.cc:7696)
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_128.c -march=armv8.2-a+sve 
>> (test for excess errors)
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve 
>> (internal compiler error: in aarch64_layout_arg, at 
>> config/aarch64/aarch64.cc:7696)
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_256.c -march=armv8.2-a+sve 
>> (test for excess errors)
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve 
>> (internal compiler error: in aarch64_layout_arg, at 
>> config/aarch64/aarch64.cc:7696)
>> +FAIL: gcc.target/aarch64/sve/pcs/struct_3_512.c -march=armv8.2-a+sve 
>> (test for excess errors)
>> regressions with this change.
>>
> 
> Really deeply sorry for this :-(
> 
> 
>> aarch64.cc:7696 is for me the newly added:
>>
>>> +  gcc_assert (alignment <= 16 * BITS_PER_UNIT
>>> +          && (!alignment || abi_break < alignment)
>>> +          && (!abi_break_packed || alignment < abi_break_packed));
>>
>> assert.
>> Details in
>> https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
>> (configure line etc.), plus if you
>> wget 
>> https://kojipkgs.fedoraproject.org//work/tasks/2857/96062857/build.log
>> sed -n '/^begin /,/^end/p' build.log | uuencode > you get a compressed 
>> tarball with the testsuite *.log files.
> 
> Thanks I managed to download this (you meant uudecode rather than 
> uuencode ;-) )
> 
> I see the scan-assembler-times are also failing in gcc.target, I guess 
> you just forgot to paste them?
> 
>  From your other message, it seems you are building with stack-protector 
> enabled by default, but I can't see that in the configure lines?
> 
> Indeed I just checked the generated code with/without 
> -fstack-protector-all, and it obviously changes a lot, thus breaking the 
> fragile scan-assembler directives. As you said, it's easy to avoid with 
> -fno-stack-protector.
> 

As a follow-up to this, I ran the full testsuite with 
-fstack-protector-all and this results in lots of failures (~65000 in 
gcc.sum alone).

Since you also mentioned -fstack-protector-strong, I ran the full 
testsuite with it, which results in more failures too but the difference 
is much smaller than with -fstack-protector=all (from 126 FAIL to 309)

For instance, I see many failures with -fstack-protector-strong in:
gcc.target/aarch64/sve/pcs/
It looks like you have them too, according to the logs I downloaded from 
your link above.

So is it worth adding -fno-stack-protector to my few new testcases?
(I can, no problem, but just wondering why you appear to notice the 
problem with my new tests, and not with the ones in 
gcc.target/aarch64/sve/pcs/)

Thanks,

Christophe

> I'll check the problem with the assert.
> 
> Thanks and sorry,
> 
> Christophe
> 
>>
>>     Jakub
>>

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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-17 12:43       ` Christophe Lyon
@ 2023-01-17 12:48         ` Jakub Jelinek
  2023-01-17 12:50           ` Christophe Lyon
  0 siblings, 1 reply; 14+ messages in thread
From: Jakub Jelinek @ 2023-01-17 12:48 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc-patches, richard.sandiford

On Tue, Jan 17, 2023 at 01:43:35PM +0100, Christophe Lyon wrote:
> As a follow-up to this, I ran the full testsuite with -fstack-protector-all
> and this results in lots of failures (~65000 in gcc.sum alone).

I guess that is way too much.

> Since you also mentioned -fstack-protector-strong, I ran the full testsuite
> with it, which results in more failures too but the difference is much
> smaller than with -fstack-protector=all (from 126 FAIL to 309)

But this could be doable by adding explicit -fno-stack-protector options
to test that can't handle those.

> For instance, I see many failures with -fstack-protector-strong in:
> gcc.target/aarch64/sve/pcs/
> It looks like you have them too, according to the logs I downloaded from
> your link above.
> 
> So is it worth adding -fno-stack-protector to my few new testcases?
> (I can, no problem, but just wondering why you appear to notice the problem
> with my new tests, and not with the ones in gcc.target/aarch64/sve/pcs/)

Because I mainly look for regressions (compare the test_summary
dumps against older gcc build); if something fails for years, it doesn't
show up in the regression diffs.

	Jakub


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

* Re: [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549]
  2023-01-17 12:48         ` Jakub Jelinek
@ 2023-01-17 12:50           ` Christophe Lyon
  0 siblings, 0 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-17 12:50 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, richard.sandiford



On 1/17/23 13:48, Jakub Jelinek wrote:
> On Tue, Jan 17, 2023 at 01:43:35PM +0100, Christophe Lyon wrote:
>> As a follow-up to this, I ran the full testsuite with -fstack-protector-all
>> and this results in lots of failures (~65000 in gcc.sum alone).
> 
> I guess that is way too much.
> 
>> Since you also mentioned -fstack-protector-strong, I ran the full testsuite
>> with it, which results in more failures too but the difference is much
>> smaller than with -fstack-protector=all (from 126 FAIL to 309)
> 
> But this could be doable by adding explicit -fno-stack-protector options
> to test that can't handle those.
> 
>> For instance, I see many failures with -fstack-protector-strong in:
>> gcc.target/aarch64/sve/pcs/
>> It looks like you have them too, according to the logs I downloaded from
>> your link above.
>>
>> So is it worth adding -fno-stack-protector to my few new testcases?
>> (I can, no problem, but just wondering why you appear to notice the problem
>> with my new tests, and not with the ones in gcc.target/aarch64/sve/pcs/)
> 
> Because I mainly look for regressions (compare the test_summary
> dumps against older gcc build); if something fails for years, it doesn't
> show up in the regression diffs.
> 

OK that's what I thought, thanks for confirming.

I'll add -fno-stack-protector to my tests.

Thanks,

Christophe

> 	Jakub
> 

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

* Re: [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1
  2023-01-12 13:03 ` [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Richard Sandiford
  2023-01-12 13:39   ` Christophe Lyon
@ 2023-01-25 14:30   ` Christophe Lyon
  1 sibling, 0 replies; 14+ messages in thread
From: Christophe Lyon @ 2023-01-25 14:30 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford



On 1/12/23 14:03, Richard Sandiford wrote:
> Christophe Lyon <christophe.lyon@arm.com> writes:
>> While looking at PR 105549, which is about fixing the ABI break
>> introduced in GCC 9.1 in parameter alignment with bit-fields, we
>> 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.
>>
>> We 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 main idea is to add a new global boolean that indicates whether
>> we're expanding the start of a function, so that aarch64_layout_arg
>> can emit warnings for callees as well as callers.  This removes the
>> need for aarch64_function_arg_boundary to warn (with its incomplete
>> information).  However, in the first patch there are still cases where
>> we emit warnings were we should not; this is fixed in patch #2 where
>> we can distinguish between GCC 9.1 and GCC.13.1 ABI breaks properly.
>>
>> 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.
>>
>> 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.
>>
>> v2->v3: removed a bogus comment, added C++ tests (copied from the C
>> ones)
>>
>> 2022-11-28  Christophe Lyon  <christophe.lyon@arm.com>
>> 	    Richard Sandiford  <richard.sandiford@arm.com>
>>
>> gcc/ChangeLog:
>>
>> 	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Fix
>> 	comment.
>> 	(aarch64_layout_arg): Factorize warning conditions.
>> 	(aarch64_function_arg_boundary): Fix typo.
>> 	* function.cc (currently_expanding_function_start): New variable.
>> 	(expand_function_start): Handle
>> 	currently_expanding_function_start.
>> 	* function.h (currently_expanding_function_start): Declare.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: New
>> 	test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: New
>> 	test.
>> 	* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: New test.
>> 	* gcc.target/aarch64/bitfield-abi-warning.h: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: New
>> 	test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: New
>> 	test.
>> 	* g++.target/aarch64/bitfield-abi-warning-align8-O2.C: New test.
>> 	* g++.target/aarch64/bitfield-abi-warning.h: New test.
> 
> OK for trunk, and for backports after a while.  Thanks for doing this,
> and for your patience through it all.
> 

I've just backported this patch (only, not the other ones which were not 
intended for backport)
- gcc-12: applied cleanly
- gcc-11: applied cleany but I had to replace dg-note with dg-message in 
the tests
- gcc-10: a small conflict, and I had to replace dg-note with dg-message 
in the tests

Thanks,

Christophe

> Richard
> 
>> ---
>>   gcc/config/aarch64/aarch64.cc                 |  28 +++-
>>   gcc/function.cc                               |   5 +
>>   gcc/function.h                                |   2 +
>>   .../bitfield-abi-warning-align16-O2-extra.C   |  86 ++++++++++++
>>   .../aarch64/bitfield-abi-warning-align16-O2.C |  87 ++++++++++++
>>   .../bitfield-abi-warning-align32-O2-extra.C   | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align32-O2.C | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align8-O2.C  |  16 +++
>>   .../g++.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>>   .../bitfield-abi-warning-align16-O2-extra.c   |  86 ++++++++++++
>>   .../aarch64/bitfield-abi-warning-align16-O2.c |  87 ++++++++++++
>>   .../bitfield-abi-warning-align32-O2-extra.c   | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align32-O2.c | 119 +++++++++++++++++
>>   .../aarch64/bitfield-abi-warning-align8-O2.c  |  16 +++
>>   .../gcc.target/aarch64/bitfield-abi-warning.h | 125 ++++++++++++++++++
>>   15 files changed, 1132 insertions(+), 7 deletions(-)
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>>   create mode 100644 gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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-align32-O2-extra.c
>>   create mode 100644 gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.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 ab78b11b158..3623df5bd94 100644
>> --- a/gcc/config/aarch64/aarch64.cc
>> +++ b/gcc/config/aarch64/aarch64.cc
>> @@ -7264,9 +7264,9 @@ 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
>> -   function for local use only.  */
>> +   4.1).  ABI_BREAK is set to the old alignment if the alignment was
>> +   incorrectly calculated in versions of GCC prior to GCC-9.  This is
>> +   a helper function for local use only.  */
>>   
>>   static unsigned int
>>   aarch64_function_arg_alignment (machine_mode mode, const_tree type,
>> @@ -7342,11 +7342,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>     if (pcum->aapcs_arg_processed)
>>       return;
>>   
>> +  bool warn_pcs_change
>> +    = (warn_psabi
>> +       && !pcum->silent_p
>> +       && (currently_expanding_function_start
>> +	   || currently_expanding_gimple_stmt));
>> +
>> +  unsigned int alignment
>> +    = aarch64_function_arg_alignment (mode, type, &abi_break);
>> +  gcc_assert (!alignment || abi_break < alignment);
>> +
>>     pcum->aapcs_arg_processed = true;
>>   
>>     pure_scalable_type_info pst_info;
>>     if (type && pst_info.analyze_registers (type))
>>       {
>> +      /* aarch64_function_arg_alignment has never had an effect on
>> +	 this case.  */
>> +
>>         /* The PCS says that it is invalid to pass an SVE value to an
>>   	 unprototyped function.  There is no ABI-defined location we
>>   	 can return in this case, so we have no real choice but to raise
>> @@ -7417,6 +7430,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>        and homogenous short-vector aggregates (HVA).  */
>>     if (allocate_nvrn)
>>       {
>> +      /* aarch64_function_arg_alignment has never had an effect on
>> +	 this case.  */
>>         if (!pcum->silent_p && !TARGET_FLOAT)
>>   	aarch64_err_no_fpadvsimd (mode);
>>   
>> @@ -7481,7 +7496,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>>   	  && (aarch64_function_arg_alignment (mode, type, &abi_break)
>>   	      == 16 * BITS_PER_UNIT))
>>   	{
>> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
>> +	  if (warn_pcs_change && abi_break)
>>   	    inform (input_location, "parameter passing for argument of type "
>>   		    "%qT changed in GCC 9.1", type);
>>   	  ++ncrn;
>> @@ -7544,7 +7559,7 @@ on_stack:
>>         int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
>>         if (pcum->aapcs_stack_size != new_size)
>>   	{
>> -	  if (abi_break && warn_psabi && currently_expanding_gimple_stmt)
>> +	  if (warn_pcs_change && abi_break)
>>   	    inform (input_location, "parameter passing for argument of type "
>>   		    "%qT changed in GCC 9.1", type);
>>   	  pcum->aapcs_stack_size = new_size;
>> @@ -7664,14 +7679,13 @@ 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)
>>   	inform (input_location, "parameter passing for argument of type "
>>   		"%qT changed in GCC 9.1", type);
>>       }
>> -
>>     return alignment;
>>   }
>>   
>> diff --git a/gcc/function.cc b/gcc/function.cc
>> index d5ed51a6a66..b037e7de31a 100644
>> --- a/gcc/function.cc
>> +++ b/gcc/function.cc
>> @@ -5049,9 +5049,12 @@ stack_protect_epilogue (void)
>>      PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
>>      the function's parameters, which must be run at any return statement.  */
>>   
>> +bool currently_expanding_function_start;
>>   void
>>   expand_function_start (tree subr)
>>   {
>> +  currently_expanding_function_start = true;
>> +
>>     /* Make sure volatile mem refs aren't considered
>>        valid operands of arithmetic insns.  */
>>     init_recog_no_volatile ();
>> @@ -5244,6 +5247,8 @@ expand_function_start (tree subr)
>>     /* If we are doing generic stack checking, the probe should go here.  */
>>     if (flag_stack_check == GENERIC_STACK_CHECK)
>>       stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
>> +
>> +  currently_expanding_function_start = false;
>>   }
>>   \f
>>   void
>> diff --git a/gcc/function.h b/gcc/function.h
>> index 098613766be..19abc5e7e6e 100644
>> --- a/gcc/function.h
>> +++ b/gcc/function.h
>> @@ -719,4 +719,6 @@ extern const char *current_function_name (void);
>>   
>>   extern void used_types_insert (tree);
>>   
>> +extern bool currently_expanding_function_start;
>> +
>>   #endif  /* GCC_FUNCTION_H */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>> new file mode 100644
>> index 00000000000..c45be832d5b
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
>> @@ -0,0 +1,86 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>> new file mode 100644
>> index 00000000000..61d12ec22eb
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
>> @@ -0,0 +1,87 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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 'S1' changed in GCC 9.1} "" { target *-*-* } 47 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) (because the argument fits in a single register).  Should not
>> +   warn, but aarch64_function_arg_boundary would need to take the argument size
>> +   into account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>> new file mode 100644
>> index 00000000000..04b183af697
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#define ALIGN 32
>> +//#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* Changed in GCC 9.1.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>> new file mode 100644
>> index 00000000000..cdb5b4df774
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#define ALIGN 32
>> +#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>> new file mode 100644
>> index 00000000000..b1764d97ea0
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
>> +
>> +#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/g++.target/aarch64/bitfield-abi-warning.h b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning.h
>> new file mode 100644
>> index 00000000000..3940b714ef8
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.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, ull a8, 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, 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)); }
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
>> new file mode 100644
>> index 00000000000..3e38cac149d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.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 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 66 }  gp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 67 } g1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 68 } g2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 69 } g4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 70 } g8p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 120 }  gp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 121 } g1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 122 } g2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 123 } g4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 124 } g8p_stdarg */
>> 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..39c5f9228ee
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
>> @@ -0,0 +1,87 @@
>> +/* { 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 } f1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 48 } f2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 49 } f4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 50 } f8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) (because the argument fits in a single register).  Should not
>> +   warn, but aarch64_function_arg_boundary would need to take the argument size
>> +   into account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 53 }  fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 60 } g1 */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 61 } g2 */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 62 } g4 */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 63 } g8 */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 74 } f1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 75 } f2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 76 } f4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 77 } f8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 80 }  fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 87 } g1_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 88 } g2_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 89 } g4_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 90 } g8_stack */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 93 }  gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} "" { target *-*-* } 101 } f1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} "" { target *-*-* } 102 } f2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} "" { target *-*-* } 103 } f4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} "" { target *-*-* } 104 } f8_stdarg */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1} "" { target *-*-* } 107 }  fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S1' changed in GCC 9.1} ""  { target *-*-* } 114 } g1_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2' changed in GCC 9.1} ""  { target *-*-* } 115 } g2_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4' changed in GCC 9.1} ""  { target *-*-* } 116 } g4_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8' changed in GCC 9.1} ""  { target *-*-* } 117 } g8_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
>> new file mode 100644
>> index 00000000000..70671ceda09
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps" } */
>> +
>> +#define ALIGN 32
>> +//#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* Changed in GCC 9.1.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
>> new file mode 100644
>> index 00000000000..757a2f1543c
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
>> @@ -0,0 +1,119 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -save-temps" } */
>> +
>> +#define ALIGN 32
>> +#define EXTRA
>> +
>> +#include "bitfield-abi-warning.h"
>> +
>> +/* In f1, f2, f4, f8, f16 (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[x1\\\]" 10 } } */
>> +
>> +/* In fp, f1p, f2p, f4p, f8p (and stdarg versions):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w1, 1" 10 { xfail *-*-* } } } */
>> +
>> +/* In f16p (and stdarg version):  */
>> +/* { dg-final { scan-assembler-times "and\tw0, w2, 1" 2 { xfail *-*-* } } } */
>> +
>> +/* In f1_stack, f2_stack, f4_stack, f8_stack, f16_stack, f8p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx\[0-9\]+, \\\[sp, 8\\\]" 6 { xfail *-*-* } } } */
>> +
>> +/* In fp_stack, f1p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrb\tw0, \\\[sp, 8\\\]" 2 { xfail *-*-* } } } */
>> +
>> +/* In f2p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldrh\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f4p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tw0, \\\[sp, 8\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* In f16p_stack:  */
>> +/* { dg-final { scan-assembler-times "ldr\tx0, \\\[sp, 16\\\]" 1 { xfail *-*-* } } } */
>> +
>> +/* Bitfield parameter in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 47-51 (f1, f2, f4, f8, f16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 53-57 (fp, f1p, f2p,
>> +   f4p, f8p) because the argument fits in a single register.  Should not warn,
>> +   but aarch64_function_arg_boundary would need to take the argument size into
>> +   account as well as whether it's passed via registers or the stack.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 53 } fp */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 54 } f1p */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 55 } f2p */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 56 } f4p */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 57 } f8p */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning since GCC 11 (was OK with GCC 9).  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 58 } f16p */
>> +
>> +
>> +/* Bitfield call argument in registers.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 60-64 (g1, g2, g4, g8, g16)
>> +   because the overall alignment is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 66-70 (gp, g1p, g2p,
>> +   g4p, g8p), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 71 } g16p */
>> +
>> +
>> +/* Bitfield parameter in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 74-78 (f1_stack,
>> +   f2_stack, f4_stack, f8_stack, f16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 80 } fp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 81 } f1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 82 } f2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 83 } f4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 84 } f8p_stack */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 85 (f16p_stack) because
>> +   the overall alignment is >= 16.  No warning expected.  */
>> +
>> +/* Bitfield call argument in stack.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 87-91 (g1_stack,
>> +   g2_stack, g4_stack, g8_stack, g16_stack) because the overall alignment is >
>> +   16.  No warning expected.  */
>> +
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}  "" { target *-*-* } 93 } gp_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1} "" { target *-*-* } 94 } g1p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1} "" { target *-*-* } 95 } g2p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1} "" { target *-*-* } 96 } g4p_stack */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1} "" { target *-*-* } 97 } g8p_stack */
>> +
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 98 (g16p_stack).  No
>> +   warning expected.  */
>> +
>> +
>> +/* Bitfield parameter in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 101-105 (f1_stdarg,
>> +   f2_stdarg, f4_stdarg, f8_stdarg, f16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* Parameter passing for these should not have changed in GCC 9.1 (PR 105549).
>> +   Fortunately we warn. Note the discrepancy with lines 120-124 below: we warn
>> +   in the callee, but not in the caller.  */
>> +/* { dg-note {parameter passing for argument of type 'struct Sp' changed in GCC 9.1}   "" { target *-*-* } 107 } fp_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S1p' changed in GCC 9.1}  "" { target *-*-* } 108 } f1p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S2p' changed in GCC 9.1}  "" { target *-*-* } 109 } f2p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S4p' changed in GCC 9.1}  "" { target *-*-* } 110 } f4p_stdarg */
>> +/* { dg-note {parameter passing for argument of type 'struct S8p' changed in GCC 9.1}  "" { target *-*-* } 111 } f8p_stdarg */
>> +
>> +/* No change in parameter passing in GCC 9.1 for line 112 (f16p_stdarg).
>> +   Should not warn.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { target *-*-* } 112 } f16p_stdarg */
>> +
>> +/* Bitfield call argument in stdarg.  */
>> +/* No change in parameter passing in GCC 9.1 for lines 114-118 (g1_stdarg,
>> +   g2_stdarg, g4_stdarg, g8_stdarg, g16_stdarg) because the overall alignment
>> +   is > 16.  No warning expected.  */
>> +
>> +/* No change in parameter passing in GCC 9.1 for lines 120-124 (gp_stdarg,
>> +   g1p_stdarg, g2p_stdarg, g4p_stdarg, g8p_stdarg), no warning expected.  */
>> +
>> +/* Changed in GCC 9.1, but we fail to emit a warning.  */
>> +/* { dg-note {parameter passing for argument of type 'struct S16p' changed in GCC 9.1} "" { xfail *-*-* } 125 } g16p_stdarg */
>> 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..3940b714ef8
>> --- /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, ull a8, 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, 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)); }

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

end of thread, other threads:[~2023-01-25 14:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-11 14:18 [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Christophe Lyon
2023-01-11 14:18 ` [PATCH v3 2/2] aarch64: Fix bit-field alignment in param passing [PR105549] Christophe Lyon
2023-01-12 13:19   ` Richard Sandiford
2023-01-12 13:38     ` Christophe Lyon
2023-01-13 15:38   ` Jakub Jelinek
2023-01-13 19:25     ` Jakub Jelinek
2023-01-13 19:50       ` Jakub Jelinek
2023-01-15 16:54     ` Christophe Lyon
2023-01-17 12:43       ` Christophe Lyon
2023-01-17 12:48         ` Jakub Jelinek
2023-01-17 12:50           ` Christophe Lyon
2023-01-12 13:03 ` [PATCH v3 1/2] aarch64: fix warning emission for ABI break since GCC 9.1 Richard Sandiford
2023-01-12 13:39   ` Christophe Lyon
2023-01-25 14:30   ` 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).