fix(ir): vector lane store resolves lane element type [F0.5]
Writing a Vector lane (`v.x = …`, `.y/.z/.w` + colour aliases) panicked with "unresolved type reached LLVM emission". The store path had no vector branch: a `.field_access` target on a Vector fell through to struct-field lookup, matched nothing, left `field_ty = .unresolved`, and built a `ptrTo(.unresolved)` that tripped the LLVM emission guard. The read path resolved the lane fine — the two had diverged (issue-0083 two-resolver class). Extract a shared `Lowering.vectorLaneIndex` resolver and route BOTH paths through it. The read path (`lowerFieldAccessOnType`) delegates to it, dropping its silent `else 0` fallback. A new vector branch in `lowerAssignment` GEPs a typed pointer to the lane (`structGepTyped`) and stores via `storeOrCompound` (plain + compound). `emitStructGep` now addresses a vector base type with a `[0, lane]` GEP. A non-lane field now reports field-not-found on both paths instead of silent-lane-0 / panic. Regression: examples/1506-vectors-lane-store.sx (panicked pre-fix, now reads back written values) + a vectorLaneIndex unit test. Resolves issue 0086; spec documents element assignment.
This commit is contained in:
46
examples/1506-vectors-lane-store.sx
Normal file
46
examples/1506-vectors-lane-store.sx
Normal file
@@ -0,0 +1,46 @@
|
||||
// Writing a `Vector` lane — `v.x = …` (and `.y`/`.z`/`.w`, plus the colour
|
||||
// aliases `.r`/`.g`/`.b`/`.a`) — stores through a pointer to that lane and
|
||||
// reads back the written value. Covers a `.[…]`-init write, a `= ---`
|
||||
// (undefined) init write, writes to every lane of a 4-lane vector, the colour
|
||||
// aliases, and a compound lane assignment (`+= / *=`).
|
||||
//
|
||||
// Regression (issue 0086): the lane STORE path fell through to struct-field
|
||||
// lookup, where no field matched a vector lane, leaving the lane pointer's
|
||||
// pointee as the `.unresolved` sentinel — which panicked at LLVM emission
|
||||
// ("unresolved type reached LLVM emission"). The store path now resolves the
|
||||
// lane index via the same shared `vectorLaneIndex` resolver the read path uses
|
||||
// and GEPs a typed pointer to the lane, so the two paths never diverge.
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: () {
|
||||
// `.[…]`-init, then write each lane of a 4-lane vector.
|
||||
v : Vector(4, f32) = .[0.0, 0.0, 0.0, 0.0];
|
||||
v.x = 1.0;
|
||||
v.y = 2.0;
|
||||
v.z = 3.0;
|
||||
v.w = 4.0;
|
||||
print("x={}\n", v.x);
|
||||
print("y={}\n", v.y);
|
||||
print("z={}\n", v.z);
|
||||
print("w={}\n", v.w);
|
||||
|
||||
// `= ---` (undefined) init, then write every lane.
|
||||
u : Vector(4, f32) = ---;
|
||||
u.x = 10.0;
|
||||
u.y = 20.0;
|
||||
u.z = 30.0;
|
||||
u.w = 40.0;
|
||||
print("u={} {} {} {}\n", u.x, u.y, u.z, u.w);
|
||||
|
||||
// Colour aliases on a 3-lane vector.
|
||||
col : Vector(3, f32) = .[0.0, 0.0, 0.0];
|
||||
col.r = 0.5;
|
||||
col.g = 0.25;
|
||||
col.b = 0.125;
|
||||
print("col={} {} {}\n", col.r, col.g, col.b);
|
||||
|
||||
// Compound lane assignment.
|
||||
col.r += 0.5;
|
||||
col.g *= 4.0;
|
||||
print("col2={} {}\n", col.r, col.g);
|
||||
}
|
||||
1
examples/expected/1506-vectors-lane-store.exit
Normal file
1
examples/expected/1506-vectors-lane-store.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/1506-vectors-lane-store.stderr
Normal file
1
examples/expected/1506-vectors-lane-store.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
7
examples/expected/1506-vectors-lane-store.stdout
Normal file
7
examples/expected/1506-vectors-lane-store.stdout
Normal file
@@ -0,0 +1,7 @@
|
||||
x=1.000000
|
||||
y=2.000000
|
||||
z=3.000000
|
||||
w=4.000000
|
||||
u=10.000000 20.000000 30.000000 40.000000
|
||||
col=0.500000 0.250000 0.125000
|
||||
col2=1.000000 1.000000
|
||||
Reference in New Issue
Block a user