On 9/11/26 3:39 AM, panciyan wrote:
From: e0001533 <[email protected]>

On RV32 a 2*XLEN argument passed when only one register remains is
split: the low word goes in the odd argument register (a7) and the
high word on the incoming stack.  When the middle-end later
reconstructs the value as a single DImode, riscv_zilsd_valid_mem_p
relies only on MEM_ALIGN, which is mis-marked A64 for the spilled
slot, so a single misaligned zilsd "ld"/"sd" is emitted (e.g.
ld s0,76(sp)) and faults under -mzilsd-strict-align.

Double-check the address: reject the zilsd access unless the offset is
a multiple of the required alignment.  For small frames the address is
a constant offset from a frame-related pointer (sp/hfp/ap/fp, all 16-byte
aligned).  For larger frames address legitimization
materializes the offset, either as two chained 12-bit adds (e.g.
addi a4,sp,13; addi a5,a4,2047; ld a0,0(a5)) or via a LUI high part
(e.g. addi a5,a4,12; add a5,sp,a5; ld a0,0(a5)).  Follow the defining
instructions of a materialized base register to recover the offset in
either case, forcing riscv_split_64bit_move_p to use two 32-bit moves
for the misaligned accesses.

Signed-off-by: Ciyan Pan <[email protected]>
gcc/ChangeLog:

         * config/riscv/riscv-protos.h (riscv_split_64bit_move_p)
         (riscv_zilsd_valid_mem_p): Add rtx_insn * parameter.
         * config/riscv/riscv.cc (riscv_zilsd_frame_ptr_p)
         (riscv_zilsd_find_def, riscv_zilsd_known_const)
         (riscv_zilsd_frame_offset): New helpers.
         (riscv_zilsd_valid_mem_p): Double-check address, including
         materialized frame offsets.
         (riscv_split_64bit_move_p, riscv_load_store_insns): Pass insn
         through to riscv_zilsd_valid_mem_p.
         * config/riscv/riscv.md (MOVE64 split): Pass insn to
         riscv_split_64bit_move_p.

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.
ISTM that the real problem is the A64 on the MEM and you need to debug why that's happening.  This patch just seems to be papering over the problem.

Jeff

Reply via email to