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:
@@ -756,13 +756,8 @@ entry:
|
||||
%allocaN = alloca [4 x i64], align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
%ig.tmp = alloca [4 x i64], align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
%ig.tmp15 = alloca [4 x i64], align 8
|
||||
%ig.tmp20 = alloca [4 x i64], align 8
|
||||
%ig.tmp26 = alloca [4 x i64], align 8
|
||||
%ig.tmp36 = alloca [4 x i64], align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %1, ptr %alloca, align 8
|
||||
%load = load i64, ptr %alloca, align 8
|
||||
@@ -782,11 +777,9 @@ if.merge.67: ; preds = %entry
|
||||
br label %while.hdr.76
|
||||
|
||||
while.hdr.76: ; preds = %while.exit.87, %if.merge.67
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp, align 8
|
||||
%ig.ptr = getelementptr [4 x i64], ptr %ig.tmp, i64 0, i64 0
|
||||
%ig.val = load i64, ptr %ig.ptr, align 8
|
||||
%icmpN = icmp ne i64 %ig.val, 0
|
||||
%igp.ptr = getelementptr i64, ptr %allocaN, i64 0
|
||||
%loadN = load i64, ptr %igp.ptr, align 8
|
||||
%icmpN = icmp ne i64 %loadN, 0
|
||||
br i1 %icmpN, label %or.merge.80, label %or.rhs.79
|
||||
|
||||
while.body.77: ; preds = %or.merge.84
|
||||
@@ -804,11 +797,9 @@ while.exit.78: ; preds = %or.merge.84
|
||||
ret { ptr, i64 } %callN
|
||||
|
||||
or.rhs.79: ; preds = %while.hdr.76
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp15, align 8
|
||||
%ig.ptr16 = getelementptr [4 x i64], ptr %ig.tmp15, i64 0, i64 1
|
||||
%ig.val17 = load i64, ptr %ig.ptr16, align 8
|
||||
%icmpN = icmp ne i64 %ig.val17, 0
|
||||
%igp.ptr14 = getelementptr i64, ptr %allocaN, i64 1
|
||||
%loadN = load i64, ptr %igp.ptr14, align 8
|
||||
%icmpN = icmp ne i64 %loadN, 0
|
||||
br label %or.merge.80
|
||||
|
||||
or.merge.80: ; preds = %or.rhs.79, %while.hdr.76
|
||||
@@ -816,11 +807,9 @@ or.merge.80: ; preds = %or.rhs.79, %while.h
|
||||
br i1 %bp, label %or.merge.82, label %or.rhs.81
|
||||
|
||||
or.rhs.81: ; preds = %or.merge.80
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp20, align 8
|
||||
%ig.ptr21 = getelementptr [4 x i64], ptr %ig.tmp20, i64 0, i64 2
|
||||
%ig.val22 = load i64, ptr %ig.ptr21, align 8
|
||||
%icmpN = icmp ne i64 %ig.val22, 0
|
||||
%igp.ptr17 = getelementptr i64, ptr %allocaN, i64 2
|
||||
%loadN = load i64, ptr %igp.ptr17, align 8
|
||||
%icmpN = icmp ne i64 %loadN, 0
|
||||
br label %or.merge.82
|
||||
|
||||
or.merge.82: ; preds = %or.rhs.81, %or.merge.80
|
||||
@@ -828,11 +817,9 @@ or.merge.82: ; preds = %or.rhs.81, %or.merg
|
||||
br i1 %bpN, label %or.merge.84, label %or.rhs.83
|
||||
|
||||
or.rhs.83: ; preds = %or.merge.82
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp26, align 8
|
||||
%ig.ptr27 = getelementptr [4 x i64], ptr %ig.tmp26, i64 0, i64 3
|
||||
%ig.val28 = load i64, ptr %ig.ptr27, align 8
|
||||
%icmpN = icmp ne i64 %ig.val28, 0
|
||||
%igp.ptr21 = getelementptr i64, ptr %allocaN, i64 3
|
||||
%loadN = load i64, ptr %igp.ptr21, align 8
|
||||
%icmpN = icmp ne i64 %loadN, 0
|
||||
br label %or.merge.84
|
||||
|
||||
or.merge.84: ; preds = %or.rhs.83, %or.merge.82
|
||||
@@ -847,18 +834,16 @@ while.hdr.85: ; preds = %while.body.86, %whi
|
||||
while.body.86: ; preds = %while.hdr.85
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%mul = mul i64 %loadN, 65536
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp36, align 8
|
||||
%ig.ptr37 = getelementptr [4 x i64], ptr %ig.tmp36, i64 0, i64 %loadN
|
||||
%ig.val38 = load i64, ptr %ig.ptr37, align 8
|
||||
%addN = add i64 %mul, %ig.val38
|
||||
%igp.ptr29 = getelementptr i64, ptr %allocaN, i64 %loadN
|
||||
%loadN = load i64, ptr %igp.ptr29, align 8
|
||||
%addN = add i64 %mul, %loadN
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%sdiv = sdiv i64 %loadN, 10
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%igp.ptr = getelementptr i64, ptr %allocaN, i64 %loadN
|
||||
store i64 %sdiv, ptr %igp.ptr, align 8
|
||||
%igp.ptr35 = getelementptr i64, ptr %allocaN, i64 %loadN
|
||||
store i64 %sdiv, ptr %igp.ptr35, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%srem = srem i64 %loadN, 10
|
||||
store i64 %srem, ptr %allocaN, align 8
|
||||
@@ -873,9 +858,9 @@ while.exit.87: ; preds = %while.hdr.85
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%igp.data = extractvalue { ptr, i64 } %loadN, 0
|
||||
%igp.ptr50 = getelementptr i8, ptr %igp.data, i64 %loadN
|
||||
%igp.ptr43 = getelementptr i8, ptr %igp.data, i64 %loadN
|
||||
%trunc = trunc i64 %addN to i8
|
||||
store i8 %trunc, ptr %igp.ptr50, align 1
|
||||
store i8 %trunc, ptr %igp.ptr43, align 1
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%subN = sub i64 %loadN, 1
|
||||
store i64 %subN, ptr %allocaN, align 8
|
||||
@@ -1197,7 +1182,6 @@ if.then.74: ; preds = %if.merge.73
|
||||
br label %if.merge.75
|
||||
|
||||
if.merge.75: ; preds = %if.then.74, %if.merge.73
|
||||
store [4 x i64] undef, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%igp.ptr = getelementptr i64, ptr %allocaN, i64 0
|
||||
store i64 %loadN, ptr %igp.ptr, align 8
|
||||
@@ -1220,10 +1204,6 @@ entry:
|
||||
%alloca = alloca i64, align 8
|
||||
%allocaN = alloca [4 x i64], align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%ig.tmp = alloca [4 x i64], align 8
|
||||
%ig.tmp9 = alloca [4 x i64], align 8
|
||||
%ig.tmp14 = alloca [4 x i64], align 8
|
||||
%ig.tmp19 = alloca [4 x i64], align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %1, ptr %alloca, align 8
|
||||
%load = load i64, ptr %alloca, align 8
|
||||
@@ -1240,29 +1220,21 @@ if.merge.380: ; preds = %entry
|
||||
%callN = call { ptr, i64 } @cstring(ptr %0, i64 16)
|
||||
store { ptr, i64 } %callN, ptr %allocaN, align 8
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp, align 8
|
||||
%ig.ptr = getelementptr [4 x i64], ptr %ig.tmp, i64 0, i64 0
|
||||
%ig.val = load i64, ptr %ig.ptr, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 0, i64 %ig.val)
|
||||
%igp.ptr = getelementptr i64, ptr %allocaN, i64 0
|
||||
%loadN = load i64, ptr %igp.ptr, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 0, i64 %loadN)
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp9, align 8
|
||||
%ig.ptr10 = getelementptr [4 x i64], ptr %ig.tmp9, i64 0, i64 1
|
||||
%ig.val11 = load i64, ptr %ig.ptr10, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 4, i64 %ig.val11)
|
||||
%igp.ptr8 = getelementptr i64, ptr %allocaN, i64 1
|
||||
%loadN = load i64, ptr %igp.ptr8, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 4, i64 %loadN)
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp14, align 8
|
||||
%ig.ptr15 = getelementptr [4 x i64], ptr %ig.tmp14, i64 0, i64 2
|
||||
%ig.val16 = load i64, ptr %ig.ptr15, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 8, i64 %ig.val16)
|
||||
%igp.ptr11 = getelementptr i64, ptr %allocaN, i64 2
|
||||
%loadN = load i64, ptr %igp.ptr11, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 8, i64 %loadN)
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load [4 x i64], ptr %allocaN, align 8
|
||||
store [4 x i64] %loadN, ptr %ig.tmp19, align 8
|
||||
%ig.ptr20 = getelementptr [4 x i64], ptr %ig.tmp19, i64 0, i64 3
|
||||
%ig.val21 = load i64, ptr %ig.ptr20, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 12, i64 %ig.val21)
|
||||
%igp.ptr14 = getelementptr i64, ptr %allocaN, i64 3
|
||||
%loadN = load i64, ptr %igp.ptr14, align 8
|
||||
call void @hex_group(ptr %0, { ptr, i64 } %loadN, i64 12, i64 %loadN)
|
||||
store i64 0, ptr %allocaN, align 8
|
||||
br label %while.hdr.387
|
||||
|
||||
@@ -1275,9 +1247,9 @@ while.body.388: ; preds = %while.hdr.387
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%ig.data = extractvalue { ptr, i64 } %loadN, 0
|
||||
%ig.ptr27 = getelementptr i8, ptr %ig.data, i64 %loadN
|
||||
%ig.val28 = load i8, ptr %ig.ptr27, align 1
|
||||
%cmp.ext = zext i8 %ig.val28 to i64
|
||||
%ig.ptr = getelementptr i8, ptr %ig.data, i64 %loadN
|
||||
%ig.val = load i8, ptr %ig.ptr, align 1
|
||||
%cmp.ext = zext i8 %ig.val to i64
|
||||
%icmpN = icmp ne i64 %cmp.ext, 48
|
||||
br i1 %icmpN, label %if.then.390, label %if.merge.391
|
||||
|
||||
|
||||
Reference in New Issue
Block a user