w6c: widen of a module-global tagged ident copies the whole box
cstage spilled frame garbage as the box; mirror the landed wwstage emission (copy from gi(SB)). The F8-era divergence-only rows gain pinned cs==ww values. Task #44.
This commit is contained in:
@@ -2611,7 +2611,8 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
for (int k = 0; k < sz; k += 8)
|
for (int k = 0; k < sz; k += 8)
|
||||||
ins2(c, A_MOVQ, areg(D_AX),
|
ins2(c, A_MOVQ, areg(D_AX),
|
||||||
amem(D_BP, write_off + k));
|
amem(D_BP, write_off + k));
|
||||||
if (src->kind == N_IDENT) {
|
if (src->kind == N_IDENT
|
||||||
|
&& localfind(*locals_p, src->str) != 0) {
|
||||||
int soff = localfind(*locals_p, src->str);
|
int soff = localfind(*locals_p, src->str);
|
||||||
for (int k = 0; k < ssz; k += 8) {
|
for (int k = 0; k < ssz; k += 8) {
|
||||||
ins2(c, A_MOVQ, amem(D_BP, soff + k),
|
ins2(c, A_MOVQ, amem(D_BP, soff + k),
|
||||||
@@ -2619,6 +2620,21 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
ins2(c, A_MOVQ, areg(D_AX),
|
ins2(c, A_MOVQ, areg(D_AX),
|
||||||
amem(D_BP, write_off + 8 + k));
|
amem(D_BP, write_off + 8 + k));
|
||||||
}
|
}
|
||||||
|
} else if (src->kind == N_IDENT) {
|
||||||
|
/* #44 (#263): a module-global tagged ident
|
||||||
|
* source has no BP slot — land gi(SB) in SI
|
||||||
|
* (aggarg_srcaddr) and copy the inner box into
|
||||||
|
* slot+8. Pre-fix the BP copy read frame garbage
|
||||||
|
* off 0(BP). ww half landed F8-c8. */
|
||||||
|
if (aggarg_srcaddr(c, src, D_SI, *locals_p)) {
|
||||||
|
for (int k = 0; k < ssz; k += 8) {
|
||||||
|
ins2(c, A_MOVQ,
|
||||||
|
amem(D_SI, k), areg(D_AX));
|
||||||
|
ins2(c, A_MOVQ, areg(D_AX),
|
||||||
|
amem(D_BP,
|
||||||
|
write_off + 8 + k));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* #38b: an sret-classified call result is in
|
/* #38b: an sret-classified call result is in
|
||||||
* memory (AX = dest pointer), not the cursor —
|
* memory (AX = dest pointer), not the cursor —
|
||||||
|
|||||||
@@ -4,29 +4,20 @@
|
|||||||
* must copy gi's whole box as the nested payload, not store its tag as the
|
* must copy gi's whole box as the nested payload, not store its tag as the
|
||||||
* payload.
|
* payload.
|
||||||
*
|
*
|
||||||
* THE BUG (cat-A silent miscompile, #263 BOTH-WRONG): cgwidentaggedstorebp's
|
* THE BUG (cat-A silent miscompile, #263 BOTH-WRONG, now CLOSED both stages):
|
||||||
* #218 nested-tagged-source arm is gated on rhstaggedident, which returns nil
|
* the #218 nested-tagged-source arm was gated local-only, so a module-global
|
||||||
* for a module-global tagged ident (local-only). So srctagged was false and a
|
* tagged source fell to the scalar word0 widen arm — gi's TAG word landed as
|
||||||
* global tagged source fell to the scalar word0 widen arm — gi's TAG word
|
* the box payload (wwstage), or frame garbage was copied, never gi(SB)
|
||||||
* landed as the box payload, the real value lost. cstage is ALSO wrong: it
|
* (cstage). The ww half landed in F8-c8; the cstage half (the nested arm's
|
||||||
* copies frame garbage (saved-BP / return-address), never gi(SB). Both wrong,
|
* N_IDENT copy grows a global branch — LEAQ gi(SB),SI via aggarg_srcaddr, copy
|
||||||
* divergent (#263); the cstage half is filed as task #44.
|
* the inner box into slot+8) landed in ww-core TASK #44. Both stages now copy
|
||||||
|
* the whole box and the .s is byte-identical.
|
||||||
*
|
*
|
||||||
* THE WWSTAGE FIX (ww-runtime-correct): srctagged also recognises a global
|
* Rows assert the exact runtime-correct value on both stages (cs==ww).
|
||||||
* tagged ident, and the nested arm's N_IDENT copy grows a global branch —
|
* row | shape | exit
|
||||||
* LEAQ gi(SB),SI via aggargsrcaddr, then copy the inner box (ssz bytes) into
|
* ----------+-----------------------------------------+-----
|
||||||
* slot+8 with the outer tag at slot+0. Local sources keep the BP copy
|
* nest_47 | gi:inner=47; (inner|str)=gi; match→v | 47
|
||||||
* (byte-id). cstage stays wrong → cs≠ww residual.
|
* nest_99 | gi:inner=99; (inner|str)=gi; match→v | 99
|
||||||
*
|
|
||||||
* cstage's residual is FRAME GARBAGE (non-deterministic across stack
|
|
||||||
* layouts), so — unlike the deterministic #263 members — the cstage rows
|
|
||||||
* assert only that cstage DIVERGES (got != the runtime-correct value and the
|
|
||||||
* build succeeded), not a pinned value. The wwstage rows assert the exact
|
|
||||||
* runtime-correct value. (#44 closes the cs side → cstage will then match.)
|
|
||||||
* row | shape | ww | cs
|
|
||||||
* ----------+-----------------------------------------+----+--------
|
|
||||||
* nest_47 | gi:inner=47; (inner|str)=gi; match→v | 47 | != 47 (garbage)
|
|
||||||
* nest_99 | gi:inner=99; (inner|str)=gi; match→v | 99 | != 99 (garbage)
|
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -154,28 +145,16 @@ main(void)
|
|||||||
drivers[d].name, drivers[d].drv);
|
drivers[d].name, drivers[d].drv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int is_ww = (d == 1);
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
total++;
|
total++;
|
||||||
int got = run_build(drivers[d].drv, &rows[i], i);
|
int got = run_build(drivers[d].drv, &rows[i], i);
|
||||||
if (is_ww) {
|
/* #44 CLOSED: cs==ww at the exact runtime-correct value
|
||||||
/* align-to-runtime-correct: exact value. */
|
* on both drivers (the .s is byte-identical). */
|
||||||
if (got != rows[i].want_ww) {
|
if (got != rows[i].want_ww) {
|
||||||
fprintf(stderr, "globtagwiden_run[wwstage][%s]:"
|
fprintf(stderr, "globtagwiden_run[%s][%s]:"
|
||||||
" exit=%d want=%d\n", rows[i].label,
|
" exit=%d want=%d\n", drivers[d].name,
|
||||||
got, rows[i].want_ww);
|
rows[i].label, got, rows[i].want_ww);
|
||||||
fail++;
|
fail++;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* #263 residual: cstage built but diverges from the
|
|
||||||
* runtime-correct value (frame garbage, #44). */
|
|
||||||
if (got == -1 || got == rows[i].want_ww) {
|
|
||||||
fprintf(stderr, "globtagwiden_run[cstage][%s]:"
|
|
||||||
" exit=%d expected build-ok and !=%d "
|
|
||||||
"(#263 residual, task #44)\n",
|
|
||||||
rows[i].label, got, rows[i].want_ww);
|
|
||||||
fail++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user