From 1bcec8dfa3d11438ec654df7879ad76bd19e07c6 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 20 Aug 2019 05:32:49 +0000 Subject: 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/function.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'gcc/function.c') diff --git a/gcc/function.c b/gcc/function.c index e368f7c..f801951 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); -- cgit v1.1