diff --git a/test/wcc/689_globptr_field_read_run.c b/test/wcc/689_globptr_field_read_run.c index 252e82c9..88d2c174 100644 --- a/test/wcc/689_globptr_field_read_run.c +++ b/test/wcc/689_globptr_field_read_run.c @@ -31,6 +31,7 @@ * bump param p.f (param control) | 10 * gp.sf.len (CHAINED str leaf) | 3 (#16) * gp.x.q (CHAINED struct leaf)| 7 (#16) + * gp.x.q i64 sink, (v>>32) | 1 (#18 spine-narrow PIN) * Each row also asserts w6c .s == w6c_ww .s byte-identical. * Pre-fix: cstage SEGV(139) on every global-ptr row; wwstage ran wrong; * cs vs ww .s differed. @@ -153,6 +154,20 @@ static const struct row ROWS[] = { "let gp: *S = nil;\n" "export fn main() i32 = { let s: S = S{a=0,x=Inner{p=0,q=0}}; gp = &s;" " s.x.q = 7; return gp.x.q: i32; };\n", 7 }, +/* #18 PIN: a CHAINED read into an i64 SINK must NOT carry a spurious load/ + * spine narrow. q holds 0x1_0000_0001; we observe the HIGH word via + * (v>>32):i32 — a truncating MOVSXD on the chained load would sign-extend + * the low word (1) and the high word would vanish (1 -> 0). The legitimate + * MOVSXD must stay on the `:i32` RETURN cast only (after a full 64-bit + * SARQ over the complete i64). Verified no-bug at HEAD; this row guards the + * spine-narrow family (cf. fld-load-op / int-cast-no-truncate fixes). */ +{ "chain_i64_sink", + "package main;\n" + "type T = struct { q: i64 };\n" + "type S = struct { x: T };\n" + "let gp: *S = nil;\n" + "export fn main() i32 = { let s: S = S{x=T{q=0}}; gp = &s;" + " s.x.q = 4294967297; let v: i64 = gp.x.q; return (v >> 32): i32; };\n", 1 }, }; #define NROWS ((int)(sizeof ROWS / sizeof ROWS[0]))