wwstage: fold chained global-ptr field READ to cstage offset-fold (#16)
wwstage's chained-N_DOT resolver (dotchainresolve) didn't resolve a global
*struct root (only local *T and global value-struct), so gp.sf.len / gp.x.y
bailed to an inner-dot load + shuffle, byte-diverging from cstage's offset-fold.
Both stages already ran correct after #15 (475c003) -- a pure rule-10 asm
divergence. cstage is untouched (the oracle); wwstage aligns up.
Resolve a global N_TPTR root, and extract emitchainbase for the viacx base-load
(byte-identical across the 5 read + 2 store sites it replaces). The chained
STORE caller declines the global-ptr root (yok=false) so it falls to cstage's
address-spine mirror -- matching the #6/#15 decline-to-resolver discipline;
local *T chained stores still fold.
Test: +2 chained rows (gp.sf.len, gp.x.q), runtime + byte-id; proven to fail
byte-id with only the compiler files reverted, pass with the fix.
Sibling follow-ups filed: #17 (>32B tagged word-order), #18 (chained read into
an i64 sink MOVSXD check).
This commit is contained in:
@@ -4942,6 +4942,28 @@ export fn dotchainresolve(c: *cgen, n: *syntax.node,
|
||||
};
|
||||
};
|
||||
};
|
||||
// Global `*struct` root (`let gp: *S`): localfindnode is nil and
|
||||
// letvarstructinfo below only matches a VALUE-struct global, so a
|
||||
// `*struct` global root needs its own arm. Gate on N_TPTR→N_TNAME
|
||||
// exactly as the local `*T` arm above; the post-resolution loop peels
|
||||
// the TY_PTR off cur.type_ and validates the pointee is a struct.
|
||||
// Mirrors cstage cgen.c's ptr_root + let_islet base resolution
|
||||
// (LEAQ name(SB),CX; MOVQ (CX),CX). (#16, chained twin of #15.)
|
||||
if (!resolved && lc == nil) {
|
||||
let gtn: *syntax.node = letvartnode(c, cur.str);
|
||||
if (gtn != nil) {
|
||||
if (gtn.kind == syntax.nkind.N_TPTR) {
|
||||
let pe: *syntax.node = gtn.lhs;
|
||||
if (pe != nil) {
|
||||
if (pe.kind == syntax.nkind.N_TNAME) {
|
||||
*outisglobal = true;
|
||||
*outptrroot = true;
|
||||
resolved = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
if (!resolved) {
|
||||
let gsi: *structinfo = letvarstructinfo(c, cur.str);
|
||||
if (gsi != nil) {
|
||||
|
||||
Reference in New Issue
Block a user