diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 70916ad63d2..546cb121331 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7467,17 +7467,21 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
    4.1).  ABI_BREAK_GCC_9 is set to the old alignment if the alignment
    was incorrectly calculated in versions of GCC prior to GCC 9.
    ABI_BREAK_GCC_13 is set to the old alignment if it was incorrectly
-   calculated in versions between GCC 9 and GCC 13.
+   calculated in versions between GCC 9 and GCC 13.  If the alignment
+   might have changed between GCC 13 and GCC 14, ABI_BREAK_GCC_14
+   is the old GCC 13 alignment, otherwise it is zero.
 
    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_gcc_9,
-				unsigned int *abi_break_gcc_13)
+				unsigned int *abi_break_gcc_13,
+				unsigned int *abi_break_gcc_14)
 {
   *abi_break_gcc_9 = 0;
   *abi_break_gcc_13 = 0;
+  *abi_break_gcc_14 = 0;
   if (!type)
     return GET_MODE_ALIGNMENT (mode);
 
@@ -7498,6 +7502,11 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
 	  gcc_assert (known_eq (POINTER_SIZE, GET_MODE_BITSIZE (mode)));
 	  return POINTER_SIZE;
 	}
+      if (TREE_CODE (type) == ENUMERAL_TYPE && TREE_TYPE (type))
+	{
+	  *abi_break_gcc_14 = TYPE_ALIGN (type);
+	  type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+	}
       gcc_assert (!TYPE_USER_ALIGN (type));
       return TYPE_ALIGN (type);
     }
@@ -7576,6 +7585,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
   HOST_WIDE_INT size;
   unsigned int abi_break_gcc_9;
   unsigned int abi_break_gcc_13;
+  unsigned int abi_break_gcc_14;
 
   /* We need to do this once per argument.  */
   if (pcum->aapcs_arg_processed)
@@ -7715,7 +7725,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 
   unsigned int alignment
     = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
