[llvm] d8295e2 - [SPIRV][HLSL] Handle arrays of resources (#111564)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 12:01:06 PDT 2024
Author: Steven Perron
Date: 2024-10-30T15:01:02-04:00
New Revision: d8295e2eeceef37bfd9e0f84918735eff6cfc659
URL: https://github.com/llvm/llvm-project/commit/d8295e2eeceef37bfd9e0f84918735eff6cfc659
DIFF: https://github.com/llvm/llvm-project/commit/d8295e2eeceef37bfd9e0f84918735eff6cfc659.diff
LOG: [SPIRV][HLSL] Handle arrays of resources (#111564)
This commit adds the ability to get a particular resource from an array
of resources using the handle_fromBinding intrinsic.
The main changes are:
1. Create an array when generating the type.
2. Add capabilities from
[SPV_EXT_descriptor_indexing](https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/EXT/SPV_EXT_descriptor_indexing.html).
We are still missing the ability to declare a runtime array. That will
be done in a follow up PR.
Added:
llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/HlslBufferLoad.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferNonUniformIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferDynIdx.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferNonUniformIdx.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Removed:
llvm/test/CodeGen/SPIRV/HlslBufferLoad.ll
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 64fde8bf67ab91..62bd8d1f9d2433 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -713,21 +713,36 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
return Reg;
}
+static std::string GetSpirvImageTypeName(const SPIRVType *Type,
+ MachineIRBuilder &MIRBuilder,
+ const std::string &Prefix);
+
static std::string buildSpirvTypeName(const SPIRVType *Type,
MachineIRBuilder &MIRBuilder) {
switch (Type->getOpcode()) {
+ case SPIRV::OpTypeSampledImage: {
+ return GetSpirvImageTypeName(Type, MIRBuilder, "sampled_image_");
+ }
case SPIRV::OpTypeImage: {
- Register SampledTypeReg = Type->getOperand(1).getReg();
- auto *SampledType = MIRBuilder.getMRI()->getUniqueVRegDef(SampledTypeReg);
- std::string TypeName =
- "image_" + buildSpirvTypeName(SampledType, MIRBuilder);
- for (uint32_t I = 2; I < Type->getNumOperands(); ++I) {
- TypeName = (TypeName + '_' + Twine(Type->getOperand(I).getImm())).str();
- }
- return TypeName;
+ return GetSpirvImageTypeName(Type, MIRBuilder, "image_");
+ }
+ case SPIRV::OpTypeArray: {
+ MachineRegisterInfo *MRI = MIRBuilder.getMRI();
+ Register ElementTypeReg = Type->getOperand(1).getReg();
+ auto *ElementType = MRI->getUniqueVRegDef(ElementTypeReg);
+ const SPIRVType *TypeInst = MRI->getVRegDef(Type->getOperand(2).getReg());
+ assert(TypeInst->getOpcode() != SPIRV::OpConstantI);
+ MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
+ assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
+ uint32_t ArraySize = ImmInst->getOperand(1).getCImm()->getZExtValue();
+ return (buildSpirvTypeName(ElementType, MIRBuilder) + Twine("[") +
+ Twine(ArraySize) + Twine("]"))
+ .str();
}
case SPIRV::OpTypeFloat:
return ("f" + Twine(Type->getOperand(1).getImm())).str();
+ case SPIRV::OpTypeSampler:
+ return ("sampler");
case SPIRV::OpTypeInt:
if (Type->getOperand(2).getImm())
return ("i" + Twine(Type->getOperand(1).getImm())).str();
@@ -737,6 +752,18 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
}
}
+static std::string GetSpirvImageTypeName(const SPIRVType *Type,
+ MachineIRBuilder &MIRBuilder,
+ const std::string &Prefix) {
+ Register SampledTypeReg = Type->getOperand(1).getReg();
+ auto *SampledType = MIRBuilder.getMRI()->getUniqueVRegDef(SampledTypeReg);
+ std::string TypeName = Prefix + buildSpirvTypeName(SampledType, MIRBuilder);
+ for (uint32_t I = 2; I < Type->getNumOperands(); ++I) {
+ TypeName = (TypeName + '_' + Twine(Type->getOperand(I).getImm())).str();
+ }
+ return TypeName;
+}
+
Register SPIRVGlobalRegistry::getOrCreateGlobalVariableWithBinding(
const SPIRVType *VarType, uint32_t Set, uint32_t Binding,
MachineIRBuilder &MIRBuilder) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 11ed7d660be09e..526305d7ed28ab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -260,6 +260,7 @@ class SPIRVInstructionSelector : public InstructionSelector {
SPIRVType *SrcPtrTy) const;
Register buildPointerToResource(const SPIRVType *ResType, uint32_t Set,
uint32_t Binding, uint32_t ArraySize,
+ Register IndexReg, bool IsNonUniform,
MachineIRBuilder MIRBuilder) const;
};
@@ -2616,10 +2617,15 @@ void SPIRVInstructionSelector::selectHandleFromBinding(Register &ResVReg,
uint32_t Set = foldImm(I.getOperand(2), MRI);
uint32_t Binding = foldImm(I.getOperand(3), MRI);
uint32_t ArraySize = foldImm(I.getOperand(4), MRI);
+ Register IndexReg = I.getOperand(5).getReg();
+ bool IsNonUniform = ArraySize > 1 && foldImm(I.getOperand(6), MRI);
MachineIRBuilder MIRBuilder(I);
- Register VarReg =
- buildPointerToResource(ResType, Set, Binding, ArraySize, MIRBuilder);
+ Register VarReg = buildPointerToResource(ResType, Set, Binding, ArraySize,
+ IndexReg, IsNonUniform, MIRBuilder);
+
+ if (IsNonUniform)
+ buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::NonUniformEXT, {});
// TODO: For now we assume the resource is an image, which needs to be
// loaded to get the handle. That will not be true for storage buffers.
@@ -2631,10 +2637,35 @@ void SPIRVInstructionSelector::selectHandleFromBinding(Register &ResVReg,
Register SPIRVInstructionSelector::buildPointerToResource(
const SPIRVType *ResType, uint32_t Set, uint32_t Binding,
- uint32_t ArraySize, MachineIRBuilder MIRBuilder) const {
- assert(ArraySize == 1 && "Resource arrays are not implemented yet.");
- return GR.getOrCreateGlobalVariableWithBinding(ResType, Set, Binding,
- MIRBuilder);
+ uint32_t ArraySize, Register IndexReg, bool IsNonUniform,
+ MachineIRBuilder MIRBuilder) const {
+ if (ArraySize == 1)
+ return GR.getOrCreateGlobalVariableWithBinding(ResType, Set, Binding,
+ MIRBuilder);
+
+ const SPIRVType *VarType = GR.getOrCreateSPIRVArrayType(
+ ResType, ArraySize, *MIRBuilder.getInsertPt(), TII);
+ Register VarReg = GR.getOrCreateGlobalVariableWithBinding(
+ VarType, Set, Binding, MIRBuilder);
+
+ SPIRVType *ResPointerType = GR.getOrCreateSPIRVPointerType(
+ ResType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
+
+ Register AcReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
+ if (IsNonUniform) {
+ // It is unclear which value needs to be marked an non-uniform, so both
+ // the index and the access changed are decorated as non-uniform.
+ buildOpDecorate(IndexReg, MIRBuilder, SPIRV::Decoration::NonUniformEXT, {});
+ buildOpDecorate(AcReg, MIRBuilder, SPIRV::Decoration::NonUniformEXT, {});
+ }
+
+ MIRBuilder.buildInstr(SPIRV::OpAccessChain)
+ .addDef(AcReg)
+ .addUse(GR.getSPIRVTypeID(ResPointerType))
+ .addUse(VarReg)
+ .addUse(IndexReg);
+
+ return AcReg;
}
bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index db5463f5c7abb0..29ce60d9983e38 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -689,11 +689,31 @@ void RequirementHandler::initAvailableCapabilitiesForVulkan(
const SPIRVSubtarget &ST) {
addAvailableCaps({Capability::Shader, Capability::Linkage});
- // Provided by all supported Vulkan versions.
+ // Core in Vulkan 1.1 and earlier.
addAvailableCaps({Capability::Int16, Capability::Int64, Capability::Float16,
Capability::Float64, Capability::GroupNonUniform,
Capability::Image1D, Capability::SampledBuffer,
- Capability::ImageBuffer});
+ Capability::ImageBuffer,
+ Capability::UniformBufferArrayDynamicIndexing,
+ Capability::SampledImageArrayDynamicIndexing,
+ Capability::StorageBufferArrayDynamicIndexing,
+ Capability::StorageImageArrayDynamicIndexing});
+
+ // Became core in Vulkan 1.2
+ if (ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
+ addAvailableCaps(
+ {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
+ Capability::InputAttachmentArrayDynamicIndexingEXT,
+ Capability::UniformTexelBufferArrayDynamicIndexingEXT,
+ Capability::StorageTexelBufferArrayDynamicIndexingEXT,
+ Capability::UniformBufferArrayNonUniformIndexingEXT,
+ Capability::SampledImageArrayNonUniformIndexingEXT,
+ Capability::StorageBufferArrayNonUniformIndexingEXT,
+ Capability::StorageImageArrayNonUniformIndexingEXT,
+ Capability::InputAttachmentArrayNonUniformIndexingEXT,
+ Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
+ Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
+ }
}
} // namespace SPIRV
@@ -729,6 +749,8 @@ static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
Reqs.addExtension(
SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
+ } else if (Dec == SPIRV::Decoration::NonUniformEXT) {
+ Reqs.addRequirements(SPIRV::Capability::ShaderNonUniformEXT);
}
}
@@ -848,6 +870,136 @@ static void AddAtomicFloatRequirements(const MachineInstr &MI,
}
}
+bool isUniformTexelBuffer(MachineInstr *ImageInst) {
+ if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
+ return false;
+ uint32_t Dim = ImageInst->getOperand(2).getImm();
+ uint32_t Sampled = ImageInst->getOperand(6).getImm();
+ return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
+}
+
+bool isStorageTexelBuffer(MachineInstr *ImageInst) {
+ if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
+ return false;
+ uint32_t Dim = ImageInst->getOperand(2).getImm();
+ uint32_t Sampled = ImageInst->getOperand(6).getImm();
+ return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
+}
+
+bool isSampledImage(MachineInstr *ImageInst) {
+ if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
+ return false;
+ uint32_t Dim = ImageInst->getOperand(2).getImm();
+ uint32_t Sampled = ImageInst->getOperand(6).getImm();
+ return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
+}
+
+bool isInputAttachment(MachineInstr *ImageInst) {
+ if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
+ return false;
+ uint32_t Dim = ImageInst->getOperand(2).getImm();
+ uint32_t Sampled = ImageInst->getOperand(6).getImm();
+ return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
+}
+
+bool isStorageImage(MachineInstr *ImageInst) {
+ if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
+ return false;
+ uint32_t Dim = ImageInst->getOperand(2).getImm();
+ uint32_t Sampled = ImageInst->getOperand(6).getImm();
+ return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
+}
+
+bool isCombinedImageSampler(MachineInstr *SampledImageInst) {
+ if (SampledImageInst->getOpcode() != SPIRV::OpTypeSampledImage)
+ return false;
+
+ const MachineRegisterInfo &MRI = SampledImageInst->getMF()->getRegInfo();
+ Register ImageReg = SampledImageInst->getOperand(1).getReg();
+ auto *ImageInst = MRI.getUniqueVRegDef(ImageReg);
+ return isSampledImage(ImageInst);
+}
+
+bool hasNonUniformDecoration(Register Reg, const MachineRegisterInfo &MRI) {
+ for (const auto &MI : MRI.reg_instructions(Reg)) {
+ if (MI.getOpcode() != SPIRV::OpDecorate)
+ continue;
+
+ uint32_t Dec = MI.getOperand(1).getImm();
+ if (Dec == SPIRV::Decoration::NonUniformEXT)
+ return true;
+ }
+ return false;
+}
+
+void addOpAccessChainReqs(const MachineInstr &Instr,
+ SPIRV::RequirementHandler &Handler,
+ const SPIRVSubtarget &Subtarget) {
+ const MachineRegisterInfo &MRI = Instr.getMF()->getRegInfo();
+ // Get the result type. If it is an image type, then the shader uses
+ // descriptor indexing. The appropriate capabilities will be added based
+ // on the specifics of the image.
+ Register ResTypeReg = Instr.getOperand(1).getReg();
+ MachineInstr *ResTypeInst = MRI.getUniqueVRegDef(ResTypeReg);
+
+ assert(ResTypeInst->getOpcode() == SPIRV::OpTypePointer);
+ uint32_t StorageClass = ResTypeInst->getOperand(1).getImm();
+ if (StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
+ StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
+ StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
+ return;
+ }
+
+ Register PointeeTypeReg = ResTypeInst->getOperand(2).getReg();
+ MachineInstr *PointeeType = MRI.getUniqueVRegDef(PointeeTypeReg);
+ if (PointeeType->getOpcode() != SPIRV::OpTypeImage &&
+ PointeeType->getOpcode() != SPIRV::OpTypeSampledImage &&
+ PointeeType->getOpcode() != SPIRV::OpTypeSampler) {
+ return;
+ }
+
+ bool IsNonUniform =
+ hasNonUniformDecoration(Instr.getOperand(0).getReg(), MRI);
+ if (isUniformTexelBuffer(PointeeType)) {
+ if (IsNonUniform)
+ Handler.addRequirements(
+ SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
+ else
+ Handler.addRequirements(
+ SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
+ } else if (isInputAttachment(PointeeType)) {
+ if (IsNonUniform)
+ Handler.addRequirements(
+ SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
+ else
+ Handler.addRequirements(
+ SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
+ } else if (isStorageTexelBuffer(PointeeType)) {
+ if (IsNonUniform)
+ Handler.addRequirements(
+ SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
+ else
+ Handler.addRequirements(
+ SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
+ } else if (isSampledImage(PointeeType) ||
+ isCombinedImageSampler(PointeeType) ||
+ PointeeType->getOpcode() == SPIRV::OpTypeSampler) {
+ if (IsNonUniform)
+ Handler.addRequirements(
+ SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
+ else
+ Handler.addRequirements(
+ SPIRV::Capability::SampledImageArrayDynamicIndexing);
+ } else if (isStorageImage(PointeeType)) {
+ if (IsNonUniform)
+ Handler.addRequirements(
+ SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
+ else
+ Handler.addRequirements(
+ SPIRV::Capability::StorageImageArrayDynamicIndexing);
+ }
+}
+
void addInstrRequirements(const MachineInstr &MI,
SPIRV::RequirementHandler &Reqs,
const SPIRVSubtarget &ST) {
@@ -967,11 +1119,17 @@ void addInstrRequirements(const MachineInstr &MI,
case SPIRV::OpConstantSampler:
Reqs.addCapability(SPIRV::Capability::LiteralSampler);
break;
+ case SPIRV::OpInBoundsAccessChain:
+ case SPIRV::OpAccessChain:
+ addOpAccessChainReqs(MI, Reqs, ST);
+ break;
case SPIRV::OpTypeImage:
addOpTypeImageReqs(MI, Reqs, ST);
break;
case SPIRV::OpTypeSampler:
- Reqs.addCapability(SPIRV::Capability::ImageBasic);
+ if (!ST.isVulkanEnv()) {
+ Reqs.addCapability(SPIRV::Capability::ImageBasic);
+ }
break;
case SPIRV::OpTypeForwardPointer:
// TODO: check if it's OpenCL's kernel.
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index 13ad1eb8e8b337..d63438baca7e76 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -355,7 +355,9 @@ defm GeometryPointSize : CapabilityOperand<24, 0, 0, [], [Geometry]>;
defm ImageGatherExtended : CapabilityOperand<25, 0, 0, [], [Shader]>;
defm StorageImageMultisample : CapabilityOperand<27, 0, 0, [], [Shader]>;
defm UniformBufferArrayDynamicIndexing : CapabilityOperand<28, 0, 0, [], [Shader]>;
-defm SampledImageArrayDymnamicIndexing : CapabilityOperand<29, 0, 0, [], [Shader]>;
+defm SampledImageArrayDynamicIndexing : CapabilityOperand<29, 0, 0, [], [Shader]>;
+defm StorageBufferArrayDynamicIndexing : CapabilityOperand<30, 0, 0, [], [Shader]>;
+defm StorageImageArrayDynamicIndexing : CapabilityOperand<31, 0, 0, [], [Shader]>;
defm ClipDistance : CapabilityOperand<32, 0, 0, [], [Shader]>;
defm CullDistance : CapabilityOperand<33, 0, 0, [], [Shader]>;
defm SampleRateShading : CapabilityOperand<35, 0, 0, [], [Shader]>;
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageDynIdx.ll
new file mode 100644
index 00000000000000..d5e95c7824144f
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageDynIdx.ll
@@ -0,0 +1,41 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability SampledImageArrayDynamicIndexing
+; CHECK-NEXT: OpCapability Sampled1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[CombindedType:%[0-9]+]] = OpTypeSampledImage [[BufferType]]
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[CombindedType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[CombindedType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[CombindedType]] [[ac]]
+ %buffer0 = call target("spirv.SampledImage", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[CombindedType]] [[ac]]
+ %buffer1 = call target("spirv.SampledImage", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageNonUniformIdx.ll
new file mode 100644
index 00000000000000..68bf3478fa9af0
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/CombinedSamplerImageNonUniformIdx.ll
@@ -0,0 +1,48 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK: OpCapability ShaderNonUniform
+; CHECK-NEXT: OpCapability SampledImageArrayNonUniformIndexing
+; CHECK-NEXT: OpCapability Sampled1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[CombindedType:%[0-9]+]] = OpTypeSampledImage [[BufferType]]
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[CombindedType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[CombindedType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0:%[0-9]+]] = OpLoad [[CombindedType]] [[ac0]]
+ %buffer0 = call target("spirv.SampledImage", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[CombindedType]] [[ac1]]
+ %buffer1 = call target("spirv.SampledImage", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/HlslBufferLoad.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/HlslBufferLoad.ll
similarity index 100%
rename from llvm/test/CodeGen/SPIRV/HlslBufferLoad.ll
rename to llvm/test/CodeGen/SPIRV/hlsl-resources/HlslBufferLoad.ll
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageDynIdx.ll
new file mode 100644
index 00000000000000..39fdc866af7ff2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageDynIdx.ll
@@ -0,0 +1,40 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability InputAttachmentArrayDynamicIndexing
+; SCHECK-NEXT: OpCapability InputAttachment
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] SubpassData 2 0 0 2 Unknown {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 6, 2, 0, 0, 2, 0)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_6_2_0_0_2_0(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 6, 2, 0, 0, 2, 0)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_6_2_0_0_2_0(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageNonUniformIdx.ll
new file mode 100644
index 00000000000000..b05b7eb885b426
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/InputAttachmentImageNonUniformIdx.ll
@@ -0,0 +1,47 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability ShaderNonUniformEXT
+; CHECK-NEXT: OpCapability InputAttachmentArrayNonUniformIndexing
+; SCHECK-NEXT: OpCapability InputAttachment
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] SubpassData 2 0 0 2 Unknown {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[BufferType]] [[ac0]]
+ %buffer0 = call target("spirv.Image", i32, 6, 2, 0, 0, 2, 0)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_6_2_0_0_2_0(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[BufferType]] [[ac1]]
+ %buffer1 = call target("spirv.Image", i32, 6, 2, 0, 0, 2, 0)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_6_2_0_0_2_0(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageDynIdx.ll
new file mode 100644
index 00000000000000..0c47eeb606e802
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageDynIdx.ll
@@ -0,0 +1,66 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability SampledImageArrayDynamicIndexing
+; CHECK-NEXT: OpCapability Sampled1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK-DAG: OpDecorate [[OtherVar:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[OtherVar]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK-DAG: [[OtherArraySize:%[0-9]+]] = OpConstant [[int]] 5
+; CHECK-DAG: [[OtherBufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[OtherArraySize]]
+; CHECK-DAG: [[OtherArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[OtherBufferArrayType]]
+; CHECK-DAG: [[OtherVar]] = OpVariable [[OtherArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @DifferentArraySizesAreDifferentVariables() #0 {
+; Make sure we use
diff erent variables when the array sizes are
diff erent
+; same in case one function calls the other.
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[OtherVar]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 5, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageNonUniformIdx.ll
new file mode 100644
index 00000000000000..ec94a8eeac2e42
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampledImageNonUniformIdx.ll
@@ -0,0 +1,47 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability ShaderNonUniformEXT
+; CHECK-NEXT: OpCapability SampledImageArrayNonUniformIndexing
+; CHECK-NEXT: OpCapability Sampled1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[BufferType]] [[ac0]]
+ %buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[BufferType]] [[ac1]]
+ %buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayDynIdx.ll
new file mode 100644
index 00000000000000..9371a792f84b2a
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayDynIdx.ll
@@ -0,0 +1,39 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability SampledImageArrayDynamicIndexing
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[SamplerType:%[0-9]+]] = OpTypeSampler
+; CHECK-DAG: [[SamplerPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[SamplerType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[SamplerArrayType:%[0-9]+]] = OpTypeArray [[SamplerType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[SamplerArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[SamplerPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[SamplerType]] [[ac]]
+ %buffer0 = call target("spirv.Sampler")
+ @llvm.spv.handle.fromBinding.tspirv.Image(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[SamplerPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[SamplerType]] [[ac]]
+ %buffer1 = call target("spirv.Sampler")
+ @llvm.spv.handle.fromBinding.tspirv.Image(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayNonUniformIdx.ll
new file mode 100644
index 00000000000000..151c4aa6d4365c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SamplerArrayNonUniformIdx.ll
@@ -0,0 +1,46 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: ShaderNonUniform
+; CHECK-NEXT: OpCapability SampledImageArrayNonUniformIndexing
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[SamplerType:%[0-9]+]] = OpTypeSampler
+; CHECK-DAG: [[SamplerPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[SamplerType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[SamplerArrayType:%[0-9]+]] = OpTypeArray [[SamplerType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[SamplerArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[SamplerPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[SamplerType]] [[ac0]]
+ %buffer0 = call target("spirv.Sampler")
+ @llvm.spv.handle.fromBinding.tspirv.Image(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[SamplerPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[SamplerType]] [[ac1]]
+ %buffer1 = call target("spirv.Sampler")
+ @llvm.spv.handle.fromBinding.tspirv.Image(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
new file mode 100644
index 00000000000000..908a81777a04a0
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
@@ -0,0 +1,40 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK-NEXT: OpCapability StorageImageArrayDynamicIndexing
+; CHECK-NEXT: OpCapability Image1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 2 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
new file mode 100644
index 00000000000000..4a582b31d60f1d
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
@@ -0,0 +1,47 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; CHECK: OpCapability ShaderNonUniformEXT
+; CHECK-NEXT: OpCapability StorageImageArrayNonUniformIndexing
+; CHECK-NEXT: OpCapability Image1D
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 2 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[BufferType]] [[ac0]]
+ %buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[BufferType]] [[ac1]]
+ %buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_0_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferDynIdx.ll
new file mode 100644
index 00000000000000..d144dcf505fa18
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferDynIdx.ll
@@ -0,0 +1,40 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; SCHECK-NEXT: OpCapability ImageBuffer
+; CHECK-NEXT: OpCapability StorageTexelBufferArrayDynamicIndexing
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] Buffer 2 0 0 2 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @void() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 5, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 5, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferNonUniformIdx.ll
new file mode 100644
index 00000000000000..2f96eda4518f06
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageTexelBufferNonUniformIdx.ll
@@ -0,0 +1,47 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; SCHECK-NEXT: OpCapability ImageBuffer
+; CHECK-NEXT: OpCapability ShaderNonUniformEXT
+; CHECK-NEXT: OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] Buffer 2 0 0 2 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[BufferType]] [[ac0]]
+ %buffer0 = call target("spirv.Image", i32, 5, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[BufferType]] [[ac1]]
+ %buffer1 = call target("spirv.Image", i32, 5, 2, 0, 0, 2, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_2_24(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferDynIdx.ll
new file mode 100644
index 00000000000000..117363241bd966
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferDynIdx.ll
@@ -0,0 +1,40 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; SCHECK-NEXT: OpCapability SampledBuffer
+; CHECK-NEXT: OpCapability UniformTexelBufferArrayDynamicIndexing
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] Buffer 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer0 = call target("spirv.Image", i32, 5, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 false)
+
+; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
+ %buffer1 = call target("spirv.Image", i32, 5, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 false)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferNonUniformIdx.ll
new file mode 100644
index 00000000000000..cec16a8e7c8b47
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/UniformTexelBufferNonUniformIdx.ll
@@ -0,0 +1,47 @@
+; TODO(pull/110270): verifier, fix G_BITCAST error "bitcast must change type"
+; RUN: llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Shader
+; SCHECK-NEXT: OpCapability SampledBuffer
+; CHECK-NEXT: OpCapability ShaderNonUniformEXT
+; CHECK-NEXT: OpCapability UniformTexelBufferArrayNonUniformIndexing
+; CHECK-NOT: OpCapability
+
+; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
+; CHECK-DAG: OpDecorate [[Var]] Binding 4
+; CHECK: OpDecorate [[Zero:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld0:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[One:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ac1:%[0-9]+]] NonUniform
+; CHECK: OpDecorate [[ld1:%[0-9]+]] NonUniform
+
+; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] Buffer 2 0 0 1 R32i {{$}}
+; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
+; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
+; CHECK-DAG: [[One]] = OpConstant [[int]] 1
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
+; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
+; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
+
+; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
+; CHECK-NEXT: OpLabel
+define void @main() #0 {
+; CHECK: [[ac0]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
+; CHECK: [[ld0]] = OpLoad [[BufferType]] [[ac0]]
+ %buffer0 = call target("spirv.Image", i32, 5, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 0, i1 true)
+
+; CHECK: [[ac1:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
+; CHECK: [[ld1]] = OpLoad [[BufferType]] [[ac1]]
+ %buffer1 = call target("spirv.Image", i32, 5, 2, 0, 0, 1, 24)
+ @llvm.spv.handle.fromBinding.tspirv.Image_f32_5_2_0_0_1_24(
+ i32 3, i32 4, i32 3, i32 1, i1 true)
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
More information about the llvm-commits
mailing list