`SPIRVLegalizePointerCast` omits `OpBitcast` when reassembling non-integer `Load<T>` results
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
`spirv-val` rejects compute shaders that call `ByteAddressBuffer::Load()` for non-integer types. The compiler fails with `The Object type (OpTypeInt) does not match the type that results from indexing into the Composite (OpTypeFloat)`. This is hitting 18 shaders in our validation suite.
The problem seems to start in #212999. The byte-reassembly sequence `SPIRVLegalizePointerCast` builds for `Load` on a `ByteAddressBuffer` reads four bytes at a time, combines each group of four with bitwise-or into a `%uint`. It then inserts that `%uint` result directly into the destination composite with no `OpBitcast` from `uint` to the destination scalar type in between. The reassembly threads through the byte width of the destination type but not its scalar kind, so any `Load` whose element type is not integer-typed hits this.
To reproduce, `ByteAddressBuffer buf; buf.Load(0)` in a compute shader fails validation. Disassembling the unvalidated output will show a `OpBitwiseOr %uint ...` feeding directly into `OpCompositeInsert %v4float ...`.
The reassembly sequence needs a bit-cast from the reassembled integer to the destination scalar type before the insert.
@tcorringham would you be able to take a look at this? If not, I'll put it on my list. Thanks.
Contributor guide
Assessment
This issue has not been assessed yet.