-				      &abi_break_gcc_13);
+				      &abi_break_gcc_13, &abi_break_gcc_14);
 
   gcc_assert ((allocate_nvrn || alignment <= 16 * BITS_PER_UNIT)
 	      && (!alignment || abi_break_gcc_9 < alignment)
@@ -7799,6 +7809,13 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 	    inform (input_location, "parameter passing for argument of type "
 		    "%qT changed in GCC 13.1", type);
 
+	  if (warn_pcs_change
+	      && abi_break_gcc_14
+	      && ((abi_break_gcc_14 == 16 * BITS_PER_UNIT)
+		  != (alignment == 16 * BITS_PER_UNIT)))
+	    inform (input_location, "parameter passing for argument of type "
+		    "%qT changed in GCC 14.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
@@ -7870,6 +7887,13 @@ on_stack:
     inform (input_location, "parameter passing for argument of type "
 	    "%qT changed in GCC 13.1", type);
 
+  if (warn_pcs_change
+      && abi_break_gcc_14
+      && ((abi_break_gcc_14 >= 16 * BITS_PER_UNIT)
+	  != (alignment >= 16 * BITS_PER_UNIT)))
+    inform (input_location, "parameter passing for argument of type "
+	    "%qT changed in GCC 14.1", type);
+
   if (alignment == 16 * BITS_PER_UNIT)
     {
       int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
@@ -7994,9 +8018,11 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
 {
   unsigned int abi_break_gcc_9;
   unsigned int abi_break_gcc_13;
+  unsigned int abi_break_gcc_14;
   unsigned int alignment = aarch64_function_arg_alignment (mode, type,
 							   &abi_break_gcc_9,
-							   &abi_break_gcc_13);
+							   &abi_break_gcc_13,
+							   &abi_break_gcc_14);
   /* 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);
@@ -19765,9 +19791,10 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
 
   unsigned int abi_break_gcc_9;
   unsigned int abi_break_gcc_13;
+  unsigned int abi_break_gcc_14;
   align
     = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
-				      &abi_break_gcc_13)
+				      &abi_break_gcc_13, &abi_break_gcc_14)
     / BITS_PER_UNIT;
 
   dw_align = false;
@@ -19815,6 +19842,12 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
 	inform (input_location, "parameter passing for argument of type "
 		"%qT changed in GCC 13.1", type);
 
+      if (warn_psabi
+	  && abi_break_gcc_14
+	  && (abi_break_gcc_14 > 8 * BITS_PER_UNIT) != (align > 8))
+	inform (input_location, "parameter passing for argument of type "
+		"%qT changed in GCC 14.1", type);
+
       if (align > 8)
 	{
 	  if (abi_break_gcc_9 && warn_psabi)
diff --git a/gcc/testsuite/g++.target/aarch64/pr109661-1.C b/gcc/testsuite/g++.target/aarch64/pr109661-1.C
new file mode 100644
index 00000000000..d668a544fa7
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr109661-1.C
@@ -0,0 +1,253 @@
+/* { dg-options "-O2 -Wpsabi" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdarg.h>
+
+#define ALIGN
+
+typedef __uint128_t u128_4 __attribute__((aligned(4)));
+typedef __uint128_t u128_8 __attribute__((aligned(8)));
+typedef __uint128_t u128_16 __attribute__((aligned(16)));
+typedef __uint128_t u128_32 __attribute__((aligned(32)));
+typedef __uint128_t u128;
+
+typedef __UINT64_TYPE__ u64_4 __attribute__((aligned(4)));
+typedef __UINT64_TYPE__ u64_8 __attribute__((aligned(8)));
+typedef __UINT64_TYPE__ u64_16 __attribute__((aligned(16)));
+typedef __UINT64_TYPE__ u64_32 __attribute__((aligned(32)));
+typedef __UINT64_TYPE__ u64;
+
+enum class ALIGN e128_4 : u128_4 { A };
+enum class ALIGN e128_8 : u128_8 { A };
+enum class ALIGN e128_16 : u128_16 { A };
+enum class ALIGN e128_32 : u128_32 { A };
+enum class ALIGN e128 : u128 { A };
+
+enum class ALIGN e64_4 : u64_4 { A };
+enum class ALIGN e64_8 : u64_8 { A };
+enum class ALIGN e64_16 : u64_16 { A };
+enum class ALIGN e64_32 : u64_32 { A };
+enum class ALIGN e64 : u64 { A };
+
+extern "C" {
+
+/*
+** reg_e128_4:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_4 reg_e128_4 (int x, e128_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+
+/*
+** reg_e128_8:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_8 reg_e128_8 (int x, e128_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+
+/*
+** reg_e128_16:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_16 reg_e128_16 (int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e128_32:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_32 reg_e128_32 (int x, e128_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+
+/*
+** reg_e128:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128 reg_e128 (int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_4:
+**	mov	x0, x1
+**	ret
+*/
+e64_4 reg_e64_4 (int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_8:
+**	mov	x0, x1
+**	ret
+*/
+e64_8 reg_e64_8 (int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_16:
+**	mov	x0, x1
+**	ret
+*/
+e64_16 reg_e64_16 (int x, e64_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_32:
+**	mov	x0, x1
+**	ret
+*/
+e64_32 reg_e64_32 (int x, e64_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64:
+**	mov	x0, x1
+**	ret
+*/
+e64 reg_e64 (int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_4:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_4 stack_e128_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+
+/*
+** stack_e128_8:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_8 stack_e128_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+
+/*
+** stack_e128_16:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_16 stack_e128_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_32:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_32 stack_e128_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128 stack_e128 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_4:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_4 stack_e64_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_8:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_8 stack_e64_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_16:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_16 stack_e64_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_16 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+
+/*
+** stack_e64_32:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_32 stack_e64_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+
+/*
+** stack_e64:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64 stack_e64 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+void callee (int n, ...);
+
+void
+caller ()
+{
+  callee (1, e128_4::A); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  callee (1, e128_8::A); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  callee (1, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e128_32::A); /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+  callee (1, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (1, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_32::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64::A); /* { dg-bogus {parameter passing} } */
+
+#define LOTS 1, 2, 3, 4, 5, 6, 7, 8, 9
+
+  callee (LOTS, e128_4::A); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  callee (LOTS, e128_8::A); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  callee (LOTS, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_32::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (LOTS, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e64_16::A); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  callee (LOTS, e64_32::A); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  callee (LOTS, e64::A); /* { dg-bogus {parameter passing} } */
+}
+
+void
+va (volatile void *ptr, ...)
+{
+  va_list ap;
+  va_start (ap, ptr);
+  *(volatile e128_4 *) ptr = va_arg (ap, e128_4); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  *(volatile e128_8 *) ptr = va_arg (ap, e128_8); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  *(volatile e128_16 *) ptr = va_arg (ap, e128_16); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_32 *) ptr = va_arg (ap, e128_32); /* { dg-bogus {parameter passing} } */
+  *(volatile e128 *) ptr = va_arg (ap, e128); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_4 *) ptr = va_arg (ap, e64_4); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_8 *) ptr = va_arg (ap, e64_8); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_16 *) ptr = va_arg (ap, e64_16); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  *(volatile e64_32 *) ptr = va_arg (ap, e64_32); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  *(volatile e64 *) ptr = va_arg (ap, e64); /* { dg-bogus {parameter passing} } */
+}
+
+}
diff --git a/gcc/testsuite/g++.target/aarch64/pr109661-2.C b/gcc/testsuite/g++.target/aarch64/pr109661-2.C
new file mode 100644
index 00000000000..f081417da95
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr109661-2.C
@@ -0,0 +1,253 @@
+/* { dg-options "-O2 -Wpsabi" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdarg.h>
+
+#define ALIGN __attribute__((aligned(8)))
+
+typedef __uint128_t u128_4 __attribute__((aligned(4)));
+typedef __uint128_t u128_8 __attribute__((aligned(8)));
+typedef __uint128_t u128_16 __attribute__((aligned(16)));
+typedef __uint128_t u128_32 __attribute__((aligned(32)));
+typedef __uint128_t u128;
+
+typedef __UINT64_TYPE__ u64_4 __attribute__((aligned(4)));
+typedef __UINT64_TYPE__ u64_8 __attribute__((aligned(8)));
+typedef __UINT64_TYPE__ u64_16 __attribute__((aligned(16)));
+typedef __UINT64_TYPE__ u64_32 __attribute__((aligned(32)));
+typedef __UINT64_TYPE__ u64;
+
+enum class ALIGN e128_4 : u128_4 { A };
+enum class ALIGN e128_8 : u128_8 { A };
+enum class ALIGN e128_16 : u128_16 { A };
+enum class ALIGN e128_32 : u128_32 { A };
+enum class ALIGN e128 : u128 { A };
+
+enum class ALIGN e64_4 : u64_4 { A };
+enum class ALIGN e64_8 : u64_8 { A };
+enum class ALIGN e64_16 : u64_16 { A };
+enum class ALIGN e64_32 : u64_32 { A };
+enum class ALIGN e64 : u64 { A };
+
+extern "C" {
+
+/*
+** reg_e128_4:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_4 reg_e128_4 (int x, e128_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+
+/*
+** reg_e128_8:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_8 reg_e128_8 (int x, e128_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+
+/*
+** reg_e128_16:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_16 reg_e128_16 (int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e128_32:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_32 reg_e128_32 (int x, e128_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+
+/*
+** reg_e128:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128 reg_e128 (int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_4:
+**	mov	x0, x1
+**	ret
+*/
+e64_4 reg_e64_4 (int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_8:
+**	mov	x0, x1
+**	ret
+*/
+e64_8 reg_e64_8 (int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_16:
+**	mov	x0, x1
+**	ret
+*/
+e64_16 reg_e64_16 (int x, e64_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_32:
+**	mov	x0, x1
+**	ret
+*/
+e64_32 reg_e64_32 (int x, e64_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64:
+**	mov	x0, x1
+**	ret
+*/
+e64 reg_e64 (int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_4:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_4 stack_e128_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+
+/*
+** stack_e128_8:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_8 stack_e128_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+
+/*
+** stack_e128_16:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_16 stack_e128_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_32:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_32 stack_e128_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128 stack_e128 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_4:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_4 stack_e64_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_8:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_8 stack_e64_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_16:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_16 stack_e64_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_16 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+
+/*
+** stack_e64_32:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_32 stack_e64_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+
+/*
+** stack_e64:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64 stack_e64 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+void callee (int n, ...);
+
+void
+caller ()
+{
+  callee (1, e128_4::A); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  callee (1, e128_8::A); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  callee (1, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e128_32::A); /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+  callee (1, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (1, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_32::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64::A); /* { dg-bogus {parameter passing} } */
+
+#define LOTS 1, 2, 3, 4, 5, 6, 7, 8, 9
+
+  callee (LOTS, e128_4::A); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  callee (LOTS, e128_8::A); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  callee (LOTS, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_32::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (LOTS, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e64_16::A); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  callee (LOTS, e64_32::A); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  callee (LOTS, e64::A); /* { dg-bogus {parameter passing} } */
+}
+
+void
+va (volatile void *ptr, ...)
+{
+  va_list ap;
+  va_start (ap, ptr);
+  *(volatile e128_4 *) ptr = va_arg (ap, e128_4); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  *(volatile e128_8 *) ptr = va_arg (ap, e128_8); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  *(volatile e128_16 *) ptr = va_arg (ap, e128_16); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_32 *) ptr = va_arg (ap, e128_32); /* { dg-bogus {parameter passing} } */
+  *(volatile e128 *) ptr = va_arg (ap, e128); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_4 *) ptr = va_arg (ap, e64_4); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_8 *) ptr = va_arg (ap, e64_8); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_16 *) ptr = va_arg (ap, e64_16); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  *(volatile e64_32 *) ptr = va_arg (ap, e64_32); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  *(volatile e64 *) ptr = va_arg (ap, e64); /* { dg-bogus {parameter passing} } */
+}
+
+}
diff --git a/gcc/testsuite/g++.target/aarch64/pr109661-3.C b/gcc/testsuite/g++.target/aarch64/pr109661-3.C
new file mode 100644
index 00000000000..dab2fb295d3
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr109661-3.C
@@ -0,0 +1,253 @@
+/* { dg-options "-O2 -Wpsabi" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdarg.h>
+
+#define ALIGN __attribute__((aligned(16)))
+
+typedef __uint128_t u128_4 __attribute__((aligned(4)));
+typedef __uint128_t u128_8 __attribute__((aligned(8)));
+typedef __uint128_t u128_16 __attribute__((aligned(16)));
+typedef __uint128_t u128_32 __attribute__((aligned(32)));
+typedef __uint128_t u128;
+
+typedef __UINT64_TYPE__ u64_4 __attribute__((aligned(4)));
+typedef __UINT64_TYPE__ u64_8 __attribute__((aligned(8)));
+typedef __UINT64_TYPE__ u64_16 __attribute__((aligned(16)));
+typedef __UINT64_TYPE__ u64_32 __attribute__((aligned(32)));
+typedef __UINT64_TYPE__ u64;
+
+enum class ALIGN e128_4 : u128_4 { A };
+enum class ALIGN e128_8 : u128_8 { A };
+enum class ALIGN e128_16 : u128_16 { A };
+enum class ALIGN e128_32 : u128_32 { A };
+enum class ALIGN e128 : u128 { A };
+
+enum class ALIGN e64_4 : u64_4 { A };
+enum class ALIGN e64_8 : u64_8 { A };
+enum class ALIGN e64_16 : u64_16 { A };
+enum class ALIGN e64_32 : u64_32 { A };
+enum class ALIGN e64 : u64 { A };
+
+extern "C" {
+
+/*
+** reg_e128_4:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_4 reg_e128_4 (int x, e128_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e128_8:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_8 reg_e128_8 (int x, e128_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e128_16:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_16 reg_e128_16 (int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e128_32:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_32 reg_e128_32 (int x, e128_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+
+/*
+** reg_e128:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128 reg_e128 (int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_4:
+**	mov	x0, x1
+**	ret
+*/
+e64_4 reg_e64_4 (int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_8:
+**	mov	x0, x1
+**	ret
+*/
+e64_8 reg_e64_8 (int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_16:
+**	mov	x0, x1
+**	ret
+*/
+e64_16 reg_e64_16 (int x, e64_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_32:
+**	mov	x0, x1
+**	ret
+*/
+e64_32 reg_e64_32 (int x, e64_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64:
+**	mov	x0, x1
+**	ret
+*/
+e64 reg_e64 (int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_4:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_4 stack_e128_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_8:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_8 stack_e128_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_16:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_16 stack_e128_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_32:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_32 stack_e128_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128 stack_e128 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_4:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_4 stack_e64_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+
+/*
+** stack_e64_8:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_8 stack_e64_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+
+/*
+** stack_e64_16:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_16 stack_e64_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_16 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+
+/*
+** stack_e64_32:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_32 stack_e64_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+
+/*
+** stack_e64:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64 stack_e64 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+
+void callee (int n, ...);
+
+void
+caller ()
+{
+  callee (1, e128_4::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e128_8::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e128_32::A); /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+  callee (1, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (1, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_32::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64::A); /* { dg-bogus {parameter passing} } */
+
+#define LOTS 1, 2, 3, 4, 5, 6, 7, 8, 9
+
+  callee (LOTS, e128_4::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_8::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_32::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (LOTS, e64_4::A); /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+  callee (LOTS, e64_8::A); /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+  callee (LOTS, e64_16::A); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  callee (LOTS, e64_32::A); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  callee (LOTS, e64::A); /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+}
+
+void
+va (volatile void *ptr, ...)
+{
+  va_list ap;
+  va_start (ap, ptr);
+  *(volatile e128_4 *) ptr = va_arg (ap, e128_4); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_8 *) ptr = va_arg (ap, e128_8); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_16 *) ptr = va_arg (ap, e128_16); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_32 *) ptr = va_arg (ap, e128_32); /* { dg-bogus {parameter passing} } */
+  *(volatile e128 *) ptr = va_arg (ap, e128); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_4 *) ptr = va_arg (ap, e64_4); /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+  *(volatile e64_8 *) ptr = va_arg (ap, e64_8); /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+  *(volatile e64_16 *) ptr = va_arg (ap, e64_16); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  *(volatile e64_32 *) ptr = va_arg (ap, e64_32); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  *(volatile e64 *) ptr = va_arg (ap, e64); /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+}
+
+}
diff --git a/gcc/testsuite/g++.target/aarch64/pr109661-4.C b/gcc/testsuite/g++.target/aarch64/pr109661-4.C
new file mode 100644
index 00000000000..d87e60fcc5d
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr109661-4.C
@@ -0,0 +1,253 @@
+/* { dg-options "-O2 -Wpsabi" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdarg.h>
+
+#define ALIGN __attribute__((aligned(32)))
+
+typedef __uint128_t u128_4 __attribute__((aligned(4)));
+typedef __uint128_t u128_8 __attribute__((aligned(8)));
+typedef __uint128_t u128_16 __attribute__((aligned(16)));
+typedef __uint128_t u128_32 __attribute__((aligned(32)));
+typedef __uint128_t u128;
+
+typedef __UINT64_TYPE__ u64_4 __attribute__((aligned(4)));
+typedef __UINT64_TYPE__ u64_8 __attribute__((aligned(8)));
+typedef __UINT64_TYPE__ u64_16 __attribute__((aligned(16)));
+typedef __UINT64_TYPE__ u64_32 __attribute__((aligned(32)));
+typedef __UINT64_TYPE__ u64;
+
+enum class ALIGN e128_4 : u128_4 { A };
+enum class ALIGN e128_8 : u128_8 { A };
+enum class ALIGN e128_16 : u128_16 { A };
+enum class ALIGN e128_32 : u128_32 { A };
+enum class ALIGN e128 : u128 { A };
+
+enum class ALIGN e64_4 : u64_4 { A };
+enum class ALIGN e64_8 : u64_8 { A };
+enum class ALIGN e64_16 : u64_16 { A };
+enum class ALIGN e64_32 : u64_32 { A };
+enum class ALIGN e64 : u64 { A };
+
+extern "C" {
+
+/*
+** reg_e128_4:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_4 reg_e128_4 (int x, e128_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+
+/*
+** reg_e128_8:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_8 reg_e128_8 (int x, e128_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+
+/*
+** reg_e128_16:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_16 reg_e128_16 (int x, e128_16 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_16' changed in GCC 14.1} } */
+
+/*
+** reg_e128_32:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128_32 reg_e128_32 (int x, e128_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+
+/*
+** reg_e128:
+** (
+**	mov	x1, x3
+**	mov	x0, x2
+** |
+**	mov	x0, x2
+**	mov	x1, x3
+** )
+**	ret
+*/
+e128 reg_e128 (int x, e128 y) { return y; } /* { dg-note {parameter passing for argument of type 'e128' changed in GCC 14.1} } */
+
+/*
+** reg_e64_4:
+**	mov	x0, x1
+**	ret
+*/
+e64_4 reg_e64_4 (int x, e64_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_8:
+**	mov	x0, x1
+**	ret
+*/
+e64_8 reg_e64_8 (int x, e64_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_16:
+**	mov	x0, x1
+**	ret
+*/
+e64_16 reg_e64_16 (int x, e64_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64_32:
+**	mov	x0, x1
+**	ret
+*/
+e64_32 reg_e64_32 (int x, e64_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** reg_e64:
+**	mov	x0, x1
+**	ret
+*/
+e64 reg_e64 (int x, e64 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_4:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_4 stack_e128_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_4 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_8:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_8 stack_e128_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_8 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_16:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_16 stack_e128_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_16 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128_32:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128_32 stack_e128_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128_32 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e128:
+**	ldp	x0, x1, \[sp, #?16\]
+**	ret
+*/
+e128 stack_e128 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e128 y) { return y; } /* { dg-bogus {parameter passing} } */
+
+/*
+** stack_e64_4:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_4 stack_e64_4 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_4 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+
+/*
+** stack_e64_8:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_8 stack_e64_8 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_8 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+
+/*
+** stack_e64_16:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_16 stack_e64_16 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_16 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+
+/*
+** stack_e64_32:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64_32 stack_e64_32 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64_32 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+
+/*
+** stack_e64:
+**	ldr	x0, \[sp, #?8\]
+**	ret
+*/
+e64 stack_e64 (u128 x0, u128 x2, u128 x4, u128 x6, int x, e64 y) { return y; } /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+
+void callee (int n, ...);
+
+void
+caller ()
+{
+  callee (1, e128_4::A); /* { dg-note {parameter passing for argument of type 'e128_4' changed in GCC 14.1} } */
+  callee (1, e128_8::A); /* { dg-note {parameter passing for argument of type 'e128_8' changed in GCC 14.1} } */
+  callee (1, e128_16::A); /* { dg-note {parameter passing for argument of type 'e128_16' changed in GCC 14.1} } */
+  callee (1, e128_32::A); /* { dg-note {parameter passing for argument of type 'e128_32' changed in GCC 14.1} } */
+  callee (1, e128::A); /* { dg-note {parameter passing for argument of type 'e128' changed in GCC 14.1} } */
+
+  callee (1, e64_4::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_8::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_16::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64_32::A); /* { dg-bogus {parameter passing} } */
+  callee (1, e64::A); /* { dg-bogus {parameter passing} } */
+
+#define LOTS 1, 2, 3, 4, 5, 6, 7, 8, 9
+
+  callee (LOTS, e128_4::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_8::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_16::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128_32::A); /* { dg-bogus {parameter passing} } */
+  callee (LOTS, e128::A); /* { dg-bogus {parameter passing} } */
+
+  callee (LOTS, e64_4::A); /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+  callee (LOTS, e64_8::A); /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+  callee (LOTS, e64_16::A); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  callee (LOTS, e64_32::A); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  callee (LOTS, e64::A); /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+}
+
+void
+va (volatile void *ptr, ...)
+{
+  va_list ap;
+  va_start (ap, ptr);
+  *(volatile e128_4 *) ptr = va_arg (ap, e128_4); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_8 *) ptr = va_arg (ap, e128_8); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_16 *) ptr = va_arg (ap, e128_16); /* { dg-bogus {parameter passing} } */
+  *(volatile e128_32 *) ptr = va_arg (ap, e128_32); /* { dg-bogus {parameter passing} } */
+  *(volatile e128 *) ptr = va_arg (ap, e128); /* { dg-bogus {parameter passing} } */
+  *(volatile e64_4 *) ptr = va_arg (ap, e64_4); /* { dg-note {parameter passing for argument of type 'e64_4' changed in GCC 14.1} } */
+  *(volatile e64_8 *) ptr = va_arg (ap, e64_8); /* { dg-note {parameter passing for argument of type 'e64_8' changed in GCC 14.1} } */
+  *(volatile e64_16 *) ptr = va_arg (ap, e64_16); /* { dg-note {parameter passing for argument of type 'e64_16' changed in GCC 14.1} } */
+  *(volatile e64_32 *) ptr = va_arg (ap, e64_32); /* { dg-note {parameter passing for argument of type 'e64_32' changed in GCC 14.1} } */
+  *(volatile e64 *) ptr = va_arg (ap, e64); /* { dg-note {parameter passing for argument of type 'e64' changed in GCC 14.1} } */
+}
+
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr109661-1.c b/gcc/testsuite/gcc.target/aarch64/pr109661-1.c
new file mode 100644
index 00000000000..5686b2b1cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr109661-1.c
@@ -0,0 +1,11 @@
+/* { dg-options "-O2 -Wpsabi" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+enum __attribute__((aligned(16))) e { E };
+
+/*
+** test:
+**	mov	w0, w1
+**	ret
+*/
+enum e test (int x, enum e y) { return y; } /* { dg-bogus {parameter passing} } */
