Skip to content

Commit 5c68c19

Browse files
committed
[SPIR-V] Fix vk::BufferPointer bitfield stores
Preserve the bitfield AST type and align the generated load and store.
1 parent 687f7c3 commit 5c68c19

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

tools/clang/lib/SPIRV/SpirvBuilder.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address,
305305
}
306306

307307
SpirvInstruction *source = value;
308+
SpirvLoad *bitfieldLoad = nullptr;
308309
const auto &bitfieldInfo = address->getBitfieldInfo();
309310
if (bitfieldInfo.hasValue()) {
310311
// Generate SPIR-V type for value. This is required to know the final
@@ -313,11 +314,12 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address,
313314
lowerTypeVisitor.visitInstruction(value);
314315
context.addToInstructionsWithLoweredType(value);
315316

316-
auto *base = createLoad(value->getResultType(), address, loc, range);
317-
source = createBitFieldInsert(/*QualType*/ {}, base, value,
317+
bitfieldLoad = createLoad(value->getResultType(), address, loc, range);
318+
source = createBitFieldInsert(/*QualType*/ {}, bitfieldLoad, value,
318319
bitfieldInfo->offsetInBits,
319320
bitfieldInfo->sizeInBits, loc, range);
320321
source->setResultType(value->getResultType());
322+
source->setAstResultType(value->getAstResultType());
321323
}
322324

323325
auto *instruction =
@@ -337,6 +339,8 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address,
337339
std::tie(align, size) = alignmentCalc.getAlignmentAndSize(
338340
source->getAstResultType(), address->getLayoutRule(), llvm::None,
339341
&stride);
342+
if (bitfieldLoad)
343+
bitfieldLoad->setAlignment(align);
340344
instruction->setAlignment(align);
341345
}
342346

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %dxc -spirv -E main -T cs_6_7 %s | FileCheck %s
2+
3+
struct Foo {
4+
uint a : 16;
5+
uint b : 16;
6+
};
7+
8+
[[vk::push_constant]] struct Pc {
9+
vk::BufferPointer<Foo> ptr;
10+
} pc;
11+
12+
[numthreads(1, 1, 1)]
13+
void main() {
14+
pc.ptr.Get().a = 123;
15+
}
16+
17+
// CHECK: [[FIELD:%[0-9]+]] = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%[0-9]+}} %int_0
18+
// CHECK: [[OLD:%[0-9]+]] = OpLoad %uint [[FIELD]] Aligned 4
19+
// CHECK: [[NEW:%[0-9]+]] = OpBitFieldInsert %uint [[OLD]] %uint_123 %uint_0 %uint_16
20+
// CHECK: OpStore [[FIELD]] [[NEW]] Aligned 4

0 commit comments

Comments
 (0)