fix(0124): large stack arrays lower to in-place access, not first-class values
Two lowering sites materialized a local array as a whole LLVM value;
the legalizer scalarizes each such op into one SelectionDAG node per
element, and at ~64K elements the DAG combiner segfaults
(DAGCombiner::visitMERGE_VALUES → ReplaceAllUsesWith).
- lowerVarDecl: an array-typed `---` initializer emits NO store — the
slot stays uninitialized instead of receiving a whole-array undef
store. The tuple zero-init carve-out stays; non-array `---` keeps
the undef store. The interp is unchanged either way (slots start
.undef).
- lowerIndexExpr: element reads on an array with addressable storage
GEP the storage and load one element — the general-expression
sibling of 0110's lowerFor fix — without value-lowering the object
(a dead whole-array load would still reach the DAG). Storage-less
arrays keep the index_get fallback.
Sibling shape filed as 0125: any_to_string's per-array-type arms still
pass the array by value, so a 64K+ array type + any {} print crashes.
Regression: examples/0055-basic-large-stack-array.sx (sx build
segfaulted pre-fix). 22 .ir snapshots re-pinned: removed undef stores
and ig.tmp spills, in-place gep+load (instruction-shape-only churn,
reviewed).
This commit is contained in:
@@ -1,4 +1,26 @@
|
||||
# 0124 — 64K+ stack arrays emit whole-aggregate load/store ops that segfault LLVM
|
||||
# RESOLVED — 0124: 64K+ stack arrays emit whole-aggregate load/store ops that segfault LLVM
|
||||
|
||||
> **RESOLVED** (2026-06-12). Root cause: two lowering sites materialized
|
||||
> a local array as a first-class LLVM value, which the legalizer
|
||||
> scalarizes into one SelectionDAG node per element. Fix: (1)
|
||||
> `lowerVarDecl` (src/ir/lower/stmt.zig) emits NO store for an
|
||||
> array-typed `---` initializer — the slot stays uninitialized instead
|
||||
> of receiving a whole-array undef store (tuple zero-init carve-out
|
||||
> kept; non-array `---` keeps the undef store); (2) `lowerIndexExpr`
|
||||
> (src/ir/lower/expr.zig) reads elements of an array with addressable
|
||||
> storage via `index_gep` on the storage + a single-element load — the
|
||||
> general-expression sibling of 0110's `lowerFor` fix — without
|
||||
> value-lowering the object (a dead whole-array load would still reach
|
||||
> the DAG). Storage-less arrays (rvalues, by-value params) keep the
|
||||
> `index_get` fallback. Residual sibling shapes filed as issue 0125
|
||||
> (`any_to_string`'s per-array-type arms pass the array by value — any
|
||||
> 64K+ array type + any `{}` print still crashes).
|
||||
> Regression test: `examples/0055-basic-large-stack-array.sx`
|
||||
> ([65536]u8 write/read loops + [131072]s64 first/last — `sx build`
|
||||
> segfaulted pre-fix). 22 `.ir` snapshots re-pinned (removed undef
|
||||
> stores / `ig.tmp` spills → in-place gep+load; reviewed
|
||||
> instruction-shape-only). Gates: zig build test 426/426, suite
|
||||
> 592/592, distribution repo 14/14.
|
||||
|
||||
## Symptom
|
||||
|
||||
|
||||
Reference in New Issue
Block a user