diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 75eba81c57..56fbaa5e51 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -33,6 +33,9 @@ line upon naming the release. Refer to previous for appropriate section names. - Fix a crash generating DXIL from sources containing a dynamic resource heap access that was discarded. Identified during development of SPIR-V support for [descriptor heaps](https://github.com/microsoft/DirectXShaderCompiler/pull/8517#discussion_r3752113078). +- SPIR-V: Fixed a crash when writing to a bitfield member through a + `vk::BufferPointer` + [#8402](https://github.com/microsoft/DirectXShaderCompiler/issues/8402). #### HLSL Language diff --git a/tools/clang/lib/SPIRV/SpirvBuilder.cpp b/tools/clang/lib/SPIRV/SpirvBuilder.cpp index d8eceaccc6..216025c984 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