[llvm] 2c4c9d8 - [SPIRV] Fix inconsistent operand order for counter resource intrinsic (#221646)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 17:48:10 PDT 2026
Author: Helena Kotas
Date: 2026-09-09T17:48:04-07:00
New Revision: 2c4c9d84bd948a92bb78b46a1c34044e246fd187
URL: https://github.com/llvm/llvm-project/commit/2c4c9d84bd948a92bb78b46a1c34044e246fd187
DIFF: https://github.com/llvm/llvm-project/commit/2c4c9d84bd948a92bb78b46a1c34044e246fd187.diff
LOG: [SPIRV] Fix inconsistent operand order for counter resource intrinsic (#221646)
The `llvm.spv.resource.handlefrombinding` intrinsic stores its binding
operands in the order (DescriptorSet, BindingNo, ...). The
`llvm.spv.resource.counterhandlefrombinding` intrinsic should use the
same order.
The `llvm.spv.resource.counterhandlefrombinding` intrinsic is currently
emitted only by the `SPIRVLegalizeImplicitBinding` pass. The pass
previously built its operands in the wrong order, and the instruction
selector repeated the same inversion when emitting decorations.
This change makes the operand order consistent with
`llvm.spv.resource.handlefrombinding`.
Test update closes a coverage gap - there were no tests for explicit
`llvm.spv.resource.counterhandlefrombinding` calls.
Assisted by GPT-5.6 Sol.
Added:
Modified:
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp
llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 35242809b76b1..41e4dc290c099 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -5872,8 +5872,8 @@ bool SPIRVInstructionSelector::selectCounterHandleFromBinding(
assert(MainHandleDef->getIntrinsicID() ==
Intrinsic::spv_resource_handlefrombinding);
- uint32_t Set = getIConstVal(Intr.getOperand(4).getReg(), MRI);
- uint32_t Binding = getIConstVal(Intr.getOperand(3).getReg(), MRI);
+ uint32_t Set = getIConstVal(Intr.getOperand(3).getReg(), MRI);
+ uint32_t Binding = getIConstVal(Intr.getOperand(4).getReg(), MRI);
uint32_t ArraySize = getIConstVal(MainHandleDef->getOperand(4).getReg(), MRI);
Register IndexReg = MainHandleDef->getOperand(5).getReg();
std::string CounterName =
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp
index 4009b2872d624..738ba182bd273 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp
@@ -93,9 +93,9 @@ struct BindingInfoCollector : public InstVisitor<BindingInfoCollector> {
} else if (CI.getIntrinsicID() ==
Intrinsic::spv_resource_counterhandlefrombinding) {
const uint32_t DescSet =
- cast<ConstantInt>(CI.getArgOperand(2))->getZExtValue();
- const uint32_t Binding =
cast<ConstantInt>(CI.getArgOperand(1))->getZExtValue();
+ const uint32_t Binding =
+ cast<ConstantInt>(CI.getArgOperand(2))->getZExtValue();
addBinding(DescSet, Binding);
} else if (CI.getIntrinsicID() ==
Intrinsic::spv_resource_counterhandlefromimplicitbinding) {
@@ -122,12 +122,14 @@ static uint32_t getOrderId(const CallInst *CI) {
static uint32_t getDescSet(const CallInst *CI) {
uint32_t DescSetArgIdx;
switch (CI->getIntrinsicID()) {
- case Intrinsic::spv_resource_handlefromimplicitbinding:
case Intrinsic::spv_resource_handlefrombinding:
+ DescSetArgIdx = 0;
+ break;
+ case Intrinsic::spv_resource_handlefromimplicitbinding:
+ case Intrinsic::spv_resource_counterhandlefrombinding:
DescSetArgIdx = 1;
break;
case Intrinsic::spv_resource_counterhandlefromimplicitbinding:
- case Intrinsic::spv_resource_counterhandlefrombinding:
DescSetArgIdx = 2;
break;
default:
@@ -269,8 +271,8 @@ void SPIRVLegalizeImplicitBindingImpl::replaceCounterHandleCall(
SmallVector<Value *, 8> Args;
Args.push_back(OldCI->getArgOperand(0));
- Args.push_back(Builder.getInt32(NewBinding));
Args.push_back(Builder.getInt32(DescSet));
+ Args.push_back(Builder.getInt32(NewBinding));
Type *Tys[] = {OldCI->getType(), OldCI->getArgOperand(0)->getType()};
Function *NewFunc = Intrinsic::getOrInsertDeclaration(
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll
index 2964da9058104..07c803dcdcd01 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/ImplicitBinding.ll
@@ -9,6 +9,8 @@
@.str.10 = private unnamed_addr constant [2 x i8] c"g\00", align 1
@.str.12 = private unnamed_addr constant [2 x i8] c"h\00", align 1
@.str.14 = private unnamed_addr constant [2 x i8] c"i\00", align 1
+ at .str.15 = private unnamed_addr constant [2 x i8] c"j\00", align 1
+ at .str.16 = private unnamed_addr constant [2 x i8] c"k\00", align 1
; CHECK-DAG: OpName [[b:%[0-9]+]] "b"
; CHECK-DAG: OpName [[c:%[0-9]+]] "c"
@@ -18,6 +20,10 @@
; CHECK-DAG: OpName [[g:%[0-9]+]] "g"
; CHECK-DAG: OpName [[h:%[0-9]+]] "h"
; CHECK-DAG: OpName [[i:%[0-9]+]] "i"
+; CHECK-DAG: OpName [[j:%[0-9]+]] "j"
+; CHECK-DAG: OpName [[j_counter:%[0-9]+]] "j.counter"
+; CHECK-DAG: OpName [[k:%[0-9]+]] "k"
+; CHECK-DAG: OpName [[k_counter:%[0-9]+]] "k.counter"
; CHECK-DAG: OpDecorate [[b]] DescriptorSet 0
; CHECK-DAG: OpDecorate [[b]] Binding 1
; CHECK-DAG: OpDecorate [[c]] DescriptorSet 0
@@ -35,7 +41,14 @@
; CHECK-NOT: OpDecorate [[h]] Binding 4
; CHECK-DAG: OpDecorate [[i]] DescriptorSet 10
; CHECK-DAG: OpDecorate [[i]] Binding 2
-
+; CHECK-DAG: OpDecorate [[j]] DescriptorSet 0
+; CHECK-DAG: OpDecorate [[j]] Binding 4
+; CHECK-DAG: OpDecorate [[j_counter]] DescriptorSet 0
+; CHECK-DAG: OpDecorate [[j_counter]] Binding 6
+; CHECK-DAG: OpDecorate [[k]] DescriptorSet 0
+; CHECK-DAG: OpDecorate [[k]] Binding 5
+; CHECK-DAG: OpDecorate [[k_counter]] DescriptorSet 0
+; CHECK-DAG: OpDecorate [[k_counter]] Binding 7
define void @main() local_unnamed_addr #0 {
entry:
@@ -72,9 +85,23 @@ entry:
%24 = load i32, ptr addrspace(11) %23, align 4
%add14.i = add nsw i32 %add12.i, %24
%25 = 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)
- store i32 %add14.i, ptr addrspace(11) %25, align 4
+
+ %handle1 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 4, i32 0, i32 1, i32 0, ptr nonnull @.str.15)
+ %counter_handle1 = call target("spirv.VulkanBuffer", i32, 12, 1) @llvm.spv.resource.counterhandlefrombinding.tspirv.VulkanBuffer_i32_12_1t.tspirv.VulkanBuffer_a0f32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %handle1, i32 0, i32 6)
+ %counter1 = tail call noundef i32 @llvm.spv.resource.updatecounter.tspirv.VulkanBuffer_i32_12_1t(target("spirv.VulkanBuffer", i32, 12, 1) %counter_handle1, i8 1)
+ %ptr1 = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %handle1, i32 0)
+ %value1 = load i32, ptr addrspace(11) %ptr1, align 4
+ %add15.i = add nsw i32 %add14.i, %value1
+
+ %handle2 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 5, i32 0, i32 1, i32 0, ptr nonnull @.str.16)
+ %counter_handle2 = call target("spirv.VulkanBuffer", i32, 12, 1) @llvm.spv.resource.counterhandlefromimplicitbinding.tspirv.VulkanBuffer_i32_12_1t.tspirv.VulkanBuffer_a0f32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %handle2, i32 6, i32 0)
+ %counter2 = tail call noundef i32 @llvm.spv.resource.updatecounter.tspirv.VulkanBuffer_i32_12_1t(target("spirv.VulkanBuffer", i32, 12, 1) %counter_handle2, i8 1)
+ %ptr2 = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %handle2, i32 0)
+ %value2 = load i32, ptr addrspace(11) %ptr2, align 4
+ %add16.i = add nsw i32 %add15.i, %value2
+
+ store i32 %add16.i, ptr addrspace(11) %25, align 4
ret void
}
-
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
More information about the llvm-commits
mailing list