Skip to content

Commit 62f9115

Browse files
authored
[SPIR-V] Add capability for non-uniform indexing for StructuredBuffer types. (llvm#163424)
- Capability `StorageBufferArrayNonUniformIndexing` is required if the non-uniform index accesses "arrays in the StorageBuffer [storage class](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Storage_Class) or BufferBlock-[decorated](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Decoration) arrays." (e.g. `RWStructuredBuffer`, `StructuredBuffer`) - Also fix the wrong unit test name: `StructuredBufferNonUniformIdx.ll` -> `RWBufferNonUniformIdx.ll` Resolves llvm#162889 Addresses llvm#161852
1 parent f7c9618 commit 62f9115

File tree

6 files changed

+67
-8
lines changed

6 files changed

+67
-8
lines changed

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,23 @@ void addOpAccessChainReqs(const MachineInstr &Instr,
12001200
return;
12011201
}
12021202

1203+
bool IsNonUniform =
1204+
hasNonUniformDecoration(Instr.getOperand(0).getReg(), MRI);
1205+
1206+
auto FirstIndexReg = Instr.getOperand(3).getReg();
1207+
bool FirstIndexIsConstant =
1208+
Subtarget.getInstrInfo()->isConstantInstr(*MRI.getVRegDef(FirstIndexReg));
1209+
1210+
if (StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1211+
if (IsNonUniform)
1212+
Handler.addRequirements(
1213+
SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1214+
else if (!FirstIndexIsConstant)
1215+
Handler.addRequirements(
1216+
SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1217+
return;
1218+
}
1219+
12031220
Register PointeeTypeReg = ResTypeInst->getOperand(2).getReg();
12041221
MachineInstr *PointeeType = MRI.getUniqueVRegDef(PointeeTypeReg);
12051222
if (PointeeType->getOpcode() != SPIRV::OpTypeImage &&
@@ -1208,27 +1225,25 @@ void addOpAccessChainReqs(const MachineInstr &Instr,
12081225
return;
12091226
}
12101227

1211-
bool IsNonUniform =
1212-
hasNonUniformDecoration(Instr.getOperand(0).getReg(), MRI);
12131228
if (isUniformTexelBuffer(PointeeType)) {
12141229
if (IsNonUniform)
12151230
Handler.addRequirements(
12161231
SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1217-
else
1232+
else if (!FirstIndexIsConstant)
12181233
Handler.addRequirements(
12191234
SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
12201235
} else if (isInputAttachment(PointeeType)) {
12211236
if (IsNonUniform)
12221237
Handler.addRequirements(
12231238
SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1224-
else
1239+
else if (!FirstIndexIsConstant)
12251240
Handler.addRequirements(
12261241
SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
12271242
} else if (isStorageTexelBuffer(PointeeType)) {
12281243
if (IsNonUniform)
12291244
Handler.addRequirements(
12301245
SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1231-
else
1246+
else if (!FirstIndexIsConstant)
12321247
Handler.addRequirements(
12331248
SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
12341249
} else if (isSampledImage(PointeeType) ||
@@ -1237,14 +1252,14 @@ void addOpAccessChainReqs(const MachineInstr &Instr,
12371252
if (IsNonUniform)
12381253
Handler.addRequirements(
12391254
SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1240-
else
1255+
else if (!FirstIndexIsConstant)
12411256
Handler.addRequirements(
12421257
SPIRV::Capability::SampledImageArrayDynamicIndexing);
12431258
} else if (isStorageImage(PointeeType)) {
12441259
if (IsNonUniform)
12451260
Handler.addRequirements(
12461261
SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1247-
else
1262+
else if (!FirstIndexIsConstant)
12481263
Handler.addRequirements(
12491264
SPIRV::Capability::StorageImageArrayDynamicIndexing);
12501265
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llc -O0 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - | FileCheck %s --match-full-lines
2+
3+
%"__cblayout_$Globals" = type <{ i32 }>
4+
5+
@i = external hidden local_unnamed_addr addrspace(12) global i32, align 4
6+
@ReadWriteBuf.str = private unnamed_addr constant [13 x i8] c"ReadWriteBuf\00", align 1
7+
@"$Globals.cb" = local_unnamed_addr global target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) poison
8+
@"$Globals.str" = private unnamed_addr constant [9 x i8] c"$Globals\00", align 1
9+
10+
; CHECK: OpCapability Shader
11+
; CHECK: OpCapability StorageTexelBufferArrayDynamicIndexingEXT
12+
13+
define void @main() local_unnamed_addr #0 {
14+
entry:
15+
%"$Globals.cb_h.i.i" = tail call target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) @"llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_tspirv.Layout_s___cblayout_$Globalss_4_0t_2_0t"(i32 1, i32 0, i32 1, i32 0, ptr nonnull @"$Globals.str")
16+
store target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) %"$Globals.cb_h.i.i", ptr @"$Globals.cb", align 8
17+
%0 = load i32, ptr addrspace(12) @i, align 4
18+
%1 = tail call target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) @llvm.spv.resource.handlefromimplicitbinding.tspirv.Image_i32_5_2_0_0_2_33t(i32 0, i32 0, i32 64, i32 %0, ptr nonnull @ReadWriteBuf.str)
19+
%2 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_33t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 33) %1, i32 98)
20+
store i32 99, ptr addrspace(11) %2, align 4
21+
ret void
22+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: llc -O0 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - | FileCheck %s --match-full-lines
2+
3+
%"__cblayout_$Globals" = type <{ i32 }>
4+
5+
@i = external hidden local_unnamed_addr addrspace(12) global i32, align 4
6+
@ReadWriteStructuredBuf.str = private unnamed_addr constant [23 x i8] c"ReadWriteStructuredBuf\00", align 1
7+
@"$Globals.cb" = local_unnamed_addr global target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) poison
8+
@"$Globals.str" = private unnamed_addr constant [9 x i8] c"$Globals\00", align 1
9+
10+
; CHECK: OpCapability Shader
11+
; CHECK: OpCapability StorageBufferArrayDynamicIndexing
12+
define void @main() local_unnamed_addr #0 {
13+
entry:
14+
%"$Globals.cb_h.i.i" = tail call target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) @"llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_tspirv.Layout_s___cblayout_$Globalss_4_0t_2_0t"(i32 2, i32 0, i32 1, i32 0, ptr nonnull @"$Globals.str")
15+
store target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 4, 0), 2, 0) %"$Globals.cb_h.i.i", ptr @"$Globals.cb", align 8
16+
%0 = load i32, ptr addrspace(12) @i, align 4
17+
%1 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 0, i32 64, i32 %0, ptr nonnull @ReadWriteStructuredBuf.str)
18+
%2 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, i32 99)
19+
store i32 98, ptr addrspace(11) %2, align 4
20+
ret void
21+
}

llvm/test/CodeGen/SPIRV/hlsl-resources/NonUniformIdx/RWStructuredBufferNonUniformIdx.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
; CHECK-DAG: OpCapability Shader
55
; CHECK-DAG: OpCapability ShaderNonUniformEXT
6+
; CHECK-DAG: OpCapability StorageBufferArrayNonUniformIndexingEXT
67
; CHECK-DAG: OpDecorate {{%[0-9]+}} NonUniformEXT
78
; CHECK-DAG: OpDecorate {{%[0-9]+}} NonUniformEXT
89
; CHECK-DAG: OpDecorate {{%[0-9]+}} NonUniformEXT

llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll renamed to llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageConstIdx.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
@.str.b0 = private unnamed_addr constant [3 x i8] c"B0\00", align 1
55

66
; CHECK-DAG: OpCapability Shader
7-
; CHECK-DAG: OpCapability StorageImageArrayDynamicIndexing
87
; CHECK-DAG: OpCapability Image1D
8+
; CHECK-DAG: OpCapability Int8
99
; CHECK-NOT: OpCapability
1010

1111
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3

0 commit comments

Comments
 (0)