[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