@@ -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)
new file mode 100644
@@ -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} } */
+}
+
+}
new file mode 100644
@@ -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} } */
+}
+
+}
new file mode 100644
@@ -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} } */
+}
+
+}
new file mode 100644
@@ -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} } */
+}
+
+}
new file mode 100644
@@ -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} } */