cgen: key the tagged-widen struct copy on natural size, not slot size
cgwidentaggedstorebp's struct-ident arms (local and module-global) counted copy bytes from structinfo.totsize, the round-8 slot width, so a struct whose natural size is not a multiple of 8 took the MOVQ word loop and copied the source slot's dirty pad bytes over the zero-fill the arm itself just established; the width-true tail emitter beneath was dead code. cstage keys the same copy on su->size. Route both arms through copysrcnatsize (the stamped-tinfo natural size, #71). Graduates r71_tagged_return_scratch_mixed.
This commit is contained in:
3
Makefile
3
Makefile
@@ -583,8 +583,7 @@ DATABYTEID_EXPECTED_MIN = 911
|
|||||||
# When a compiler fix lands the entry fails demanding graduation out of
|
# When a compiler fix lands the entry fails demanding graduation out of
|
||||||
# this list rather than silently widening coverage. Tracked with the #59
|
# this list rather than silently widening coverage. Tracked with the #59
|
||||||
# divergence family.
|
# divergence family.
|
||||||
DATABYTEID_DIVERGED = r71_tagged_return_scratch_mixed \
|
DATABYTEID_DIVERGED = r76_typeeq_fn_diff_arity r76_typeeq_fn_diff_param_type \
|
||||||
r76_typeeq_fn_diff_arity r76_typeeq_fn_diff_param_type \
|
|
||||||
r76_typeeq_fn_io_vtable_shape r76_typeeq_fn_variadic_vs_fixed \
|
r76_typeeq_fn_io_vtable_shape r76_typeeq_fn_variadic_vs_fixed \
|
||||||
r940_str_forrange_arg
|
r940_str_forrange_arg
|
||||||
$(if $(DATABYTEID_FILES),,$(error test-byteid: empty data corpus))
|
$(if $(DATABYTEID_FILES),,$(error test-byteid: empty data corpus))
|
||||||
|
|||||||
@@ -4842,7 +4842,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
|
|||||||
let gtag: i32 = taggedvariantindext(c, dt, src);
|
let gtag: i32 = taggedvariantindext(c, dt, src);
|
||||||
if (gtag < 0) { gtag = 0; };
|
if (gtag < 0) { gtag = 0; };
|
||||||
if (aggargsrcaddr(c, src, "SI")) {
|
if (aggargsrcaddr(c, src, "SI")) {
|
||||||
let gtot: i32 = gsi.totsize;
|
// Natural size, not slot-padded (see the
|
||||||
|
// local-ident twin below; cstage su->size).
|
||||||
|
let gtot: i32 = copysrcnatsize(c, src);
|
||||||
let gk: i32 = 0;
|
let gk: i32 = 0;
|
||||||
for (gk + 8 <= gtot) {
|
for (gk + 8 <= gtot) {
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
@@ -4913,7 +4915,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
|
|||||||
let lc: *local = localfindnode(c, src.str);
|
let lc: *local = localfindnode(c, src.str);
|
||||||
let soff: i32 = 0;
|
let soff: i32 = 0;
|
||||||
if (lc != nil) { soff = lc.off; };
|
if (lc != nil) { soff = lc.off; };
|
||||||
let stotal: i32 = si.totsize;
|
// Copy the NATURAL size (cstage su->size): the slot-
|
||||||
|
// padded totsize would MOVQ the source slot's dirty
|
||||||
|
// pad bytes over the zero-fill just established.
|
||||||
|
let stotal: i32 = copysrcnatsize(c, src);
|
||||||
let ki: i32 = 0;
|
let ki: i32 = 0;
|
||||||
for (ki + 8 <= stotal) {
|
for (ki + 8 <= stotal) {
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
|
|||||||
Reference in New Issue
Block a user