From 5c68c190d08b1e5da0100b4b1ca9880a89194c57 Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Wed, 29 Jul 2026 16:58:16 -0400 Subject: [PATCH] [SPIR-V] Fix vk::BufferPointer bitfield stores Preserve the bitfield AST type and align the generated load and store. --- tools/clang/lib/SPIRV/SpirvBuilder.cpp | 8 ++++++-- .../vk.buffer-pointer.bitfield.hlsl | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tools/clang/test/CodeGenSPIRV/vk.buffer-pointer.bitfield.hlsl diff --git a/tools/clang/lib/SPIRV/SpirvBuilder.cpp b/tools/clang/lib/SPIRV/SpirvBuilder.cpp index f61d61ed71..c170586abd 100644 --- a/tools/clang/lib/SPIRV/SpirvBuilder.cpp +++ b/tools/clang/lib/SPIRV/SpirvBuilder.cpp @@ -305,6 +305,7 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address, } SpirvInstruction *source = value; + SpirvLoad *bitfieldLoad = nullptr; const auto &bitfieldInfo = address->getBitfieldInfo(); if (bitfieldInfo.hasValue()) { // Generate SPIR-V type for value. This is required to know the final @@ -313,11 +314,12 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address, lowerTypeVisitor.visitInstruction(value); context.addToInstructionsWithLoweredType(value); - auto *base = createLoad(value->getResultType(), address, loc, range); - source = createBitFieldInsert(/*QualType*/ {}, base, value, + bitfieldLoad = createLoad(value->getResultType(), address, loc, range); + source = createBitFieldInsert(/*QualType*/ {}, bitfieldLoad, value, bitfieldInfo->offsetInBits, bitfieldInfo->sizeInBits, loc, range); source->setResultType(value->getResultType()); + source->setAstResultType(value->getAstResultType()); } auto *instruction = @@ -337,6 +339,8 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address, std::tie(align, size) = alignmentCalc.getAlignmentAndSize( source->getAstResultType(), address->getLayoutRule(), llvm::None, &stride); + if (bitfieldLoad) + bitfieldLoad->setAlignment(align); instruction->setAlignment(align); } diff --git a/tools/clang/test/CodeGenSPIRV/vk.buffer-pointer.bitfield.hlsl b/tools/clang/test/CodeGenSPIRV/vk.buffer-pointer.bitfield.hlsl new file mode 100644 index 0000000000..b2b4c813be --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/vk.buffer-pointer.bitfield.hlsl @@ -0,0 +1,20 @@ +// RUN: %dxc -spirv -E main -T cs_6_7 %s | FileCheck %s + +struct Foo { + uint a : 16; + uint b : 16; +}; + +[[vk::push_constant]] struct Pc { + vk::BufferPointer ptr; +} pc; + +[numthreads(1, 1, 1)] +void main() { + pc.ptr.Get().a = 123; +} + +// CHECK: [[FIELD:%[0-9]+]] = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%[0-9]+}} %int_0 +// CHECK: [[OLD:%[0-9]+]] = OpLoad %uint [[FIELD]] Aligned 4 +// CHECK: [[NEW:%[0-9]+]] = OpBitFieldInsert %uint [[OLD]] %uint_123 %uint_0 %uint_16 +// CHECK: OpStore [[FIELD]] [[NEW]] Aligned 4