wcc: narrow integer pointer-deref load width via localloadop (#116)
TK_STAR integer arm now routes through localloadop (cstage cgen.c) / localloadop (wwstage cgenexpr.ww) — load-twin of the landed signed- narrow-scalar-reads fix, was omitting TK_STAR. Closes the *p (CMPQ, full-width arith) miscompile family (#116 + 962/963 instances all fixed by the same width-aware load). Float arm untouched (#96 already routed via X0). New test 947 (10 rows): packed CMPQ + signed/unsigned narrow widths + TY_NAMED/TBANG alias + TY_ENUM peel + i64/bool controls.
This commit is contained in:
@@ -2315,7 +2315,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
ins2(c, node_isf32(n) ? A_MOVSS : A_MOVSD,
|
||||
amem(D_AX, 0), areg(D_X0));
|
||||
} else {
|
||||
ins2(c, A_MOVQ, amem(D_AX, 0), areg(D_AX));
|
||||
/* Load-twin of the signed-narrow-scalar-reads
|
||||
* sweep (project_cgen_int_cast_no_truncate);
|
||||
* TK_STAR was the omitted site, refiled as
|
||||
* #116. A raw MOVQ pulls 8 bytes through a
|
||||
* narrow `*iN` and overlaps the next element
|
||||
* — the `*p` value reads honest only when the
|
||||
* caller's sink happens to truncate (i32 store,
|
||||
* i32 return). Width-preserving sinks (CMPQ,
|
||||
* 64-bit arith) saw garbage in the high bytes.
|
||||
* localloadop keys MOVSXD/MOVSWQ/MOVSBQ +
|
||||
* MOVL/MOVZWQ/MOVZBQ off n->type, with the
|
||||
* TY_NAMED / TY_ENUM peel pre-folded so an
|
||||
* aliased narrow (`type err = !i32`) lands on
|
||||
* the right opcode. */
|
||||
ins2(c, localloadop(n->type),
|
||||
amem(D_AX, 0), areg(D_AX));
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
|
||||
Reference in New Issue
Block a user