wcc: cstage array-init dispatches MOVW for esz==2 (#128a)
cstage cgen.c array-literal init dispatch now uses MOVW for esz==2 (u16/i16 element width). Was deferred (cgen.c:7194-7198 explicit TODO: "Add MOVW to w6a if real i16 arrays land") until A_MOVW landed in both stages' w6a; that prereq is now met. Fixes silent partial-init clobber where MOVQ writes 8B over a 2B slot, overwriting neighbouring elements/locals. Wwstage was already correct (selfhost/cmd/wcc/cgenutil.ww:872-877 emits MOVW for sz==2 in tnodestoreop) — cstage aligns UP to wwstage's correctness here, a rule-10 inversion from the usual align-richer-DOWN. Test 914 (4 rows: u16 full-init, u16 small-values, u8 control, i16 signed) catches the bug via the rule-10 cs==ww byte-id gate. Runtime is not a reliable lever — ww rejects truly-partial inits, and fully-init [N]u16 accident-corrects via MOVQ-overlap (each write rewrote the prior write's trailing 6B). Reviewer non-vacuity: stash the fix → 3/4 rows fail on byte-id, restore → 4/4 green. Bootstrap NEUTRAL: 990-997 byte-id + combined_ww_fresh green; zero pre-existing partial-init narrow-element callers in lib/+selfhost/. strconv stof_data tables emit DATAW (raw bytes) and bypass this path, which is why fold-2 landed clean despite the bug. Sibling bugs filed for backlog (reviewer-128a flag-don't-bundle per rule-11): #141 (cgen.c:4894-4898 variadic-gather array-store has the same dispatch gap) and #142 (wwstage cgenstmt.ww:976-990 primsize(elemn.str) returns 0 for TY_NAMED alias names → wrong- stride store on [N]alias-of-u16; cstage already TY_NAMED-peeled).
This commit is contained in:
@@ -7190,12 +7190,14 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
int op = A_MOVQ;
|
||||
if (!is_str_el) {
|
||||
if (esz == 1) op = A_MOVB;
|
||||
else if (esz == 2) op = A_MOVW;
|
||||
else if (esz == 4) op = A_MOVL;
|
||||
/* esz == 2 (i16/u16) falls through to MOVQ —
|
||||
* over-writes by 6B; the next element store
|
||||
* rewrites the high half. For the last element
|
||||
* this trails 6 bytes into the next stack slot.
|
||||
* Add MOVW to w6a if real i16 arrays land. */
|
||||
/* #128a: esz==2 routes to MOVW (A_MOVW landed in
|
||||
* both stages' w6a). Pre-fix the 2-byte case fell
|
||||
* through to MOVQ, over-writing 6B into the next
|
||||
* element's slot; sequential adjacent writes
|
||||
* accident-corrected fully-init arrays but
|
||||
* partial inits clobbered neighbours. */
|
||||
}
|
||||
int idx = 0;
|
||||
Node *last = NULL;
|
||||
|
||||
Reference in New Issue
Block a user