[PATCH] Fix alignment of partially-passed stack arguments

For a partially-passed argument (part in registers, part on the
stack), assign_parm_find_stack_rtl reconstructs the full value by
spilling the register part just below the aligned stack slot.  The
resulting address is therefore only aligned to the largest power of
two dividing the size of the register part, not to the full argument
boundary.  The function currently sets align to data->locate.boundary
whenever data->entry_parm is non-null, which includes the partial-arg
case, so the reconstructed MEM is wrongly marked with the full
boundary alignment (e.g. A64 on RV32 for a DImode argument split
between a register and the stack).  Clamp the alignment to the partial
size.

This is the root cause of a RISC-V zilsd issue where a single
misaligned zilsd "ld"/"sd" was emitted for a split stack argument
because riscv_zilsd_valid_mem_p trusted the over-stated MEM_ALIGN.
With the slot now marked with the correct alignment the access is
split into two 32-bit loads.

Signed-off-by: Ciyan Pan <panciyan@eswincomputing.com>
gcc/ChangeLog:

	* function.cc (assign_parm_find_stack_rtl): When data->partial is
	nonzero, limit the stack slot alignment to the largest power of
	two dividing the partial size.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/zilsd-align-split-arg-1.c: New test.
	* gcc.target/riscv/zilsd-align-split-arg-2.c: New test.
	* gcc.target/riscv/zilsd-align-split-arg-3.c: New test.
	* gcc.target/riscv/zilsd-align-split-arg-4.c: New test.
5 files changed