aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/aarch64/aarch64.c23
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr91710.c16
2 files changed, 30 insertions, 9 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 09d79f6..12625a4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -6337,9 +6337,9 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
static unsigned int
aarch64_function_arg_alignment (machine_mode mode, const_tree type,
- bool *abi_break)
+ unsigned int *abi_break)
{
- *abi_break = false;
+ *abi_break = 0;
if (!type)
return GET_MODE_ALIGNMENT (mode);
@@ -6381,7 +6381,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
if (bitfield_alignment > alignment)
{
- *abi_break = true;
+ *abi_break = alignment;
return bitfield_alignment;
}
@@ -6403,7 +6403,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
int ncrn, nvrn, nregs;
bool allocate_ncrn, allocate_nvrn;
HOST_WIDE_INT size;
- bool abi_break;
+ unsigned int abi_break;
/* We need to do this once per argument. */
if (pcum->aapcs_arg_processed)
@@ -6721,14 +6721,19 @@ aarch64_function_arg_regno_p (unsigned regno)
static unsigned int
aarch64_function_arg_boundary (machine_mode mode, const_tree type)
{
- bool abi_break;
+ unsigned int abi_break;
unsigned int alignment = aarch64_function_arg_alignment (mode, type,
&abi_break);
+ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
if (abi_break & warn_psabi)
- inform (input_location, "parameter passing for argument of type "
- "%qT changed in GCC 9.1", type);
+ {
+ 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 MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
+ return alignment;
}
/* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
@@ -18253,7 +18258,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
f_stack, NULL_TREE);
size = int_size_in_bytes (type);
- bool abi_break;
+ unsigned int abi_break;
align
= aarch64_function_arg_alignment (mode, type, &abi_break) / BITS_PER_UNIT;
diff --git a/gcc/testsuite/gcc.target/aarch64/pr91710.c b/gcc/testsuite/gcc.target/aarch64/pr91710.c
new file mode 100644
index 0000000..496eb50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr91710.c
@@ -0,0 +1,16 @@
+/* PR target/91710 */
+/* { dg-do compile } */
+
+struct S { unsigned int i:4; };
+
+unsigned int test1(struct S s) { /* { dg-bogus "parameter passing for argument of type" } */
+ return s.i;
+}
+
+unsigned int test2(unsigned x, struct S s) { /* { dg-bogus "parameter passing for argument of type" } */
+ return x - s.i;
+}
+
+unsigned int test3(unsigned x, unsigned y, struct S s) { /* { dg-bogus "parameter passing for argument of type" } */
+ return x - y - s.i;
+}