cgen: B6-c1 assign/reassign family single peels fold into type_chase_named — 9 lines, cs-only

The exact B6-c1 set (rob b6 spec §2): cgexpr :6359 (tagged-local plain
reassign lu), :6403/:6405 (deref-target assign pu/vt), :6460/:6462
(deref compound-assign pu/vt), :6518 (str/slice/struct reassign lu) +
cgstmt :11696 (nomem null-propagate r), :12047 (assign base peel bu),
:13625 (destructure-reassign rhs ru — chased; the #64 citation above it
stays, the deferral is about the tuple-literal rhs ROUTE, not this
peel). Raw `->under` in cgen.c 58→49.

TRAIN INVARIANT: cs-only — zero selfhost/ or lib/ bytes move; w6c_ww/
ww_ww bit-identical to ken's 4cac1cb baselines (md5
b6bddc8eb5c3ed8e805e50371d4b7017 / 4e9ca8741f19e1f68219ff799a5e5a14).
cs movers bounded to exactly: kb6_streassign, kb5_wstore_a (the
named c1 family); the rest of the kb4/kb5/kb6/kna corpus + five
selfhost mains byte-NEUTRAL both stages; kw1_101 / fill2 / tuparg_c /
xampdef / amplen1 detectors unmoved. 989 lib ratchet: zero flips.

LIVE graduation: kb6_streassign (the :6518 lu single-peel missed
TY_STR at 2 alias levels, fell to the scalar default — `b = a` copied
the ptr WORD0 only, len/cap stale, cs silent exit 1; ww was the
runtime-correct full 3-word reference) → 0/0 byte-id. Designed
graduation: kb5_wstore_a (ken C1-CORR-2 seed — the ident-lhs N_ASSIGN
tagged gate :6359 is cgexpr INLINE, never reached B5's :2456 funnel)
→ wstore_a_2lvl re-pinned K_RUN_NOID→K_RUN in the b5 suite (84→85
checks). kb6_sreassign / kb6_dassign latent controls byte-NEUTRAL as
ken's structural bound predicts.

New 944_alias_cgen_b6_run row table (3 rows, 9 checks): streassign_2lvl
+ sreassign_2lvl/dassign_2lvl controls; Makefile wires
test_alias_cgen_b6_run into the unit list. All 944-family suites green;
sizelint 0.
This commit is contained in:
2026-06-06 03:48:54 +09:00
parent 4cac1cbb89
commit 1f14becdf3
4 changed files with 300 additions and 23 deletions

View File

@@ -6356,7 +6356,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (n->lhs && n->lhs->kind == N_IDENT && n->op == TK_ASSIGN
&& n->lhs->type) {
Type *lt = n->lhs->type;
Type *lu = (lt && lt->kind == TY_NAMED) ? lt->under : lt;
Type *lu = type_chase_named(lt);
if (lu && lu->kind == TY_TAGGED) {
int rhs_sret_call = n->rhs
&& n->rhs->kind == N_CALL
@@ -6400,9 +6400,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (n->lhs && n->lhs->kind == N_UN && n->lhs->op == TK_STAR
&& n->op == TK_ASSIGN && !place_slit && !deref_agg) {
Type *pt = n->lhs->lhs ? n->lhs->lhs->type : NULL;
Type *pu = (pt && pt->kind == TY_NAMED) ? pt->under : pt;
Type *pu = type_chase_named(pt);
Type *vt = (pu && pu->kind == TY_PTR) ? pu->sub : NULL;
if (vt && vt->kind == TY_NAMED) vt = vt->under;
vt = type_chase_named(vt);
/* `*p = v` for *f64 / *f32: cgexpr leaves the value in X0,
* not AX. Spill X0 to the stack, evaluate the pointer
* (clobbers AX/BX freely), then reload X0 and MOVSD/MOVSS
@@ -6457,9 +6457,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (n->lhs && n->lhs->kind == N_UN && n->lhs->op == TK_STAR
&& n->op != TK_ASSIGN) {
Type *pt = n->lhs->lhs ? n->lhs->lhs->type : NULL;
Type *pu = (pt && pt->kind == TY_NAMED) ? pt->under : pt;
Type *pu = type_chase_named(pt);
Type *vt = (pu && pu->kind == TY_PTR) ? pu->sub : NULL;
if (vt && vt->kind == TY_NAMED) vt = vt->under;
vt = type_chase_named(vt);
int sz = vt ? (int)vt->size : 8;
int load_op = fldloadop(vt, sz);
int store_op = fldstoreop(vt, sz);
@@ -6515,7 +6515,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (n->lhs && n->lhs->kind == N_IDENT && n->op == TK_ASSIGN
&& n->lhs->type) {
Type *lt = n->lhs->type;
Type *lu = (lt && lt->kind == TY_NAMED) ? lt->under : lt;
Type *lu = type_chase_named(lt);
/* str/slice local/let: str IS []u8, so both store the full
* 3-word {ptr,len,cap} from (AX,BX,CX) at off+0/+8/+16
* (local) or via &name(SB) → DI scratch (global — CX holds
@@ -11693,7 +11693,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
ins2(c, A_CMPQ, aimm(0), areg(D_AX));
ins1(c, A_JNE, abranch(ok));
Type *r = cg_ret_type;
if (r && r->kind == TY_NAMED) r = r->under;
r = type_chase_named(r);
int nidx = cg_tag_for_variant(r, ty_nomem);
if (nidx < 0) nidx = 1;
ins2(c, A_MOVQ, aimm(nidx), areg(D_AX));
@@ -12043,8 +12043,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
Node *base = n->rhs->lhs;
Node *idx = n->rhs->rhs;
Type *bt = base ? base->type : NULL;
Type *bu = (bt && bt->kind == TY_NAMED)
? bt->under : bt;
Type *bu = type_chase_named(bt);
if (base && base->kind == N_IDENT && bu
&& bu->kind == TY_ARRAY) {
int esz = (bu->sub)
@@ -13622,7 +13621,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
* (silent skew) — the #57 decl wire stops at return/let. */
cgexpr(c, n->rhs, *locals);
Type *rt = n->rhs ? n->rhs->type : NULL;
Type *ru = (rt && rt->kind == TY_NAMED) ? rt->under : rt;
Type *ru = type_chase_named(rt);
Tparam *tp0 = (ru && ru->kind == TY_TUPLE) ? ru->params : NULL;
int mf32;
if (sret_recv > 0) {