kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 1c79c987fcc7f947130adf86d32566849657ae54
parent 19bfa484a2cc61e639afe8823cd50dac1c46d04c
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 27 May 2026 05:56:06 -0700

aa64: set sret x8 after argument loads in plan_call

For a call returning via sret (indirect result), the x8 pointer setup was
emitted before the argument register loads. When an argument value was
allocated to x8 (x8 is allocable), the sret load clobbered it before it was
moved into its argument register, so arg0 received the sret pointer instead.
Emit the x8 setup after the argument loads (the arg loop never targets x8 and
uses x16 as scratch). Fixes tail+sret returns (36, 37).

Aggregate/sret ABI now fully passes on the optimizer path. Remaining
bypass-off failures are inline asm only (7). Default path: 408/408.

Diffstat:
Msrc/arch/aa64/native.c | 26+++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/arch/aa64/native.c b/src/arch/aa64/native.c @@ -1726,17 +1726,6 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, { u32 next_int = 0, next_fp = 0, stack = 0; int tail_call = (desc->flags & CG_CALL_TAIL) != 0; - if (abi && abi->has_sret) { - NativeLoc x8 = - aa_reg_loc(builtin_id(CFREE_CG_BUILTIN_I64), NATIVE_REG_INT, 8u); - if (desc->flags & CG_CALL_TAIL) { - AANativeTarget* a = aa_of(t); - NativeLoc saved = aa_stack_loc(x8.type, a->sret_ptr_slot, 0); - aa_load_part(t, x8, saved, 0, 8); - } else if (desc->nresults) { - aa_addr_of_loc(t, x8, desc->results[0]); - } - } for (u32 i = 0; i < desc->nargs; ++i) { ABIArgInfo tmp; const ABIArgInfo* ai = aa_param_abi(t, abi, desc, i, &tmp); @@ -1791,6 +1780,21 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, } } } + /* Set the indirect-result register (x8) *after* the argument loads: an + * argument source may have been allocated to x8, and the sret pointer load + * would otherwise clobber it before it is moved into its argument + * register. */ + if (abi && abi->has_sret) { + NativeLoc x8 = + aa_reg_loc(builtin_id(CFREE_CG_BUILTIN_I64), NATIVE_REG_INT, 8u); + if (desc->flags & CG_CALL_TAIL) { + AANativeTarget* a = aa_of(t); + NativeLoc saved = aa_stack_loc(x8.type, a->sret_ptr_slot, 0); + aa_load_part(t, x8, saved, 0, 8); + } else if (desc->nresults) { + aa_addr_of_loc(t, x8, desc->results[0]); + } + } } if (abi && abi->ret.kind == ABI_ARG_DIRECT && desc->nresults) { u32 nr = 0, ni = 0, nf = 0;