llvm / llvm/llvm-project

`SPIRVLegalizePointerCast` omits `OpBitcast` when reassembling non-integer `Load<T>` results

Open
#220,005 6 comments 0 reactions 1 assignee Claimed by @pow2clk View on GitHub
clang:HLSL:SPIRV SPIR-V
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.