Skip to content

Commit fea1ab6

Browse files
committed
Add a check to test unique implicit binding numbers.
1 parent 4be20d9 commit fea1ab6

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,32 @@ void SPIRVLegalizeImplicitBinding::collectBindingInfo(Module &M) {
9292
cast<ConstantInt>(B->getArgOperand(OrderIdArgIdx))->getZExtValue();
9393
return OrderA < OrderB;
9494
});
95+
96+
// Check that the order Id is unique per resource.
97+
for (uint32_t i = 1; i < ImplicitBindingCalls.size(); ++i) {
98+
const uint32_t OrderIdArgIdx = 0;
99+
const uint32_t DescSetArgIdx = 1;
100+
const uint32_t OrderA =
101+
cast<ConstantInt>(
102+
ImplicitBindingCalls[i - 1]->getArgOperand(OrderIdArgIdx))
103+
->getZExtValue();
104+
const uint32_t OrderB =
105+
cast<ConstantInt>(ImplicitBindingCalls[i]->getArgOperand(OrderIdArgIdx))
106+
->getZExtValue();
107+
if (OrderA == OrderB) {
108+
const uint32_t DescSetA =
109+
cast<ConstantInt>(
110+
ImplicitBindingCalls[i - 1]->getArgOperand(DescSetArgIdx))
111+
->getZExtValue();
112+
const uint32_t DescSetB =
113+
cast<ConstantInt>(
114+
ImplicitBindingCalls[i]->getArgOperand(DescSetArgIdx))
115+
->getZExtValue();
116+
assert(DescSetA == DescSetB &&
117+
"If two implicit binding calls have the same order ID, they must "
118+
"also have the same descriptor set.");
119+
}
120+
}
95121
}
96122

97123
uint32_t SPIRVLegalizeImplicitBinding::getAndReserveFirstUnusedBinding(
@@ -112,7 +138,8 @@ uint32_t SPIRVLegalizeImplicitBinding::getAndReserveFirstUnusedBinding(
112138
}
113139

114140
void SPIRVLegalizeImplicitBinding::replaceImplicitBindingCalls(Module &M) {
115-
std::unordered_map<uint32_t, uint32_t> OrderIdToBinding;
141+
uint32_t lastOrderId = -1;
142+
uint32_t lastBindingNumber = -1;
116143

117144
for (CallInst *OldCI : ImplicitBindingCalls) {
118145
IRBuilder<> Builder(OldCI);
@@ -123,11 +150,11 @@ void SPIRVLegalizeImplicitBinding::replaceImplicitBindingCalls(Module &M) {
123150

124151
// Reuse an existing binding for this order ID, if one was already assigned.
125152
// Otherwise, assign a new binding.
126-
const uint32_t NewBinding =
127-
(OrderIdToBinding.find(OrderId) != OrderIdToBinding.end())
128-
? OrderIdToBinding[OrderId]
129-
: getAndReserveFirstUnusedBinding(DescSet);
130-
OrderIdToBinding[OrderId] = NewBinding;
153+
const uint32_t NewBinding = (lastOrderId == OrderId)
154+
? lastBindingNumber
155+
: getAndReserveFirstUnusedBinding(DescSet);
156+
lastOrderId = OrderId;
157+
lastBindingNumber = NewBinding;
131158

132159
SmallVector<Value *, 8> Args;
133160
Args.push_back(Builder.getInt32(DescSet));

llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
; CHECK-DAG: OpDecorate [[g]] Binding 0
3333
; CHECK-DAG: OpDecorate [[h]] DescriptorSet 10
3434
; CHECK-DAG: OpDecorate [[h]] Binding 3
35+
; CHECK-NOT: OpDecorate [[h]] Binding 4
3536
; CHECK-DAG: OpDecorate [[i]] DescriptorSet 10
3637
; CHECK-DAG: OpDecorate [[i]] Binding 2
3738

@@ -45,8 +46,8 @@ entry:
4546
%4 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefrombinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 10, i32 1, i32 1, i32 0, ptr nonnull @.str.8)
4647
%5 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 2, i32 10, i32 1, i32 0, ptr nonnull @.str.10)
4748
%6 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 3, i32 10, i32 2, i32 0, ptr nonnull @.str.12)
48-
%7 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefrombinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 10, i32 2, i32 1, i32 0, ptr nonnull @.str.14)
49-
%8 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 3, i32 10, i32 2, i32 1, ptr nonnull @.str.12)
49+
%7 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 3, i32 10, i32 2, i32 1, ptr nonnull @.str.12)
50+
%8 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefrombinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 10, i32 2, i32 1, i32 0, ptr nonnull @.str.14)
5051
%9 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_5_2_0_0_2_0t(target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) %1, i32 0)
5152
%10 = load i32, ptr addrspace(11) %9, align 4
5253
%11 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_5_2_0_0_2_0t(target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) %2, i32 0)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-vulkan1.3-library %s -o -
2+
; This is to test that all resources, even if they have different descriptor sets, get unique binding numbers
3+
; XFAIL: *
4+
5+
@.str = private unnamed_addr constant [2 x i8] c"b\00", align 1
6+
@.str.2 = private unnamed_addr constant [2 x i8] c"c\00", align 1
7+
8+
define void @main() local_unnamed_addr #0 {
9+
entry:
10+
%0 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
11+
%1 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_5_2_0_0_2_0t(target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) %0, i32 0)
12+
%2 = load i32, ptr addrspace(11) %1, align 4
13+
%3 = tail call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.SignedImage_i32_5_2_0_0_2_0t(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
14+
%4 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_5_2_0_0_2_0t(target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 0) %3, i32 0)
15+
store i32 %2, ptr addrspace(11) %4, align 4
16+
ret void
17+
}
18+
19+
20+
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

0 commit comments

Comments
 (0)