w6c+wwstage: array global-aggregate-receive g = f() (#272 commit-2)

The caller-half of the global case: `g = mk()` into a GLOBAL array
stored only the first word — a ≤24B reg-return landed `MOVQ AX, g(SB)`
(8 of 24 bytes); a >24B sret-return hit the #220 sret-to-symbol gate
which was TY_STRUCT-only and fell through to the same truncation.

≤24B: the local aggregate-receive arm was `off != 0`-only, so a global
array fell to the scalar IDENT store. Add a global ARRAY arm — LEAQ
name(SB), DI then store the full+tail words from AX/DX/CX (an array is
never float-class, so AX/DX/CX is always the transport; no `g+8(SB)`
operand form exists). Mirrors the str/slice global arm.
>24B: add TY_ARRAY to the #220 sret-to-symbol gate (cg_sret_dest_sym /
sretdestnode) — the callee writes the whole array through RDI.

A ≤24B STRUCT global receive can be float-class (X0/X1, not AX/DX/CX),
so it is left at its pre-existing symmetric behaviour — no consumer.

949_aggret_source_run gains global_recv (c → 15) and global_recv_sret
(>24B → 22), both with per-row byte-id.
This commit is contained in:
2026-06-02 15:00:55 +09:00
parent 0d39129741
commit 9d81ba77b7
5 changed files with 249 additions and 50 deletions

View File

@@ -103,6 +103,22 @@ static const struct row rows[] = {
"fn mk(p: *pair) pair = { return *p; };\n"
"export fn main() i32 = { let x: pair = pair { a = 5i64, b = 9i64 };\n"
" let r: pair = mk(&x); return (r.a + r.b): i32; };\n", 14 },
/* #272 commit-2 caller-half: `g = mk()` into a GLOBAL array ≤24B.
* The receive must store the full AX/DX/CX, not the 8-byte AX
* truncation (g[1]/g[2] would read 0). */
{ "global_recv",
"package main;\n"
"let g: [3]i64 = [0i64, 0i64, 0i64];\n"
"fn mk() [3]i64 = { return [4i64, 5i64, 6i64]; };\n"
"export fn main() i32 = { g = mk();\n"
" return (g[0]+g[1]+g[2]): i32; };\n", 15 },
/* global receive into a >24B array — the sret-to-symbol path. */
{ "global_recv_sret",
"package main;\n"
"let g: [4]i64 = [0i64,0i64,0i64,0i64];\n"
"fn mk(p: *[4]i64) [4]i64 = { return *p; };\n"
"export fn main() i32 = { let a: [4]i64 = [4i64,5i64,6i64,7i64];\n"
" g = mk(&a); return (g[0]+g[1]+g[2]+g[3]): i32; };\n", 22 },
{ NULL, NULL, 0 }
};