From 1bcec8dfa3d11438ec654df7879ad76bd19e07c6 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 20 Aug 2019 05:32:49 +0000 Subject: [PATCH] re PR middle-end/89544 (Argument marshalling incorrectly assumes stack slots are naturally aligned.) 2019-08-20 Bernd Edlinger PR middle-end/89544 * function.c (assign_parm_find_stack_rtl): Use larger alignment when possible. testsuite: 2019-08-20 Bernd Edlinger PR middle-end/89544 * gcc.target/arm/unaligned-argument-1.c: New test. * gcc.target/arm/unaligned-argument-2.c: New test. From-SVN: r274691 --- gcc/ChangeLog | 6 ++++++ gcc/function.c | 17 ++++++++++++++++- gcc/testsuite/ChangeLog | 6 ++++++ .../gcc.target/arm/unaligned-argument-1.c | 19 +++++++++++++++++++ .../gcc.target/arm/unaligned-argument-2.c | 19 +++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/arm/unaligned-argument-1.c create mode 100644 gcc/testsuite/gcc.target/arm/unaligned-argument-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 895e5f12792..e22140ff3ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-20 Bernd Edlinger + + PR middle-end/89544 + * function.c (assign_parm_find_stack_rtl): Use larger alignment + when possible. + 2019-08-19 Joel Hutton * config/aarch64/aarch64-protos.h (aarch64_fpconst_pow2_recip): New prototype diff --git a/gcc/function.c b/gcc/function.c index e368f7c013e..f8019513928 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2697,8 +2697,23 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data) intentionally forcing upward padding. Otherwise we have to come up with a guess at the alignment based on OFFSET_RTX. */ poly_int64 offset; - if (data->locate.where_pad != PAD_DOWNWARD || data->entry_parm) + if (data->locate.where_pad == PAD_NONE || data->entry_parm) align = boundary; + else if (data->locate.where_pad == PAD_UPWARD) + { + align = boundary; + /* If the argument offset is actually more aligned than the nominal + stack slot boundary, take advantage of that excess alignment. + Don't make any assumptions if STACK_POINTER_OFFSET is in use. */ + if (poly_int_rtx_p (offset_rtx, &offset) + && STACK_POINTER_OFFSET == 0) + { + unsigned int offset_align = known_alignment (offset) * BITS_PER_UNIT; + if (offset_align == 0 || offset_align > STACK_BOUNDARY) + offset_align = STACK_BOUNDARY; + align = MAX (align, offset_align); + } + } else if (poly_int_rtx_p (offset_rtx, &offset)) { align = least_bit_hwi (boundary); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6f0bec89379..1aeccfd64b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-08-20 Bernd Edlinger + + PR middle-end/89544 + * gcc.target/arm/unaligned-argument-1.c: New test. + * gcc.target/arm/unaligned-argument-2.c: New test. + 2019-08-19 Joel Hutton * gcc.target/aarch64/fmul_scvtf_1.c: New test. diff --git a/gcc/testsuite/gcc.target/arm/unaligned-argument-1.c b/gcc/testsuite/gcc.target/arm/unaligned-argument-1.c new file mode 100644 index 00000000000..805a3a7f80d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/unaligned-argument-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arm_ok } */ +/* { dg-require-effective-target arm_ldrd_strd_ok } */ +/* { dg-options "-marm -mno-unaligned-access -O3" } */ + +struct s { + int a, b; +} __attribute__((aligned(8))); + +struct s f0; + +void f(int a, int b, int c, int d, struct s f) +{ + f0 = f; +} + +/* { dg-final { scan-assembler-times "ldrd" 1 } } */ +/* { dg-final { scan-assembler-times "strd" 1 } } */ +/* { dg-final { scan-assembler-times "stm" 0 } } */ diff --git a/gcc/testsuite/gcc.target/arm/unaligned-argument-2.c b/gcc/testsuite/gcc.target/arm/unaligned-argument-2.c new file mode 100644 index 00000000000..a35ce3a6d4b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/unaligned-argument-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arm_ok } */ +/* { dg-require-effective-target arm_ldrd_strd_ok } */ +/* { dg-options "-marm -mno-unaligned-access -O3" } */ + +struct s { + int a, b; +} __attribute__((aligned(8))); + +struct s f0; + +void f(int a, int b, int c, int d, int e, struct s f) +{ + f0 = f; +} + +/* { dg-final { scan-assembler-times "ldrd" 0 } } */ +/* { dg-final { scan-assembler-times "strd" 0 } } */ +/* { dg-final { scan-assembler-times "stm" 1 } } */ -- 2.30.2