| Issue |
170777
|
| Summary |
[HLSL][Matrix] Support MatrixSingleSubscript Dynamic Index Swizzle
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
farzonl
|
The introduction of the `MatrixSingleSubscriptExpr` AST type meant we needed a
custom emitter in `EmitMatrixSingleSubscriptExpr` which meant we needed a new
`MatrixRow` Lvalue type because `ExtVectorElt` had a requirment for constant
indicies. We can still use `MakeExtVectorElt` but only if the row index is
constant. For now if we don't have them then `EmitExtVectorElementExpr` fails.
Like so:
```cpp
if (Base.isMatrixRow())
return EmitUnsupportedLValue(E, "Matrix single index swizzle");
```
That means today the following cases work
```hlsl
export float4 getMatrix(float4x4 M, int index) {
return M[index];
}
export void setMatrix(out float4x4 M, int index, float4 V) {
M[index] = V;
}
export void setMatrix2(out float4x4 M, float4 V) {
M[3].abgr = V;
}
export void setMatrix3(out float4x4 M, float4 V) {
M[1].rgba = V;
}
```
That also means this doesn't work
```hlsl
export void setMatrix4(out float4x4 M, int index, float4 V) {
M[index].abgr = V;
}
export float3 getMatrix2(float4x4 M, int index) {
return M[index].rgb;
}
```
This failing case while visually similar to swizzling on an array of vectors is
very different. for an array-of-vectors, the “hard part” (the dynamic index) is
already solved before the swizzle ever sees it. For matrices, you’re trying to
push that dynamic index into the swizzle layer, where it fundamentally doesn’t
fit. Example
```hlsl
float4 v[10];
float2 x = v[i].xy;
```
The AST just treates the array subscript as a base:
```
ArraySubscriptExpr( base = v, idx = i ) --> type float4
ExtVectorElementExpr( base = ArraySubscriptExpr, "xy" )
```
Crucially: the dynamic index i is already baked into the pointer. The LValue
itself doesn’t need to remember i separately. MakeExtVectorElt only needs:
1. “where is the vector?” → baseLV.getAddress()
2. “which components (xy)?” → constant mask {0, 1}
That’s why arrays-of-vectors don’t have your problem: the dynamic part (i) is
entirely handled by the array-subscript lvalue; the swizzle only deals with
constant component selection inside a single, already-chosen vector.
With matrices, what you want conceptually is very similar:
```hlsl
float4x4 M;
float2 x = M[row].xy;
```
But the the difference is Clang’s matrix extension doesn’t model a matrix as
“array of row-vectors” or “array of col-vectors” at the IR level. Its
represented as one singular vector. For example the ir would look like
```llvm
instruction <16 x float> // for a 4x4, flattened
```
## Plan(s)
1. Keep flattened representation but add custom row abstraction
- The “swizzle” logic has to special-case “base is matrix-row” and do the right gather/scatter.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs