This commit adds support for 'peeled arrays' in HLSL constant buffers.
HLSL CBuffers may have padding between array elements but not after the
last element. This is represented in LLVM IR as {[N-1 x {T, pad}], T}.
Changes include:
- Recognition of the peeled array pattern.
- Logic to reconstitute these into SPIR-V compatible arrays.
- Support for spirv.Padding type in GlobalRegistry and Builtins.
- Updates to SPIRVCBufferAccess to correctly calculate member offsets
in these padded structures.
Depends on https://github.com/llvm/llvm-project/pull/169076
This change drops the use of the "Layout" type and instead uses explicit
padding throughout the compiler to represent types in HLSL buffers.
There are a few parts to this, though it's difficult to split them up as
they're very interdependent:
1. Refactor HLSLBufferLayoutBuilder to allow us to calculate the padding
of arbitrary types.
2. Teach Clang CodeGen to use HLSL specific paths for cbuffers when
generating aggregate copies, array accesses, and structure accesses.
3. Simplify DXILCBufferAccesses such that it directly replaces accesses
with dx.resource.getpointer rather than recalculating the layout.
4. Basic infrastructure for SPIR-V handling, but the implementation
itself will need work in follow ups.
Fixes several issues, including #138996, #144573, and #156084.
Resolves#147352.
The comment here pointed out that RAUW would fall over given a
constantexpr, but then proceeded to just do what RAUW does by hand,
which falls over in the same way. Instead, convert constantexprs
involving cbuffer globals to instructions before processing them.
The test update just modifies the existing cbuffer test, since it
implied it was trying to test this exact case anyways.
This patch introduces a new pass, SPIRVCBufferAccess, which is
responsible for translating accesses to HLSL constant buffer (cbuffer)
global variables into accesses to the proper SPIR-V resource.
The pass operates by:
1. Identifying all cbuffers via the `!hlsl.cbs` metadata.
2. Replacing all uses of cbuffer member global variables with
`llvm.spv.resource.getpointer` intrinsics.
3. Cleaning up the original global variables and metadata.
This approach allows subsequent passes, like SPIRVEmitIntrinsics, to
correctly fold GEPs into a single OpAccessChain instruction.
The patch also includes a comprehensive set of lit tests to cover
various scenarios:
- Basic cbuffer access direct load and GEPs.
- Unused and partially unused cbuffers.
This implements the SPIR-V version of
https://github.com/llvm/wg-hlsl/blob/main/proposals/0016-constant-buffers.md#lowering-to-buffer-load-intrinsics.