[clang] [llvm] [HLSL] Implement Texture2DArray for HLSL (PR #203951)

Tim Corringham via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 23 09:10:54 PDT 2026


https://github.com/tcorringham updated https://github.com/llvm/llvm-project/pull/203951

>From 60b9bb043e0c8589996d980a28cab09231826521 Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Mon, 15 Jun 2026 17:42:45 +0100
Subject: [PATCH 1/6] [HLSL] Implement Texture2DArray for HLSL

Add support for the Texture2DArray type, builtin argument checking,
codegen, and associated tests.
This change implements the parts of #194910 which could not be tested
without a HLSL texture array type.

Assisted by Cursor

Fixes #194944
---
 clang/lib/CodeGen/Targets/DirectX.cpp         |   7 +-
 clang/lib/CodeGen/Targets/SPIR.cpp            |   2 +-
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 202 ++--
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h   |  39 +-
 clang/lib/Sema/HLSLExternalSemaSource.cpp     |  47 +-
 clang/lib/Sema/SemaHLSL.cpp                   |  24 +-
 .../AST/HLSL/Texture2DArray-scalar-AST.hlsl   | 931 ++++++++++++++++++
 .../HLSL/Texture2DArray-shorthand-AST.hlsl    |  39 +
 .../AST/HLSL/Texture2DArray-vector-AST.hlsl   | 931 ++++++++++++++++++
 ...Texture2DArray-CalculateLevelOfDetail.hlsl |  44 +
 .../resources/Texture2DArray-Gather.hlsl      | 183 ++++
 .../Texture2DArray-GetDimensions.hlsl         | 103 ++
 .../resources/Texture2DArray-Load.hlsl        | 236 +++++
 .../resources/Texture2DArray-Mips.hlsl        |  67 ++
 .../resources/Texture2DArray-Sample.hlsl      |  90 ++
 .../resources/Texture2DArray-SampleBias.hlsl  |  66 ++
 .../resources/Texture2DArray-SampleCmp.hlsl   |  78 ++
 .../Texture2DArray-SampleCmpLevelZero.hlsl    |  48 +
 .../resources/Texture2DArray-SampleGrad.hlsl  | 108 ++
 .../resources/Texture2DArray-SampleLevel.hlsl |  68 ++
 .../resources/Texture2DArray-Subscript.hlsl   |  74 ++
 ...xture2DArray-default-explicit-binding.hlsl |  26 +
 .../resources/Texture2DArray-default.hlsl     |  16 +
 .../Texture2DArray-shorthand-contexts.hlsl    |  31 +
 ...Texture2DArray-CalculateLevelOfDetail.hlsl |  33 +
 .../Texture2DArray-GetDimensions.hlsl         |  80 ++
 .../Resources/Texture2DArray-SampleBias.hlsl  |  33 +
 .../Resources/Texture2DArray-SampleCmp.hlsl   |  47 +
 .../Texture2DArray-SampleCmpLevelZero.hlsl    |  36 +
 .../Resources/Texture2DArray-SampleGrad.hlsl  |  34 +
 .../Resources/Texture2DArray-SampleLevel.hlsl |  28 +
 .../Resources/Texture2DArray-Sema.hlsl        |  43 +
 .../Resources/Texture2DArray-Subscript.hlsl   |  28 +
 .../test/SemaHLSL/Texture2DArray-Gather.hlsl  |  50 +
 .../Texture2DArray-GatherCmp-Vulkan.hlsl      |  23 +
 .../SemaHLSL/Texture2DArray-Load-errors.hlsl  |  44 +
 .../SemaHLSL/Texture2DArray-mips-errors.hlsl  |  33 +
 .../DirectX/Texture2DArray-SampleBias.ll      | 109 ++
 .../DirectX/Texture2DArray-SampleGrad.ll      |  81 ++
 .../DirectX/Texture2DArray-annotateHandle.ll  |  37 +
 .../SPIRV/hlsl-resources/Gather2DArray.ll     |  44 +
 .../SPIRV/hlsl-resources/LoadLevel2DArray.ll  |  41 +
 .../SPIRV/hlsl-resources/Sample2DArray.ll     |  68 ++
 .../SPIRV/hlsl-resources/SampleGrad2DArray.ll |  53 +
 44 files changed, 4277 insertions(+), 128 deletions(-)
 create mode 100644 clang/test/AST/HLSL/Texture2DArray-scalar-AST.hlsl
 create mode 100644 clang/test/AST/HLSL/Texture2DArray-shorthand-AST.hlsl
 create mode 100644 clang/test/AST/HLSL/Texture2DArray-vector-AST.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-CalculateLevelOfDetail.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-Gather.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-Load.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-Mips.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-Sample.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-SampleBias.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmp.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmpLevelZero.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-SampleGrad.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-SampleLevel.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-Subscript.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-default-explicit-binding.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-default.hlsl
 create mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-shorthand-contexts.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-CalculateLevelOfDetail.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-GetDimensions.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-SampleBias.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmp.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmpLevelZero.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-SampleGrad.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-SampleLevel.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-Sema.hlsl
 create mode 100644 clang/test/SemaHLSL/Resources/Texture2DArray-Subscript.hlsl
 create mode 100644 clang/test/SemaHLSL/Texture2DArray-Gather.hlsl
 create mode 100644 clang/test/SemaHLSL/Texture2DArray-GatherCmp-Vulkan.hlsl
 create mode 100644 clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
 create mode 100644 clang/test/SemaHLSL/Texture2DArray-mips-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
 create mode 100644 llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
 create mode 100644 llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-resources/LoadLevel2DArray.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-resources/Sample2DArray.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-resources/SampleGrad2DArray.ll

diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index e5b01c21e9e2f..f483a7b867016 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -97,7 +97,10 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
         RK = llvm::dxil::ResourceKind::Texture1D;
         break;
       case llvm::dxil::ResourceDimension::Dim2D:
-        RK = llvm::dxil::ResourceKind::Texture2D;
+        if (ResAttrs.IsArray)
+          RK = llvm::dxil::ResourceKind::Texture2DArray;
+        else
+          RK = llvm::dxil::ResourceKind::Texture2D;
         break;
       case llvm::dxil::ResourceDimension::Dim3D:
         RK = llvm::dxil::ResourceKind::Texture3D;
@@ -106,7 +109,7 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
         RK = llvm::dxil::ResourceKind::TextureCube;
         break;
       default:
-        llvm_unreachable("Unsupported resource dimension for textur.");
+        llvm_unreachable("Unsupported resource dimension for texture.");
       }
       Ints.push_back(static_cast<unsigned>(RK));
     }
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index 0a96d612c8a87..88e7c7f9482a4 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -922,7 +922,7 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource(
   IntParams[1] = 2;
 
   // Arrayed
-  IntParams[2] = 0;
+  IntParams[2] = static_cast<unsigned>(attributes.IsArray);
 
   // MS
   IntParams[3] = 0;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 40e4f4024d6da..f8018729b4644 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1038,8 +1038,8 @@ BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass RC, bool IsROV,
                                          bool RawBuffer, bool HasCounter,
                                          AccessSpecifier Access) {
   QualType ElementTy = getHandleElementType();
-  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, ElementTy,
-                  Access);
+  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer,
+                  /*IsArray=*/false, ElementTy, Access);
   if (HasCounter)
     addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
   return *this;
@@ -1047,16 +1047,17 @@ BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass RC, bool IsROV,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addTextureHandle(ResourceClass RC, bool IsROV,
-                                         ResourceDimension RD,
+                                         bool IsArray, ResourceDimension RD,
                                          AccessSpecifier Access) {
-  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, getHandleElementType(),
-                  Access);
+  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, IsArray,
+                  getHandleElementType(), Access);
   return *this;
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addSamplerHandle() {
   addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
-                  /*IsROV=*/false, /*RawBuffer=*/false, getHandleElementType());
+                  /*IsROV=*/false, /*RawBuffer=*/false, /*IsArray=*/false,
+                  getHandleElementType());
   return *this;
 }
 
@@ -1111,22 +1112,22 @@ CXXRecordDecl *BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
     ResourceClass RC, ResourceDimension RD, bool IsROV, bool RawBuffer,
-    QualType ElementTy, AccessSpecifier Access) {
+    bool IsArray, QualType ElementTy, AccessSpecifier Access) {
   return addResourceMember("__handle", RC, RD, IsROV, RawBuffer,
-                           /*IsCounter=*/false, ElementTy, Access);
+                           /*IsCounter=*/false, IsArray, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember(
     ResourceClass RC, bool IsROV, bool RawBuffer, QualType ElementTy,
     AccessSpecifier Access) {
   return addResourceMember("__counter_handle", RC, ResourceDimension::Unknown,
-                           IsROV, RawBuffer,
-                           /*IsCounter=*/true, ElementTy, Access);
+                           IsROV, RawBuffer, /*IsCounter=*/true,
+                           /*IsArray=*/false, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
     StringRef MemberName, ResourceClass RC, ResourceDimension RD, bool IsROV,
-    bool RawBuffer, bool IsCounter, QualType ElementTy,
+    bool RawBuffer, bool IsCounter, bool IsArray, QualType ElementTy,
     AccessSpecifier Access) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
 
@@ -1151,6 +1152,8 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
           : nullptr};
   if (IsCounter)
     Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
+  if (IsArray)
+    Attrs.push_back(HLSLIsArrayAttr::CreateImplicit(Ctx));
 
   if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
                                        AttributedResTy))
@@ -1405,13 +1408,14 @@ BuiltinTypeDeclBuilder::addCopyAssignmentOperator(AccessSpecifier Access) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim,
+                                                   bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
 
   uint32_t VecSize = 1;
   if (Dim != ResourceDimension::Unknown)
-    VecSize = getResourceDimensions(Dim);
+    VecSize = getResourceDimensions(Dim) + (IsArray ? 1 : 0);
 
   QualType IndexTy = VecSize > 1
                          ? AST.getExtVectorType(AST.UnsignedIntTy, VecSize)
@@ -1446,7 +1450,8 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
 CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
                                                         QualType ReturnType) {
   ASTContext &AST = Record->getASTContext();
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t VecSize =
+      getResourceDimensions(Dim) + (getResourceAttrs().IsArray ? 1 : 0);
   QualType IntTy = AST.IntTy;
   QualType IndexTy = VecSize > 1 ? AST.getExtVectorType(IntTy, VecSize) : IntTy;
   QualType CoordLevelTy = AST.getExtVectorType(IntTy, VecSize + 1);
@@ -1459,7 +1464,8 @@ CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
   BuiltinTypeDeclBuilder MipsSliceBuilder(SemaRef, MipsSliceRecord);
   MipsSliceBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
-                       getResourceAttrs().IsROV, false, ReturnType,
+                       getResourceAttrs().IsROV, /*RawBuffer=*/false,
+                       getResourceAttrs().IsArray, ReturnType,
                        AccessSpecifier::AS_public)
       .addMemberVariable("__level", IntTy, {}, AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
@@ -1502,7 +1508,8 @@ CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
   BuiltinTypeDeclBuilder MipsBuilder(SemaRef, MipsRecord);
   MipsBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
-                       getResourceAttrs().IsROV, false, ReturnType,
+                       getResourceAttrs().IsROV, /*RawBuffer=*/false,
+                       getResourceAttrs().IsArray, ReturnType,
                        AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
       .addCopyConstructor(AccessSpecifier::AS_protected)
@@ -1553,13 +1560,15 @@ BuiltinTypeDeclBuilder::addMipsMember(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim,
+                                              bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 2 : 1);
   QualType IntTy = AST.IntTy;
-  QualType OffsetTy = AST.getExtVectorType(IntTy, VecSize);
-  QualType LocationTy = AST.getExtVectorType(IntTy, VecSize + 1);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
+  QualType LocationTy = AST.getExtVectorType(IntTy, CoordSize);
   QualType ReturnType = getHandleElementType();
 
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
@@ -1627,23 +1636,24 @@ BuiltinTypeDeclBuilder::addByteAddressBufferStoreMethods() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim, bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T Sample(SamplerState s, float2 location)
   BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
                    PH::LastStmt, PH::_1)
@@ -1653,8 +1663,8 @@ BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
   // T Sample(SamplerState s, float2 location, int2 offset)
   BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
                    PH::LastStmt, PH::_1, PH::_2)
@@ -1664,8 +1674,8 @@ BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
   // T Sample(SamplerState s, float2 location, int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
@@ -1675,23 +1685,25 @@ BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim,
+                                             bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleBias(SamplerState s, float2 location, float bias)
   BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
@@ -1702,9 +1714,9 @@ BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
   // T SampleBias(SamplerState s, float2 location, float bias, int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1715,9 +1727,9 @@ BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
   // float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
@@ -1727,25 +1739,28 @@ BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim,
+                                             bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
+  QualType OffsetFloatTy = AST.getExtVectorType(FloatTy, OffsetSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleGrad(SamplerState s, float2 location, float2 ddx, float2 ddy)
   BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1756,10 +1771,10 @@ BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
   // int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
@@ -1770,10 +1785,10 @@ BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
   // int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
@@ -1784,23 +1799,25 @@ BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim,
+                                              bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleLevel(SamplerState s, float2 location, float lod)
   BuiltinTypeMethodBuilder(*this, "SampleLevel", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("LOD", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_level", ReturnType,
@@ -1811,9 +1828,9 @@ BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
   // T SampleLevel(SamplerState s, float2 location, float lod, int2 offset)
   return BuiltinTypeMethodBuilder(*this, "SampleLevel", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("LOD", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_level", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1822,23 +1839,25 @@ BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim,
+                                            bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleCmp(SamplerComparisonState s, float2 location, float compare_value)
   BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
@@ -1850,9 +1869,9 @@ BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
   // int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
                    PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1863,9 +1882,9 @@ BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
   // int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
@@ -1875,24 +1894,26 @@ BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim,
+                                                     bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleCmpLevelZero(SamplerComparisonState s, float2 location, float
   // compare_value)
   BuiltinTypeMethodBuilder(*this, "SampleCmpLevelZero", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
@@ -1904,9 +1925,9 @@ BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim) {
   // compare_value, int2 offset)
   return BuiltinTypeMethodBuilder(*this, "SampleCmpLevelZero", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -2008,18 +2029,19 @@ QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim, bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getGatherReturnType();
 
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType LocationTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(LocationTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(LocationTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType OffsetTy = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // Overloads for Gather, GatherRed, GatherGreen, GatherBlue, GatherAlpha
@@ -2037,7 +2059,7 @@ BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
     // ret GatherVariant(SamplerState s, float2 location)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
                      PH::LastStmt, PH::_1,
@@ -2047,7 +2069,7 @@ BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
     // ret GatherVariant(SamplerState s, float2 location, int2 offset)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("Offset", OffsetTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
@@ -2060,18 +2082,20 @@ BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim,
+                                            bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.getExtVectorType(AST.FloatTy, 4);
 
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // Overloads for GatherCmp, GatherCmpRed, GatherCmpGreen, GatherCmpBlue,
@@ -2091,7 +2115,7 @@ BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
     // compare_value)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerComparisonStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("CompareValue", FloatTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather_cmp", ReturnType,
@@ -2103,9 +2127,9 @@ BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
     // compare_value, int2 offset)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerComparisonStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("CompareValue", FloatTy)
-        .addParam("Offset", Int2Ty)
+        .addParam("Offset", OffsetTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather_cmp", ReturnType,
                      PH::Handle, PH::LastStmt, PH::_1, PH::_2,
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index f8fc2eeb3af55..09cf1fceca116 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -80,12 +80,14 @@ class BuiltinTypeDeclBuilder {
                    bool HasCounter,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
-  addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD,
+  addTextureHandle(ResourceClass RC, bool IsROV, bool IsArray,
+                   ResourceDimension RD,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addSamplerHandle();
   BuiltinTypeDeclBuilder &addConstantBufferConversionToType();
-  BuiltinTypeDeclBuilder &addArraySubscriptOperators(
-      ResourceDimension Dim = ResourceDimension::Unknown);
+  BuiltinTypeDeclBuilder &
+  addArraySubscriptOperators(ResourceDimension Dim = ResourceDimension::Unknown,
+                             bool IsArray = false);
 
   // Builtin types constructors
   BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
@@ -100,18 +102,27 @@ class BuiltinTypeDeclBuilder {
 
   // Builtin types methods
   BuiltinTypeDeclBuilder &addLoadMethods();
-  BuiltinTypeDeclBuilder &addTextureLoadMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addTextureLoadMethods(ResourceDimension Dim,
+                                                bool IsArray = false);
   BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods();
   BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods();
-  BuiltinTypeDeclBuilder &addSampleMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleBiasMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleGradMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleLevelMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleCmpMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleCmpLevelZeroMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addSampleMethods(ResourceDimension Dim,
+                                           bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleBiasMethods(ResourceDimension Dim,
+                                               bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleGradMethods(ResourceDimension Dim,
+                                               bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleLevelMethods(ResourceDimension Dim,
+                                                bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleCmpMethods(ResourceDimension Dim,
+                                              bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleCmpLevelZeroMethods(ResourceDimension Dim,
+                                                       bool IsArray = false);
   BuiltinTypeDeclBuilder &addCalculateLodMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addGatherMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addGatherCmpMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addGatherMethods(ResourceDimension Dim,
+                                           bool IsArray = false);
+  BuiltinTypeDeclBuilder &addGatherCmpMethods(ResourceDimension Dim,
+                                              bool IsArray = false);
   BuiltinTypeDeclBuilder &addIncrementCounterMethod();
   BuiltinTypeDeclBuilder &addDecrementCounterMethod();
   BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
@@ -138,7 +149,7 @@ class BuiltinTypeDeclBuilder {
   BuiltinTypeDeclBuilder &
   addResourceMember(StringRef MemberName, ResourceClass RC,
                     ResourceDimension RD, bool IsROV, bool RawBuffer,
-                    bool IsCounter, QualType ElementTy,
+                    bool IsCounter, bool IsArray, QualType ElementTy,
                     AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addFriend(CXXRecordDecl *Friend);
   CXXRecordDecl *addPrivateNestedRecord(StringRef Name);
@@ -146,7 +157,7 @@ class BuiltinTypeDeclBuilder {
   CXXRecordDecl *addMipsType(ResourceDimension Dim, QualType ReturnType);
   BuiltinTypeDeclBuilder &
   addHandleMember(ResourceClass RC, ResourceDimension RD, bool IsROV,
-                  bool RawBuffer, QualType ElementTy,
+                  bool RawBuffer, bool IsArray, QualType ElementTy,
                   AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
   addCounterHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 3f7255cb3f8a7..fec9175f6dc05 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -258,26 +258,27 @@ static BuiltinTypeDeclBuilder setupSamplerType(CXXRecordDecl *Decl, Sema &S) {
 /// Set up common members and attributes for texture types
 static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S,
                                                ResourceClass RC, bool IsROV,
+                                               bool IsArray,
                                                ResourceDimension Dim) {
   return BuiltinTypeDeclBuilder(S, Decl)
-      .addTextureHandle(RC, IsROV, Dim)
-      .addTextureLoadMethods(Dim)
-      .addArraySubscriptOperators(Dim)
+      .addTextureHandle(RC, IsROV, IsArray, Dim)
+      .addTextureLoadMethods(Dim, IsArray)
+      .addArraySubscriptOperators(Dim, IsArray)
       .addMipsMember(Dim)
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
       .addStaticInitializationFunctions(false)
-      .addSampleMethods(Dim)
-      .addSampleBiasMethods(Dim)
-      .addSampleGradMethods(Dim)
-      .addSampleLevelMethods(Dim)
-      .addSampleCmpMethods(Dim)
-      .addSampleCmpLevelZeroMethods(Dim)
+      .addSampleMethods(Dim, IsArray)
+      .addSampleBiasMethods(Dim, IsArray)
+      .addSampleGradMethods(Dim, IsArray)
+      .addSampleLevelMethods(Dim, IsArray)
+      .addSampleCmpMethods(Dim, IsArray)
+      .addSampleCmpLevelZeroMethods(Dim, IsArray)
       .addCalculateLodMethods(Dim)
       .addGetDimensionsMethods(Dim)
-      .addGatherMethods(Dim)
-      .addGatherCmpMethods(Dim);
+      .addGatherMethods(Dim, IsArray)
+      .addGatherCmpMethods(Dim, IsArray);
 }
 
 // Add a partial specialization for a template. The `TextureTemplate` is
@@ -678,7 +679,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
 
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     ResourceDimension::Dim2D)
+                     /*IsArray=*/false, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 
@@ -686,7 +687,27 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
       *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
   onCompletion(PartialSpec, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     ResourceDimension::Dim2D)
+                     /*IsArray=*/false, ResourceDimension::Dim2D)
+        .completeDefinition();
+  });
+
+  // Texture2DArray — same as Texture2D but IsArray=true
+  Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2DArray")
+             .addSimpleTemplateParams({"element_type"}, {Float4Ty},
+                                      TypedBufferConcept)
+             .finalizeForwardDeclaration();
+
+  onCompletion(Decl, [this](CXXRecordDecl *Decl) {
+    setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
+                     /*IsArray=*/true, ResourceDimension::Dim2D)
+        .completeDefinition();
+  });
+
+  auto *PartialSpec2DA = addVectorTexturePartialSpecialization(
+      *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
+  onCompletion(PartialSpec2DA, [this](CXXRecordDecl *Decl) {
+    setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
+                     /*IsArray=*/true, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 }
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index d784f8614a3bc..d591413822475 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3651,7 +3651,8 @@ static bool CheckIndexType(Sema *S, CallExpr *TheCall, unsigned IndexArgIndex) {
 
   unsigned int ExpectedDim = 1;
   if (ResAttrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
-    ExpectedDim = getResourceDimensions(ResAttrs.ResourceDimension);
+    ExpectedDim = getResourceDimensions(ResAttrs.ResourceDimension) +
+                  (ResAttrs.IsArray ? 1 : 0);
 
   if (ActualDim != ExpectedDim) {
     S->Diag(TheCall->getArg(IndexArgIndex)->getBeginLoc(),
@@ -3706,7 +3707,8 @@ static bool CheckVectorElementCount(Sema *S, QualType PassedType,
 
 enum class SampleKind { Sample, Bias, Grad, Level, Cmp, CmpLevelZero };
 
-static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall) {
+static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall,
+                                           bool IncludeArraySlice = true) {
   // Check the texture handle.
   if (CheckResourceHandle(&S, TheCall, 0,
                           [](const HLSLAttributedResourceType *ResType) {
@@ -3728,7 +3730,8 @@ static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall) {
 
   // Check the location.
   unsigned ExpectedDim =
-      getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
+      getResourceDimensions(ResourceTy->getAttrs().ResourceDimension) +
+      (IncludeArraySlice && ResourceTy->getAttrs().IsArray ? 1 : 0);
   if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
                               S.Context.FloatTy, ExpectedDim,
                               TheCall->getBeginLoc()))
@@ -3741,7 +3744,9 @@ static bool CheckCalculateLodBuiltin(Sema &S, CallExpr *TheCall) {
   if (S.checkArgCount(TheCall, 3))
     return true;
 
-  if (CheckTextureSamplerAndLocation(S, TheCall))
+  // CalculateLevelOfDetail location uses resource dimension only (e.g. float2
+  // for 2D), not an extra array slice component like Sample/Gather.
+  if (CheckTextureSamplerAndLocation(S, TheCall, /*IncludeArraySlice=*/false))
     return true;
 
   TheCall->setType(S.Context.FloatTy);
@@ -3847,11 +3852,12 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr *TheCall) {
   auto *ResourceTy =
       TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
 
-  // Check the location + lod (int3 for Texture2D).
-  unsigned ExpectedDim =
+  // Check the location + lod (int3 for Texture2D, int4 for Texture2DArray).
+  unsigned ResourceDim =
       getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
+  unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 0);
   QualType CoordLODTy = TheCall->getArg(1)->getType();
-  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, ExpectedDim + 1,
+  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim + 1,
                               TheCall->getArg(1)->getBeginLoc()))
     return true;
 
@@ -3864,10 +3870,10 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr *TheCall) {
     return true;
   }
 
-  // Check the offset operand.
+  // Check the offset operand (int2 for 2D textures; no array slice).
   if (TheCall->getNumArgs() > 2) {
     if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
-                                S.Context.IntTy, ExpectedDim,
+                                S.Context.IntTy, ResourceDim,
                                 TheCall->getArg(2)->getBeginLoc()))
       return true;
   }
diff --git a/clang/test/AST/HLSL/Texture2DArray-scalar-AST.hlsl b/clang/test/AST/HLSL/Texture2DArray-scalar-AST.hlsl
new file mode 100644
index 0000000000000..8e853c9a7e954
--- /dev/null
+++ b/clang/test/AST/HLSL/Texture2DArray-scalar-AST.hlsl
@@ -0,0 +1,931 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -o - %s | FileCheck %s
+
+// CHECK: CXXRecordDecl {{.*}} SamplerState definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit {{.*}} __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+
+// CHECK: CXXRecordDecl {{.*}} SamplerComparisonState definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit {{.*}} __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+
+// CHECK: ClassTemplateDecl {{.*}} Texture2DArray
+// CHECK: TemplateTypeParmDecl {{.*}} element_type
+// CHECK: CXXRecordDecl {{.*}} Texture2DArray definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+
+// CHECK: CXXMethodDecl {{.*}} Load 'element_type (vector<int, 4>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<int, 4>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 4>' lvalue ParmVar {{.*}} 'Location' 'vector<int, 4>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Load 'element_type (vector<int, 4>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<int, 4>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 4>' lvalue ParmVar {{.*}} 'Location' 'vector<int, 4>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(vector<unsigned int, 3>) const' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Index 'vector<unsigned int, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<unsigned int, 3>' lvalue ParmVar {{.*}} 'Index' 'vector<unsigned int, 3>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'element_type (hlsl::SamplerState, vector<float, 3>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'element_type (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'element_type (hlsl::SamplerState, vector<float, 3>, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'element_type (hlsl::SamplerState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'element_type (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'element_type (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'element_type (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'element_type (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'element_type (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleLevel 'element_type (hlsl::SamplerState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} LOD 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'LOD' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleLevel 'element_type (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} LOD 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'LOD' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmpLevelZero 'float (hlsl::SamplerComparisonState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp_level_zero' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmpLevelZero 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp_level_zero' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} CalculateLevelOfDetail 'float (hlsl::SamplerState, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_calculate_lod' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} CalculateLevelOfDetailUnclamped 'float (hlsl::SamplerState, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_calculate_lod_unclamped' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)'
+// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<element_type>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherRed 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherRed 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherGreen 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherGreen 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherBlue 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherBlue 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherAlpha 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherAlpha 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmp 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmp 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpRed 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpGreen 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpBlue 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpAlpha 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+Texture2DArray<float> t;
+SamplerState s;
+SamplerComparisonState scs;
+
+void main(float3 loc, float cmp) {
+  t.Sample(s, loc);
+  t.Sample(s, loc, int2(1, 2));
+  t.Sample(s, loc, int2(1, 2), 1.0);
+  t.SampleBias(s, loc, 0.0);
+  t.SampleBias(s, loc, 0.0, int2(1, 2));
+  t.SampleBias(s, loc, 0.0, int2(1, 2), 1.0);
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0));
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0), int2(1, 2));
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0), int2(1, 2), 1.0);
+  t.SampleLevel(s, loc, 0.0);
+  t.SampleLevel(s, loc, 0.0, int2(1, 2));
+  t.SampleCmp(scs, loc, cmp);
+  t.SampleCmp(scs, loc, cmp, int2(1, 2));
+  t.SampleCmp(scs, loc, cmp, int2(1, 2), 1.0f);
+  t.SampleCmpLevelZero(scs, loc, cmp);
+  t.SampleCmpLevelZero(scs, loc, cmp, int2(1, 2));
+  t.CalculateLevelOfDetail(s, loc.xy);
+  t.CalculateLevelOfDetailUnclamped(s, loc.xy);
+  t.Gather(s, loc);
+  uint u_w, u_h, u_l;
+  float f_w, f_h, f_l;
+  t.GetDimensions(u_w, u_h);
+  t.GetDimensions(0, u_w, u_h, u_l);
+  t.GetDimensions(f_w, f_h);
+  t.GetDimensions(0, f_w, f_h, f_l);
+}
diff --git a/clang/test/AST/HLSL/Texture2DArray-shorthand-AST.hlsl b/clang/test/AST/HLSL/Texture2DArray-shorthand-AST.hlsl
new file mode 100644
index 0000000000000..2c1aa6e2fd4ca
--- /dev/null
+++ b/clang/test/AST/HLSL/Texture2DArray-shorthand-AST.hlsl
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -o - %s | FileCheck %s
+
+// CHECK: VarDecl {{.*}} t1 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+Texture2DArray t1;
+
+// CHECK: VarDecl {{.*}} t1_explicit 'Texture2DArray<>':'hlsl::Texture2DArray<>'
+Texture2DArray<> t1_explicit;
+
+// CHECK: VarDecl {{.*}} t2 'Texture2DArray<float>':'hlsl::Texture2DArray<float>'
+Texture2DArray<float> t2;
+
+// CHECK: VarDecl {{.*}} t3 'Texture2DArray<float4>':'hlsl::Texture2DArray<>'
+Texture2DArray<float4> t3;
+
+// CHECK: TypedefDecl {{.*}} tex_alias 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+typedef Texture2DArray tex_alias;
+
+struct S {
+  // CHECK: FieldDecl {{.*}} tex 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+  Texture2DArray tex;
+};
+
+// CHECK: FunctionDecl {{.*}} foo 'hlsl::Texture2DArray<vector<float, 4>> (hlsl::Texture2DArray<vector<float, 4>>)'
+// CHECK: ParmVarDecl {{.*}} p 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+Texture2DArray foo(Texture2DArray p) {
+  // CHECK: VarDecl {{.*}} local 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+  Texture2DArray local;
+  return local;
+}
+
+template<typename T>
+void template_foo(T p) {
+  // CHECK: VarDecl {{.*}} local 'hlsl::Texture2DArray<vector<float, 4>>':'hlsl::Texture2DArray<>'
+  Texture2DArray local;
+}
+
+void main() {
+  template_foo(1);
+}
diff --git a/clang/test/AST/HLSL/Texture2DArray-vector-AST.hlsl b/clang/test/AST/HLSL/Texture2DArray-vector-AST.hlsl
new file mode 100644
index 0000000000000..390007672c18a
--- /dev/null
+++ b/clang/test/AST/HLSL/Texture2DArray-vector-AST.hlsl
@@ -0,0 +1,931 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -o - %s | FileCheck %s
+
+// CHECK: CXXRecordDecl {{.*}} SamplerState definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit {{.*}} __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+
+// CHECK: CXXRecordDecl {{.*}} SamplerComparisonState definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit {{.*}} __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+
+// CHECK: ClassTemplateDecl {{.*}} Texture2DArray
+// CHECK: TemplateTypeParmDecl {{.*}} element_type
+// CHECK: CXXRecordDecl {{.*}} Texture2DArray
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK: ClassTemplatePartialSpecializationDecl {{.*}} Texture2DArray definition explicit_specialization
+// CHECK: TemplateArgument type 'vector<element_type, element_count>':'vector<type-parameter-0-0, element_count>'
+// CHECK: TemplateTypeParmDecl {{.*}} element_type
+// CHECK: NonTypeTemplateParmDecl {{.*}} element_count
+// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+
+// CHECK: CXXMethodDecl {{.*}} Load 'vector<element_type, element_count> (vector<int, 4>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<int, 4>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 4>' lvalue ParmVar {{.*}} 'Location' 'vector<int, 4>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Load 'vector<element_type, element_count> (vector<int, 4>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<int, 4>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 4>' lvalue ParmVar {{.*}} 'Location' 'vector<int, 4>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} operator[] 'vector<element_type, element_count> const hlsl_device &(vector<unsigned int, 3>) const' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Index 'vector<unsigned int, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: UnaryOperator {{.*}} 'vector<element_type, element_count> hlsl_device' lvalue prefix '*' cannot overflow
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count> hlsl_device *' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<unsigned int, 3>' lvalue ParmVar {{.*}} 'Index' 'vector<unsigned int, 3>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Sample 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleBias 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Bias 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_bias' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Bias' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleGrad 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, vector<float, 2>, vector<float, 2>, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDX 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} DDY 'vector<float, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_grad' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDX' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'DDY' 'vector<float, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleLevel 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} LOD 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'LOD' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleLevel 'vector<element_type, element_count> (hlsl::SamplerState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} LOD 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, element_count>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_level' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'LOD' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmp 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Clamp 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'Clamp' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmpLevelZero 'float (hlsl::SamplerComparisonState, vector<float, 3>, float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp_level_zero' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} SampleCmpLevelZero 'float (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_sample_cmp_level_zero' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} CalculateLevelOfDetail 'float (hlsl::SamplerState, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_calculate_lod' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} CalculateLevelOfDetailUnclamped 'float (hlsl::SamplerState, vector<float, 2>)'
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'float' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_calculate_lod_unclamped' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}}
+// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)'
+// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}}
+// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict'
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}}
+// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
+
+// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
+// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict'
+// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: CallExpr {{.*}}
+// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// CHECK-SAME: ' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<vector<element_type, element_count>>' lvalue implicit this
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict'
+
+// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherRed 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherRed 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherGreen 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherGreen 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherBlue 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherBlue 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherAlpha 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherAlpha 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 3>, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<element_type, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmp 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmp 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpRed 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpGreen 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpBlue 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
+// CHECK-NEXT: AlwaysInlineAttr
+
+// CHECK: CXXMethodDecl {{.*}} GatherCmpAlpha 'vector<float, 4> (hlsl::SamplerComparisonState, vector<float, 3>, float, vector<int, 2>)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 3>'
+// CHECK-NEXT: ParmVarDecl {{.*}} CompareValue 'float'
+// CHECK-NEXT: ParmVarDecl {{.*}} Offset 'vector<int, 2>'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: ReturnStmt
+// CHECK-NEXT: CStyleCastExpr {{.*}} 'vector<float, 4>' <Dependent>
+// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_gather_cmp' 'void (...) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2DArray<{{.*}}>' lvalue implicit this
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::SamplerComparisonState' lvalue ParmVar {{.*}} 'Sampler' 'hlsl::SamplerComparisonState'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 3>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 3>'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'CompareValue' 'float'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
+// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<int, 2>' lvalue ParmVar {{.*}} 'Offset' 'vector<int, 2>'
+// CHECK-NEXT: AlwaysInlineAttr
+
+Texture2DArray<float4> t;
+SamplerState s;
+SamplerComparisonState scs;
+
+void main(float3 loc, float cmp) {
+  t.Sample(s, loc);
+  t.Sample(s, loc, int2(1, 2));
+  t.Sample(s, loc, int2(1, 2), 1.0);
+  t.SampleBias(s, loc, 0.0);
+  t.SampleBias(s, loc, 0.0, int2(1, 2));
+  t.SampleBias(s, loc, 0.0, int2(1, 2), 1.0);
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0));
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0), int2(1, 2));
+  t.SampleGrad(s, loc, float2(0,0), float2(0,0), int2(1, 2), 1.0);
+  t.SampleLevel(s, loc, 0.0);
+  t.SampleLevel(s, loc, 0.0, int2(1, 2));
+  t.SampleCmp(scs, loc, cmp);
+  t.SampleCmp(scs, loc, cmp, int2(1, 2));
+  t.SampleCmp(scs, loc, cmp, int2(1, 2), 1.0f);
+  t.SampleCmpLevelZero(scs, loc, cmp);
+  t.SampleCmpLevelZero(scs, loc, cmp, int2(1, 2));
+  t.CalculateLevelOfDetail(s, loc.xy);
+  t.CalculateLevelOfDetailUnclamped(s, loc.xy);
+  t.Gather(s, loc);
+  uint u_w, u_h, u_l;
+  float f_w, f_h, f_l;
+  t.GetDimensions(u_w, u_h);
+  t.GetDimensions(0, u_w, u_h, u_l);
+  t.GetDimensions(f_w, f_h);
+  t.GetDimensions(0, f_w, f_h, f_l);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-CalculateLevelOfDetail.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-CalculateLevelOfDetail.hlsl
new file mode 100644
index 0000000000000..eebde4aacdbf6
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-CalculateLevelOfDetail.hlsl
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+Texture2DArray t;
+SamplerState s;
+
+// CHECK: define hidden {{.*}} float @test_lod(float vector[2])(<2 x float> {{.*}} %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::CalculateLevelOfDetail(hlsl::SamplerState, float vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <2 x float> {{.*}} %{{.*}})
+// CHECK: ret float %[[CALL]]
+
+float test_lod(float2 loc : LOC) : SV_Target {
+  return t.CalculateLevelOfDetail(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::CalculateLevelOfDetail(hlsl::SamplerState, float vector[2])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <2 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <2 x float>, ptr %[[COORD]]
+// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.calculate.lod.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v2f32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]])
+// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.calculate.lod.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]])
+// CHECK: ret float %[[RES]]
+
+// CHECK: define hidden {{.*}} float @test_lod_unclamped(float vector[2])(<2 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[LOC_VAL:.*]] = load <2 x float>, ptr {{.*}}
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::CalculateLevelOfDetailUnclamped(hlsl::SamplerState, float vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <2 x float> {{.*}} %[[LOC_VAL]])
+// CHECK: ret float %[[CALL]]
+
+float test_lod_unclamped(float2 loc : LOC) : SV_Target {
+  return t.CalculateLevelOfDetailUnclamped(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::CalculateLevelOfDetailUnclamped(hlsl::SamplerState, float vector[2])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <2 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <2 x float>, ptr %[[COORD]]
+// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.calculate.lod.unclamped.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v2f32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]])
+// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.calculate.lod.unclamped.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]])
+// CHECK: ret float %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-Gather.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-Gather.hlsl
new file mode 100644
index 0000000000000..38b348de6124f
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-Gather.hlsl
@@ -0,0 +1,183 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerState" = type { target("dx.Sampler", 0) }
+// DXIL: %"class.hlsl::SamplerComparisonState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerState" = type { target("spirv.Sampler") }
+// SPIRV: %"class.hlsl::SamplerComparisonState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerState s;
+SamplerComparisonState sc;
+
+// CHECK: define hidden {{.*}} <4 x float> @main(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Gather(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 main(float3 loc : LOC) : SV_Target {
+  return t.Gather(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Gather(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_offset(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Gather(hlsl::SamplerState, float vector[3], int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, <2 x i32> {{.*}} <i32 1, i32 2>)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_offset(float3 loc : LOC) : SV_Target {
+  return t.Gather(s, loc, int2(1, 2));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Gather(hlsl::SamplerState, float vector[3], int vector[2])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x i32> {{.*}} %[[OFFSET:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> %[[OFFSET_VAL]])
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> %[[OFFSET_VAL]])
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_green(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherGreen(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_green(float3 loc : LOC) : SV_Target {
+  return t.GatherGreen(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherGreen(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 1, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 1, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_red(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherRed(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_red(float3 loc : LOC) : SV_Target {
+  return t.GatherRed(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherRed(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_blue(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherBlue(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_blue(float3 loc : LOC) : SV_Target {
+  return t.GatherBlue(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherBlue(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 2, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 2, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_alpha(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherAlpha(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_alpha(float3 loc : LOC) : SV_Target {
+  return t.GatherAlpha(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherAlpha(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 3, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], i32 3, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_cmp(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherCmp(hlsl::SamplerComparisonState, float vector[3], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 5.000000e-01)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_cmp(float3 loc : LOC) : SV_Target {
+  return t.GatherCmp(sc, loc, 0.5);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::GatherCmp(hlsl::SamplerComparisonState, float vector[3], float)(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], float {{.*}} %[[CMP:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[CMP_ADDR:.*]] = alloca float
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store float %[[CMP]], ptr %[[CMP_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[CMP_VAL:.*]] = load float, ptr %[[CMP_ADDR]]
+// CHECK: %[[CONV:.*]] = fpext {{.*}} float %[[CMP_VAL]] to double
+// CHECK: %[[TRUNC:.*]] = fptrunc {{.*}} double %[[CONV]] to float
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.cmp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], float %[[TRUNC]], i32 0, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.cmp.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], float %[[TRUNC]], <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
new file mode 100644
index 0000000000000..f295839be4887
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+Texture2DArray<float4> Tex : register(t0);
+
+// CHECK: define {{.*}} void @test_uint_dims()
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
+void test_uint_dims() {
+  uint w, h;
+  Tex.GetDimensions(w, h);
+}
+
+// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded.
+
+// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]]
+// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]])
+// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]])
+// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
+// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0
+// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]]
+// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
+// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1
+// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]]
+
+// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]])
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
+void test_uint_levels_dims(uint mipLevel) {
+  uint w, h, l;
+  Tex.GetDimensions(mipLevel, w, h, l);
+}
+
+// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]]
+// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]]
+// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]])
+// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
+// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
+// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0
+// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]]
+// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
+// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1
+// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]]
+// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]]
+// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2
+// CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]]
+
+// CHECK: define {{.*}} void @test_float_dims()
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
+void test_float_dims() {
+  float w, h;
+  Tex.GetDimensions(w, h);
+}
+
+// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]]
+// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]])
+// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]])
+// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
+// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0
+// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float
+// CHECK: store float %[[W_F]], ptr %[[W_PTR]]
+// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
+// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1
+// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float
+// CHECK: store float %[[H_F]], ptr %[[H_PTR]]
+
+// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]])
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
+void test_float_levels_dims(uint mipLevel) {
+  float w, h, l;
+  Tex.GetDimensions(mipLevel, w, h, l);
+}
+
+// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray<float vector[4]>::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]]
+// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]]
+// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]])
+// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
+// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
+// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0
+// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float
+// CHECK: store float %[[W_F]], ptr %[[W_PTR]]
+// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
+// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1
+// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float
+// CHECK: store float %[[H_F]], ptr %[[H_PTR]]
+// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]]
+// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2
+// CHECK: %[[L_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[L_VAL]] to float
+// CHECK: store float %[[L_F]], ptr %[[L_PTR]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-Load.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-Load.hlsl
new file mode 100644
index 0000000000000..02909846c9833
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-Load.hlsl
@@ -0,0 +1,236 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+Texture2DArray<float4> t;
+
+// CHECK: define hidden {{.*}} <4 x float> @test_load(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Load(int vector[4])(ptr {{.*}} @t, <4 x i32> noundef %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_load(int2 loc : LOC) : SV_Target {
+  return t.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[LOCATION_ADDR:.*]] = alloca <4 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <4 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]]
+// CHECK: %[[LOCATION_VAL:.*]] = load <4 x i32>, ptr %[[LOCATION_ADDR]]
+// CHECK: %[[COORD:.*]] = shufflevector <4 x i32> %[[LOCATION_VAL]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2>
+// CHECK: %[[LOD:.*]] = extractelement <4 x i32> %[[LOCATION_VAL]], i64 3
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], <3 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], <3 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_load_offset(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_load_offset(int2 loc : LOC) : SV_Target {
+  return t.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[LOCATION_ADDR:.*]] = alloca <4 x i32>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <4 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]]
+// CHECK: %[[LOCATION_VAL:.*]] = load <4 x i32>, ptr %[[LOCATION_ADDR]]
+// CHECK: %[[COORD:.*]] = shufflevector <4 x i32> %[[LOCATION_VAL]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2>
+// CHECK: %[[LOD:.*]] = extractelement <4 x i32> %[[LOCATION_VAL]], i64 3
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], <3 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]])
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], <3 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]])
+// CHECK: ret <4 x float> %[[RES]]
+
+
+// For the rest of the types, we just check that the call to the member
+// function has the correct return type.
+
+Texture2DArray<float> t_float;
+
+// CHECK: define hidden {{.*}} float @test_load_float(int vector[2])
+// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret float %[[RES]]
+float test_load_float(int2 loc : LOC) {
+  return t_float.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define hidden {{.*}} float @test_load_offset_float(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2DArray<float>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_float, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret float %[[CALL]]
+float test_load_offset_float(int2 loc : LOC) {
+  return t_float.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret float %[[RES]]
+
+Texture2DArray<float2> t_float2;
+
+// CHECK: define hidden {{.*}} <2 x float> @test_load_float2(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2DArray<float vector[2]>::Load(int vector[4])(ptr {{.*}} @t_float2, <4 x i32> noundef %{{.*}})
+// CHECK: ret <2 x float> %[[CALL]]
+float2 test_load_float2(int2 loc : LOC) {
+  return t_float2.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2DArray<float vector[2]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret <2 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <2 x float> @test_load_offset_float2(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2DArray<float vector[2]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_float2, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <2 x float> %[[CALL]]
+float2 test_load_offset_float2(int2 loc : LOC) {
+  return t_float2.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2DArray<float vector[2]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret <2 x float> %[[RES]]
+
+Texture2DArray<float3> t_float3;
+
+// CHECK: define hidden {{.*}} <3 x float> @test_load_float3(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2DArray<float vector[3]>::Load(int vector[4])(ptr {{.*}} @t_float3, <4 x i32> noundef %{{.*}})
+// CHECK: ret <3 x float> %[[CALL]]
+float3 test_load_float3(int2 loc : LOC) {
+  return t_float3.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2DArray<float vector[3]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret <3 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <3 x float> @test_load_offset_float3(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2DArray<float vector[3]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_float3, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <3 x float> %[[CALL]]
+float3 test_load_offset_float3(int2 loc : LOC) {
+  return t_float3.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2DArray<float vector[3]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret <3 x float> %[[RES]]
+
+Texture2DArray<int> t_int;
+
+// CHECK: define hidden {{.*}} i32 @test_load_int(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2DArray<int>::Load(int vector[4])(ptr {{.*}} @t_int, <4 x i32> noundef %{{.*}})
+// CHECK: ret i32 %[[CALL]]
+int test_load_int(int2 loc : LOC) {
+  return t_int.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2DArray<int>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret i32 %[[RES]]
+
+// CHECK: define hidden {{.*}} i32 @test_load_offset_int(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2DArray<int>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_int, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret i32 %[[CALL]]
+int test_load_offset_int(int2 loc : LOC) {
+  return t_int.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2DArray<int>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret i32 %[[RES]]
+
+Texture2DArray<int2> t_int2;
+
+// CHECK: define hidden {{.*}} <2 x i32> @test_load_int2(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2DArray<int vector[2]>::Load(int vector[4])(ptr {{.*}} @t_int2, <4 x i32> noundef %{{.*}})
+// CHECK: ret <2 x i32> %[[CALL]]
+int2 test_load_int2(int2 loc : LOC) {
+  return t_int2.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2DArray<int vector[2]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret <2 x i32> %[[RES]]
+
+// CHECK: define hidden {{.*}} <2 x i32> @test_load_offset_int2(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2DArray<int vector[2]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_int2, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <2 x i32> %[[CALL]]
+int2 test_load_offset_int2(int2 loc : LOC) {
+  return t_int2.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2DArray<int vector[2]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret <2 x i32> %[[RES]]
+
+Texture2DArray<int3> t_int3;
+
+// CHECK: define hidden {{.*}} <3 x i32> @test_load_int3(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2DArray<int vector[3]>::Load(int vector[4])(ptr {{.*}} @t_int3, <4 x i32> noundef %{{.*}})
+// CHECK: ret <3 x i32> %[[CALL]]
+int3 test_load_int3(int2 loc : LOC) {
+  return t_int3.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2DArray<int vector[3]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret <3 x i32> %[[RES]]
+
+// CHECK: define hidden {{.*}} <3 x i32> @test_load_offset_int3(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2DArray<int vector[3]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_int3, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <3 x i32> %[[CALL]]
+int3 test_load_offset_int3(int2 loc : LOC) {
+  return t_int3.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2DArray<int vector[3]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret <3 x i32> %[[RES]]
+
+Texture2DArray<int4> t_int4;
+
+// CHECK: define hidden {{.*}} <4 x i32> @test_load_int4(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2DArray<int vector[4]>::Load(int vector[4])(ptr {{.*}} @t_int4, <4 x i32> noundef %{{.*}})
+// CHECK: ret <4 x i32> %[[CALL]]
+int4 test_load_int4(int2 loc : LOC) {
+  return t_int4.Load(int4(loc, 0, 0));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2DArray<int vector[4]>::Load(int vector[4])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
+// CHECK: ret <4 x i32> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x i32> @test_load_offset_int4(int vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2DArray<int vector[4]>::Load(int vector[4], int vector[2])(ptr {{.*}} @t_int4, <4 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: ret <4 x i32> %[[CALL]]
+int4 test_load_offset_int4(int2 loc : LOC) {
+  return t_int4.Load(int4(loc, 0, 0), int2(1, 1));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2DArray<int vector[4]>::Load(int vector[4], int vector[2])(ptr {{.*}} %[[THIS:.*]], <4 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_7t.v3i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 7) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %{{.*}}, <3 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
+// CHECK: ret <4 x i32> %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-Mips.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-Mips.hlsl
new file mode 100644
index 0000000000000..f42963165e7c2
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-Mips.hlsl
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+
+Texture2DArray<float4> t;
+
+// CHECK: define internal {{.*}} <4 x float> @test_mips(float vector[3])(<3 x float> {{.*}} %loc)
+// CHECK: entry:
+// CHECK: %[[LOC_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[REF_TMP:.*]] = alloca %"struct.hlsl::Texture2DArray<>::mips_slice_type"
+// CHECK: store <3 x float> %loc, ptr %[[LOC_ADDR]]
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::mips_type::operator[](int) const(ptr {{.*}} %[[REF_TMP]], ptr {{.*}} getelementptr {{.*}} (i8, ptr @t, i32 4), i32 noundef 0)
+// CHECK: %[[V0:.*]] = load <3 x float>, ptr %[[LOC_ADDR]]
+// CHECK: %[[SHUF:.*]] = shufflevector <3 x float> %[[V0]], <3 x float> poison, <2 x i32> <i32 0, i32 1>
+// CHECK: %[[CONV:.*]] = fptosi <2 x float> %[[SHUF]] to <2 x i32>
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::mips_slice_type::operator[](int vector[3]) const(ptr {{.*}} %[[REF_TMP]], <3 x i32> {{.*}} %[[VEC:.*]])
+// CHECK: ret <4 x float> %[[CALL]]
+
+[shader("pixel")]
+float4 test_mips(float3 loc : LOC) : SV_Target {
+  return t.mips[0][int3(int2(loc.xy), 0)];
+}
+
+// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray<float vector[4]>::mips_type::operator[](int) const(ptr  {{.*}} %agg.result, ptr {{.*}} %this, i32 {{.*}} %Level)
+// CHECK: entry:
+// CHECK: %{{.*}} = alloca ptr
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[LEVEL_ADDR:.*]] = alloca i32
+// CHECK: %[[SLICE:.*]] = alloca %"struct.hlsl::Texture2DArray<>::mips_slice_type"
+// CHECK: store ptr %agg.result, ptr %{{.*}}
+// CHECK: store ptr %this, ptr %[[THIS_ADDR]]
+// CHECK: store i32 %Level, ptr %[[LEVEL_ADDR]]
+// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::mips_slice_type::mips_slice_type()(ptr {{.*}} %[[SLICE]])
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr {{.*}} %"struct.hlsl::Texture2DArray<>::mips_type", ptr %[[THIS1]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]]
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr {{.*}} %"struct.hlsl::Texture2DArray<>::mips_slice_type", ptr %[[SLICE]], i32 0, i32 0
+// CHECK: store target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], ptr %[[HANDLE_GEP2]]
+// CHECK: %[[L_VAL:.*]] = load i32, ptr %[[LEVEL_ADDR]]
+// CHECK: %[[LEVEL_GEP:.*]] = getelementptr {{.*}} %"struct.hlsl::Texture2DArray<>::mips_slice_type", ptr %[[SLICE]], i32 0, i32 1
+// CHECK: store i32 %[[L_VAL]], ptr %[[LEVEL_GEP]]
+// CHECK: call void @hlsl::Texture2DArray<float vector[4]>::mips_slice_type::mips_slice_type(hlsl::Texture2DArray<float vector[4]>::mips_slice_type const&)(ptr noundef nonnull align 4 dereferenceable(8) %agg.result, ptr noundef nonnull align 4 dereferenceable(8) %[[SLICE]])
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::mips_slice_type::operator[](int vector[3]) const(ptr {{.*}} %[[THIS:.*]], <3 x i32> noundef %[[COORD:.*]])
+// CHECK: entry:
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x i32>
+// CHECK: %[[VEC_TMP:.*]] = alloca <3 x i32>
+// CHECK: store <3 x i32> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS1:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[COORD_PARAM:.*]] = load <3 x i32>, ptr %[[COORD_ADDR]]
+// CHECK: store <3 x i32> %[[COORD_PARAM]], ptr %[[VEC_TMP]]
+// CHECK: %[[HANDLE_PTR:.*]] = getelementptr {{.*}} %"struct.hlsl::Texture2DArray<>::mips_slice_type", ptr %[[THIS1]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_PTR]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x i32>, ptr %[[VEC_TMP]]
+// CHECK: %[[VECEXT:.*]] = extractelement <3 x i32> %[[COORD_VAL]], i32 0
+// CHECK: %[[VECINIT:.*]] = insertelement <4 x i32> poison, i32 %[[VECEXT]], i32 0
+// CHECK: %[[COORD_VAL2:.*]] = load <3 x i32>, ptr %[[VEC_TMP]]
+// CHECK: %[[VECEXT2:.*]] = extractelement <3 x i32> %[[COORD_VAL2]], i32 1
+// CHECK: %[[VECINIT3:.*]] = insertelement <4 x i32> %[[VECINIT]], i32 %[[VECEXT2]], i32 1
+// CHECK: %[[COORD_VAL3:.*]] = load <3 x i32>, ptr %[[VEC_TMP]]
+// CHECK: %[[VECEXT3:.*]] = extractelement <3 x i32> %[[COORD_VAL3]], i32 2
+// CHECK: %[[VECINIT4:.*]] = insertelement <4 x i32> %[[VECINIT3]], i32 %[[VECEXT3]], i32 2
+// CHECK: %[[LEVEL_PTR:.*]] = getelementptr {{.*}} %"struct.hlsl::Texture2DArray<>::mips_slice_type", ptr %[[THIS1]], i32 0, i32 1
+// CHECK: %[[LEVEL_VAL:.*]] = load i32, ptr %[[LEVEL_PTR]]
+// CHECK: %[[VECINIT5:.*]] = insertelement <4 x i32> %[[VECINIT4]], i32 %[[LEVEL_VAL]], i32 3
+// CHECK: %[[COORD_X:.*]] = shufflevector <4 x i32> %[[VECINIT5]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2>
+// CHECK: %[[LOD:.*]] = extractelement <4 x i32> %[[VECINIT5]], i64 3
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_7t.v3i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], <3 x i32> %[[COORD_X]], i32 %[[LOD]], <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-Sample.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-Sample.hlsl
new file mode 100644
index 0000000000000..7f875e6010fa5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-Sample.hlsl
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerState s;
+
+// CHECK: define hidden {{.*}} <4 x float> @main(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 main(float3 loc : LOC) : SV_Target {
+  return t.Sample(s, loc);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> zeroinitializer)
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_offset(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3], int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, <2 x i32> {{.*}} <i32 1, i32 2>)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_offset(float3 loc : LOC) : SV_Target {
+  return t.Sample(s, loc, int2(1, 2));
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3], int vector[2])(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x i32> {{.*}} %[[OFFSET:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]])
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]])
+// CHECK: ret <4 x float> %[[RES]]
+
+// CHECK: define hidden {{.*}} <4 x float> @test_clamp(float vector[3])(<3 x float> noundef nofpclass(nan inf) %[[LOC:.*]])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3], int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}}, <2 x i32> {{.*}} <i32 1, i32 2>, float {{.*}} 1.000000e+00)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_clamp(float3 loc : LOC) : SV_Target {
+  return t.Sample(s, loc, int2(1, 2), 1.0f);
+}
+
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3], int vector[2], float)(ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x i32> {{.*}} %[[OFFSET:[^,]+]], float {{.*}} %[[CLAMP:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: %[[CLAMP_ADDR:.*]] = alloca float
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: store float %[[CLAMP]], ptr %[[CLAMP_ADDR]]
+// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP]]
+// CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// CHECK: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]]
+// CHECK: %[[CLAMP_CAST:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]])
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.clamp.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <3 x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]])
+// CHECK: ret <4 x float> %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleBias.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleBias.hlsl
new file mode 100644
index 0000000000000..cf27cde829cc5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleBias.hlsl
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerState s;
+
+// CHECK-LABEL: @test_bias(float vector[3])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_bias(float3 loc : LOC) : SV_Target {
+  return t.SampleBias(s, loc, 0.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float)(
+// CHECK: %[[THIS_VAL1:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL1]], i32 0, i32 0
+// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
+// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
+// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
+// CHECK: %[[BIAS_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: %{{.*}} = call {{.*}} <4 x float> @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <3 x float> %{{.*}}, float %[[BIAS_CAST1]], <2 x i32> zeroinitializer)
+// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <3 x float> %{{.*}}, float %[[BIAS_CAST1]], <2 x i32> zeroinitializer)
+
+// CHECK-LABEL: @test_offset(float vector[3])
+// CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>)
+// CHECK: ret <4 x float> %[[CALL_OFFSET]]
+
+float4 test_offset(float3 loc : LOC) : SV_Target {
+  return t.SampleBias(s, loc, 0.0f, int2(1, 2));
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float, int vector[2])(
+// CHECK: %[[THIS_VAL2:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL2]], i32 0, i32 0
+// CHECK: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
+// CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
+// CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
+// CHECK: %[[BIAS_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: %{{.*}} = call {{.*}} <4 x float> @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <3 x float> %{{.*}}, float %[[BIAS_CAST2]], <2 x i32> %{{.*}})
+// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <3 x float> %{{.*}}, float %[[BIAS_CAST2]], <2 x i32> %{{.*}})
+
+// CHECK-LABEL: @test_clamp(float vector[3])
+// CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float, int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00)
+// CHECK: ret <4 x float> %[[CALL_CLAMP]]
+
+float4 test_clamp(float3 loc : LOC) : SV_Target {
+  return t.SampleBias(s, loc, 0.0f, int2(1, 2), 1.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[3], float, int vector[2], float)(
+// CHECK: %[[THIS_VAL3:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL3]], i32 0, i32 0
+// CHECK: %[[HANDLE3:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP3]]
+// CHECK: %[[SAMPLER_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
+// CHECK: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]]
+// CHECK: %[[BIAS_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: %{{.*}} = call {{.*}} <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <3 x float> %{{.*}}, float %[[BIAS_CAST3]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]])
+// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <3 x float> %{{.*}}, float %[[BIAS_CAST3]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]])
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmp.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmp.hlsl
new file mode 100644
index 0000000000000..ff0da74489e92
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmp.hlsl
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerComparisonState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerComparisonState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerComparisonState s;
+
+// CHECK-LABEL: @test_cmp(float vector[3], float)
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00)
+// CHECK: ret float %[[CALL]]
+
+float test_cmp(float3 loc : LOC, float cmp : CMP) : SV_Target {
+  return t.SampleCmp(s, loc, 0.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float)(
+// CHECK-SAME: ptr noundef nonnull {{.*}} %[[THIS1:[^,]+]], ptr noundef byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER1:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD1:[^,]+]], float noundef nofpclass(nan inf) %[[CMP1:[^)]+]])
+// CHECK: %[[THIS_VAL1:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL1]], i32 0, i32 0
+// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
+// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER1]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
+// CHECK: %[[COORD_VAL1:.*]] = load <3 x float>, ptr %{{.*}}
+// CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: call {{.*}} float @llvm.dx.resource.samplecmp.f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer)
+// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer)
+
+// CHECK-LABEL: @test_offset(float vector[3], float)
+// CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>)
+// CHECK: ret float %[[CALL_OFFSET]]
+
+float test_offset(float3 loc : LOC, float cmp : CMP) : SV_Target {
+  return t.SampleCmp(s, loc, 0.0f, int2(1, 2));
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float, int vector[2])(
+// CHECK-SAME: ptr noundef nonnull {{.*}} %[[THIS2:[^,]+]], ptr noundef byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER2:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD2:[^,]+]], float noundef nofpclass(nan inf) %[[CMP2:[^,]+]], <2 x i32> noundef %[[OFFSET2:[^)]+]])
+// CHECK: %[[THIS_VAL2:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL2]], i32 0, i32 0
+// CHECK: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
+// CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER2]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
+// CHECK: %[[COORD_VAL2:.*]] = load <3 x float>, ptr %{{.*}}
+// CHECK: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %{{.*}}
+// DXIL: call {{.*}} float @llvm.dx.resource.samplecmp.f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
+// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
+
+// CHECK-LABEL: @test_clamp(float vector[3], float)
+// CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float, int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00)
+// CHECK: ret float %[[CALL_CLAMP]]
+
+float test_clamp(float3 loc : LOC, float cmp : CMP) : SV_Target {
+  return t.SampleCmp(s, loc, 0.0f, int2(1, 2), 1.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[3], float, int vector[2], float)(
+// CHECK-SAME: ptr noundef nonnull {{.*}} %[[THIS3:[^,]+]], ptr noundef byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER3:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD3:[^,]+]], float noundef nofpclass(nan inf) %[[CMP3:[^,]+]], <2 x i32> noundef %[[OFFSET3:[^,]+]], float noundef nofpclass(nan inf) %[[CLAMP3:[^)]+]])
+// CHECK: %[[THIS_VAL3:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL3]], i32 0, i32 0
+// CHECK: %[[HANDLE3:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP3]]
+// CHECK: %[[SAMPLER_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER3]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]]
+// CHECK: %[[COORD_VAL3:.*]] = load <3 x float>, ptr %{{.*}}
+// CHECK: %[[CMP_VAL3:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK: %[[OFFSET_VAL3:.*]] = load <2 x i32>, ptr %{{.*}}
+// CHECK: %[[CLAMP_VAL3:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: call {{.*}} float @llvm.dx.resource.samplecmp.clamp.f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <3 x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]])
+// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.clamp.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <3 x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]])
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmpLevelZero.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmpLevelZero.hlsl
new file mode 100644
index 0000000000000..06916a9b2e357
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmpLevelZero.hlsl
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+Texture2DArray<float4> t;
+SamplerComparisonState s;
+
+// CHECK-LABEL: @test_cmp_level_zero(float vector[3], float)
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[3], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00)
+// CHECK: ret float %[[CALL]]
+
+float test_cmp_level_zero(float3 loc : LOC, float cmp : CMP) : SV_Target {
+  return t.SampleCmpLevelZero(s, loc, 0.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[3], float)(
+// CHECK-SAME: ptr noundef nonnull {{.*}} %[[THIS1:[^,]+]], ptr noundef byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER1:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD1:[^,]+]], float noundef nofpclass(nan inf) %[[CMP1:[^)]+]])
+// CHECK: %[[THIS_VAL1:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL1]], i32 0, i32 0
+// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
+// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER1]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
+// CHECK: %[[COORD_VAL1:.*]] = load <3 x float>, ptr %{{.*}}
+// CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: call {{.*}} float @llvm.dx.resource.samplecmplevelzero.f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer)
+// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmplevelzero.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer)
+
+// CHECK-LABEL: @test_cmp_level_zero_offset(float vector[3], float)
+// CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[3], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>)
+// CHECK: ret float %[[CALL_OFFSET]]
+
+float test_cmp_level_zero_offset(float3 loc : LOC, float cmp : CMP) : SV_Target {
+  return t.SampleCmpLevelZero(s, loc, 0.0f, int2(1, 2));
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} float @hlsl::Texture2DArray<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[3], float, int vector[2])(
+// CHECK-SAME: ptr noundef nonnull {{.*}} %[[THIS2:[^,]+]], ptr noundef byval(%"class.hlsl::SamplerComparisonState") {{.*}} %[[SAMPLER2:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD2:[^,]+]], float noundef nofpclass(nan inf) %[[CMP2:[^,]+]], <2 x i32> noundef %[[OFFSET2:[^)]+]])
+// CHECK: %[[THIS_VAL2:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL2]], i32 0, i32 0
+// CHECK: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
+// CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %[[SAMPLER2]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
+// CHECK: %[[COORD_VAL2:.*]] = load <3 x float>, ptr %{{.*}}
+// CHECK: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}}
+// CHECK: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %{{.*}}
+// DXIL: call {{.*}} float @llvm.dx.resource.samplecmplevelzero.f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
+// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmplevelzero.f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleGrad.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleGrad.hlsl
new file mode 100644
index 0000000000000..236d717120798
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleGrad.hlsl
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerState s;
+
+// CHECK-LABEL: @test_grad(float vector[3], float vector[2], float vector[2])
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}})
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_grad(float3 loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : SV_Target {
+  return t.SampleGrad(s, loc, ddx, ddy);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2])(
+// CHECK-SAME: ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x float> {{.*}} %[[DDX:[^,]+]], <2 x float> {{.*}} %[[DDY:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[DDX_ADDR:.*]] = alloca <2 x float>
+// CHECK: %[[DDY_ADDR:.*]] = alloca <2 x float>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x float> %[[DDX]], ptr %[[DDX_ADDR]]
+// CHECK: store <2 x float> %[[DDY]], ptr %[[DDY_ADDR]]
+// CHECK: %[[THIS_VAL1:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL1]], i32 0, i32 0
+// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
+// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[DDX_VAL:.*]] = load <2 x float>, ptr %[[DDX_ADDR]]
+// CHECK: %[[DDY_VAL:.*]] = load <2 x float>, ptr %[[DDY_ADDR]]
+// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer)
+// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer)
+
+// CHECK-LABEL: @test_offset(float vector[3], float vector[2], float vector[2])
+// CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2], int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x i32> noundef <i32 1, i32 2>)
+// CHECK: ret <4 x float> %[[CALL_OFFSET]]
+
+float4 test_offset(float3 loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : SV_Target {
+  return t.SampleGrad(s, loc, ddx, ddy, int2(1, 2));
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2], int vector[2])(
+// CHECK-SAME: ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x float> {{.*}} %[[DDX:[^,]+]], <2 x float> {{.*}} %[[DDY:[^,]+]], <2 x i32> {{.*}} %[[OFFSET:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[DDX_ADDR:.*]] = alloca <2 x float>
+// CHECK: %[[DDY_ADDR:.*]] = alloca <2 x float>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x float> %[[DDX]], ptr %[[DDX_ADDR]]
+// CHECK: store <2 x float> %[[DDY]], ptr %[[DDY_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: %[[THIS_VAL2:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL2]], i32 0, i32 0
+// CHECK: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
+// CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[DDX_VAL:.*]] = load <2 x float>, ptr %[[DDX_ADDR]]
+// CHECK: %[[DDY_VAL:.*]] = load <2 x float>, ptr %[[DDY_ADDR]]
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]])
+// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]])
+
+// CHECK-LABEL: @test_clamp(float vector[3], float vector[2], float vector[2])
+// CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2], int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00)
+// CHECK: ret <4 x float> %[[CALL_CLAMP]]
+
+float4 test_clamp(float3 loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : SV_Target {
+  return t.SampleGrad(s, loc, ddx, ddy, int2(1, 2), 1.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[3], float vector[2], float vector[2], int vector[2], float)(
+// CHECK-SAME: ptr {{.*}} %[[THIS:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER:[^,]+]], <3 x float> {{.*}} %[[COORD:[^,]+]], <2 x float> {{.*}} %[[DDX:[^,]+]], <2 x float> {{.*}} %[[DDY:[^,]+]], <2 x i32> {{.*}} %[[OFFSET:[^,]+]], float {{.*}} %[[CLAMP:[^)]+]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR:.*]] = alloca <3 x float>
+// CHECK: %[[DDX_ADDR:.*]] = alloca <2 x float>
+// CHECK: %[[DDY_ADDR:.*]] = alloca <2 x float>
+// CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
+// CHECK: %[[CLAMP_ADDR:.*]] = alloca float
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x float> %[[COORD]], ptr %[[COORD_ADDR]]
+// CHECK: store <2 x float> %[[DDX]], ptr %[[DDX_ADDR]]
+// CHECK: store <2 x float> %[[DDY]], ptr %[[DDY_ADDR]]
+// CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// CHECK: store float %[[CLAMP]], ptr %[[CLAMP_ADDR]]
+// CHECK: %[[THIS_VAL3:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL3]], i32 0, i32 0
+// CHECK: %[[HANDLE3:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP3]]
+// CHECK: %[[SAMPLER_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]]
+// CHECK: %[[COORD_VAL:.*]] = load <3 x float>, ptr %[[COORD_ADDR]]
+// CHECK: %[[DDX_VAL:.*]] = load <2 x float>, ptr %[[DDX_ADDR]]
+// CHECK: %[[DDY_VAL:.*]] = load <2 x float>, ptr %[[DDY_ADDR]]
+// CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]]
+// CHECK: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]]
+// CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplegrad.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]])
+// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <3 x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]])
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleLevel.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleLevel.hlsl
new file mode 100644
index 0000000000000..d6aba2ac0f39b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-SampleLevel.hlsl
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// DXIL: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// DXIL: %"class.hlsl::SamplerState" = type { target("dx.Sampler", 0) }
+
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::SamplerState" = type { target("spirv.Sampler") }
+
+Texture2DArray<float4> t;
+SamplerState s;
+
+// CHECK-LABEL: @test_level(float vector[3], float)
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[3], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00)
+// CHECK: ret <4 x float> %[[CALL]]
+
+float4 test_level(float3 loc : LOC, float lod : LOD) : SV_Target {
+  return t.SampleLevel(s, loc, 0.0f);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[3], float)(
+// CHECK-SAME: ptr {{.*}} %[[THIS1:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER1:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD1:[^,]+]], float noundef nofpclass(nan inf) %[[LOD1:[^)]+]])
+// CHECK: %[[THIS_ADDR1:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR1:.*]] = alloca <3 x float>
+// CHECK: %[[LOD_ADDR1:.*]] = alloca float
+// CHECK: store ptr %[[THIS1]], ptr %[[THIS_ADDR1]]
+// CHECK: store <3 x float> %[[COORD1]], ptr %[[COORD_ADDR1]]
+// CHECK: store float %[[LOD1]], ptr %[[LOD_ADDR1]]
+// CHECK: %[[THIS_VAL1:.*]] = load ptr, ptr %[[THIS_ADDR1]]
+// CHECK: %[[HANDLE_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL1]], i32 0, i32 0
+// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
+// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER1]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
+// CHECK: %[[COORD_VAL1:.*]] = load <3 x float>, ptr %[[COORD_ADDR1]]
+// CHECK: %[[LOD_VAL1:.*]] = load float, ptr %[[LOD_ADDR1]]
+// CHECK: %[[LOD_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
+// DXIL: call {{.*}}                         <4 x float> @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <2 x i32> zeroinitializer)
+// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplelevel.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <3 x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <2 x i32> zeroinitializer)
+
+// CHECK-LABEL: @test_offset(float vector[3], float)
+// CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[3], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <3 x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>)
+// CHECK: ret <4 x float> %[[CALL_OFFSET]]
+
+float4 test_offset(float3 loc : LOC, float lod : LOD) : SV_Target {
+  return t.SampleLevel(s, loc, 0.0f, int2(1, 2));
+}
+
+// CHECK-LABEL: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[3], float, int vector[2])(
+// CHECK-SAME: ptr {{.*}} %[[THIS2:[^,]+]], ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}} %[[SAMPLER2:[^,]+]], <3 x float> noundef nofpclass(nan inf) %[[COORD2:[^,]+]], float noundef nofpclass(nan inf) %[[LOD2:[^,]+]], <2 x i32> noundef %[[OFFSET2:[^)]+]])
+// CHECK: %[[THIS_ADDR2:.*]] = alloca ptr
+// CHECK: %[[COORD_ADDR2:.*]] = alloca <3 x float>
+// CHECK: %[[LOD_ADDR2:.*]] = alloca float
+// CHECK: %[[OFFSET_ADDR2:.*]] = alloca <2 x i32>
+// CHECK: store ptr %[[THIS2]], ptr %[[THIS_ADDR2]]
+// CHECK: store <3 x float> %[[COORD2]], ptr %[[COORD_ADDR2]]
+// CHECK: store float %[[LOD2]], ptr %[[LOD_ADDR2]]
+// CHECK: store <2 x i32> %[[OFFSET2]], ptr %[[OFFSET_ADDR2]]
+// CHECK: %[[THIS_VAL2:.*]] = load ptr, ptr %[[THIS_ADDR2]]
+// CHECK: %[[HANDLE_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL2]], i32 0, i32 0
+// CHECK: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
+// CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER2]], i32 0, i32 0
+// CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
+// CHECK: %[[COORD_VAL2:.*]] = load <3 x float>, ptr %[[COORD_ADDR2]]
+// CHECK: %[[LOD_VAL2:.*]] = load float, ptr %[[LOD_ADDR2]]
+// CHECK: %[[LOD_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR2]]
+// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
+// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplelevel.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <3 x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <2 x i32> %[[OFFSET_VAL2]])
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-Subscript.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-Subscript.hlsl
new file mode 100644
index 0000000000000..613c36a5d9f6c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-Subscript.hlsl
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -Wno-sign-conversion -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -Wno-sign-conversion -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+Texture2DArray<float4> Tex : register(t0);
+Texture2DArray<float> Tex2 : register(t1);
+Texture2DArray<int3> Tex3 : register(t2);
+
+[numthreads(1,1,1)]
+void main(uint3 DTid : SV_DispatchThreadID) {
+  float4 val = Tex[DTid];
+  float val2 = Tex2[DTid];
+  int3 val3 = Tex3[DTid];
+}
+
+// CHECK: define hidden {{.*}}void @main(unsigned int vector[3])(<3 x i32> noundef %[[DTID:.*]])
+// CHECK: %[[DTID_ADDR:.*]] = alloca <3 x i32>
+// CHECK: %[[VAL:.*]] = alloca <4 x float>
+// CHECK: %[[VAL2:.*]] = alloca float
+// CHECK: %[[VAL3:.*]] = alloca <3 x i32>
+// CHECK: store <3 x i32> %[[DTID]], ptr %[[DTID_ADDR]]
+// CHECK: %[[DTID_VAL:.*]] = load <3 x i32>, ptr %[[DTID_ADDR]]
+// CHECK: %[[CALL1:.*]] = call noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<float vector[4]>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) @Tex, <3 x i32> noundef %[[DTID_VAL]])
+// CHECK: %[[LOAD_VAL:.*]] = load <4 x float>, ptr{{.*}} %[[CALL1]]
+// CHECK: store <4 x float> %[[LOAD_VAL]], ptr %[[VAL]]
+// CHECK: %[[DTID_VAL2:.*]] = load <3 x i32>, ptr %[[DTID_ADDR]]
+// CHECK: %[[CALL2:.*]] = call noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<float>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) @Tex2, <3 x i32> noundef %[[DTID_VAL2]])
+// CHECK: %[[LOAD_VAL2:.*]] = load float, ptr{{.*}} %[[CALL2]]
+// CHECK: store float %[[LOAD_VAL2]], ptr %[[VAL2]]
+// CHECK: %[[DTID_VAL3:.*]] = load <3 x i32>, ptr %[[DTID_ADDR]]
+// CHECK: %[[CALL3:.*]] = call noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<int vector[3]>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) @Tex3, <3 x i32> noundef %[[DTID_VAL3]])
+// CHECK: %[[LOAD_VAL3:.*]] = load <3 x i32>, ptr{{.*}} %[[CALL3]]
+// CHECK: store <3 x i32> %[[LOAD_VAL3]], ptr %[[VAL3]]
+
+// CHECK: define linkonce_odr hidden noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<float vector[4]>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %[[THIS:.*]], <3 x i32> noundef %[[INDEX:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[INDEX_ADDR:.*]] = alloca <3 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x i32> %[[INDEX]], ptr %[[INDEX_ADDR]]
+// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_PTR:.*]] = getelementptr {{.*}} %"class.hlsl::Texture2DArray", ptr %[[THIS1]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_PTR]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_PTR]]
+// CHECK: %[[INDEX_VAL:.*]] = load <3 x i32>, ptr %[[INDEX_ADDR]]
+// DXIL: %[[PTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.Texture_v4f32_0_0_0_7t.v3i32(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// SPIRV: %[[PTR:.*]] = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_1_2_1_0_1_0t.v3i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// CHECK: ret ptr {{.*}}%[[PTR]]
+
+// CHECK: define linkonce_odr hidden noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<float>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %[[THIS:.*]], <3 x i32> noundef %[[INDEX:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[INDEX_ADDR:.*]] = alloca <3 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x i32> %[[INDEX]], ptr %[[INDEX_ADDR]]
+// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_PTR:.*]] = getelementptr {{.*}} %"class.hlsl::Texture2DArray.0", ptr %[[THIS1]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", float, 0, 0, 0, 7), ptr %[[HANDLE_PTR]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_PTR]]
+// CHECK: %[[INDEX_VAL:.*]] = load <3 x i32>, ptr %[[INDEX_ADDR]]
+// DXIL: %[[PTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.Texture_f32_0_0_0_7t.v3i32(target("dx.Texture", float, 0, 0, 0, 7) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// SPIRV: %[[PTR:.*]] = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_1_2_1_0_1_0t.v3i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// CHECK: ret ptr {{.*}}%[[PTR]]
+
+// CHECK: define linkonce_odr hidden noundef {{.*}}ptr{{.*}} @hlsl::Texture2DArray<int vector[3]>::operator[](unsigned int vector[3]) const(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %[[THIS:.*]], <3 x i32> noundef %[[INDEX:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+// CHECK: %[[INDEX_ADDR:.*]] = alloca <3 x i32>
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// CHECK: store <3 x i32> %[[INDEX]], ptr %[[INDEX_ADDR]]
+// CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[HANDLE_PTR:.*]] = getelementptr {{.*}} %"class.hlsl::Texture2DArray{{.*}}", ptr %[[THIS1]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <3 x i32>, 0, 0, 1, 7), ptr %[[HANDLE_PTR]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_PTR]]
+// CHECK: %[[INDEX_VAL:.*]] = load <3 x i32>, ptr %[[INDEX_ADDR]]
+// DXIL: %[[PTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.Texture_v3i32_0_0_1_7t.v3i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 7) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// SPIRV: %[[PTR:.*]] = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_1_2_1_0_1_0t.v3i32(target("spirv.SignedImage", i32, 1, 2, 1, 0, 1, 0) %[[HANDLE]], <3 x i32> %[[INDEX_VAL]])
+// CHECK: ret ptr {{.*}}%[[PTR]]
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-default-explicit-binding.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-default-explicit-binding.hlsl
new file mode 100644
index 0000000000000..71e2881420592
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-default-explicit-binding.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=SPIRV
+
+SamplerState g_s : register(s0);
+Texture2DArray<> default_template : register(t1, space2);
+Texture2DArray implicit_template : register(t0, space1);
+
+// CHECK: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// SPIRV: %"class.hlsl::Texture2DArray" = type { target("spirv.Image", float, 1, 2, 1, 0, 1, 0), %"struct.hlsl::Texture2DArray<>::mips_type" }
+
+// CHECK: @{{.*}}default_template = internal global %"class.hlsl::Texture2DArray" poison, align {{[0-9]+}}
+// CHECK: @{{.*}}implicit_template = internal global %"class.hlsl::Texture2DArray" poison, align {{[0-9]+}}
+// SPIRV: @{{.*}}default_template = internal global %"class.hlsl::Texture2DArray" poison, align {{[0-9]+}}
+// SPIRV: @{{.*}}implicit_template = internal global %"class.hlsl::Texture2DArray" poison, align {{[0-9]+}}
+
+[shader("pixel")]
+float4 main(float3 uv : TEXCOORD) : SV_Target {
+  return implicit_template.Sample(g_s, uv) + default_template.Sample(g_s, uv);
+}
+
+// CHECK: call void @{{.*}}__createFromBinding{{.*}}(ptr {{.*}}@{{.*}}default_template, i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @{{.*}})
+// CHECK: call void @{{.*}}__createFromBinding{{.*}}(ptr {{.*}}@{{.*}}implicit_template, i32 noundef 0, i32 noundef 1, i32 noundef 1, i32 noundef 0, ptr noundef @{{.*}})
+// SPIRV: call void @{{.*}}__createFromBinding{{.*}}(ptr {{.*}}@{{.*}}default_template, i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @{{.*}})
+// SPIRV: call void @{{.*}}__createFromBinding{{.*}}(ptr {{.*}}@{{.*}}implicit_template, i32 noundef 0, i32 noundef 1, i32 noundef 1, i32 noundef 0, ptr noundef @{{.*}})
+// CHECK: define void @main()
+// SPIRV: define void @main()
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-default.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-default.hlsl
new file mode 100644
index 0000000000000..ccbd580cba3d4
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-default.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -std=hlsl202x -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | FileCheck %s
+
+// CHECK: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+// CHECK: %"class.hlsl::Texture2DArray.0" = type { target("dx.Texture", float, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<float>::mips_type" }
+
+// CHECK: @{{.*}}t1 = internal global %"class.hlsl::Texture2DArray" poison, align 4
+Texture2DArray<> t1;
+
+// CHECK: @{{.*}}t2 = internal global %"class.hlsl::Texture2DArray.0" poison, align 4
+Texture2DArray<float> t2;
+
+// CHECK: @{{.*}}t3 = internal global %"class.hlsl::Texture2DArray" poison, align 4
+Texture2DArray t3;
+
+void main() {
+}
diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-shorthand-contexts.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-shorthand-contexts.hlsl
new file mode 100644
index 0000000000000..78ba7f699000f
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Texture2DArray-shorthand-contexts.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
+
+// CHECK: %"class.hlsl::Texture2DArray" = type { target("dx.Texture", <4 x float>, 0, 0, 0, 7), %"struct.hlsl::Texture2DArray<>::mips_type" }
+
+SamplerState g_s : register(s0);
+
+struct S {
+  Texture2DArray tex;
+};
+
+// CHECK: define {{.*}}void @use_struct(S)(ptr noundef {{.*}}%s)
+void use_struct(S s) {
+  // CHECK: call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3])
+  float4 val = s.tex.Sample(g_s, float3(0.5, 0.5, 0.1));
+}
+
+// CHECK: define {{.*}}void @use_param(hlsl::Texture2DArray<float vector[4]>)(ptr noundef {{.*}}%p)
+void use_param(Texture2DArray p) {
+  // CHECK: call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3])
+  float4 val = p.Sample(g_s, float3(0.5, 0.5, 0.1));
+}
+
+[shader("pixel")]
+float4 main() : SV_Target {
+  // CHECK: %local = alloca %"class.hlsl::Texture2DArray"
+  Texture2DArray local;
+  // CHECK: call {{.*}} <4 x float> @hlsl::Texture2DArray<float vector[4]>::Sample(hlsl::SamplerState, float vector[3])
+  return local.Sample(g_s, float3(0.5, 0.5, 0.1));
+}
+
+// CHECK: declare <4 x float> @llvm.dx.resource.sample.v4f32
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-CalculateLevelOfDetail.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-CalculateLevelOfDetail.hlsl
new file mode 100644
index 0000000000000..9d26af51a120b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-CalculateLevelOfDetail.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
+
+Texture2DArray<float4> tex;
+SamplerState samp;
+
+void main() {
+  float2 loc = float2(0, 0);
+
+  tex.CalculateLevelOfDetail(samp, loc);
+  tex.CalculateLevelOfDetailUnclamped(samp, loc);
+
+  // expected-error at +2 {{too few arguments to function call, expected 2, have 1}}
+  // expected-note@* {{'CalculateLevelOfDetail' declared here}}
+  tex.CalculateLevelOfDetail(samp);
+
+  // expected-error at +2 {{too few arguments to function call, expected 2, have 1}}
+  // expected-note@* {{'CalculateLevelOfDetailUnclamped' declared here}}
+  tex.CalculateLevelOfDetailUnclamped(samp);
+
+  // expected-error at +2 {{too many arguments to function call, expected 2, have 3}}
+  // expected-note@* {{'CalculateLevelOfDetail' declared here}}
+  tex.CalculateLevelOfDetail(samp, loc, 0);
+
+  // expected-error at +2{{too many arguments to function call, expected 2, have 3}}
+  // expected-note@* {{'CalculateLevelOfDetailUnclamped' declared here}}
+  tex.CalculateLevelOfDetailUnclamped(samp, loc, 0);
+
+  // expected-error at +1 {{cannot initialize a parameter of type 'vector<float, 2>' (vector of 2 'float' values) with an lvalue of type 'const char[8]'}}
+  tex.CalculateLevelOfDetail(samp, "invalid");
+
+  // expected-error at +1 {{cannot initialize a parameter of type 'vector<float, 2>' (vector of 2 'float' values) with an lvalue of type 'const char[8]'}}
+  tex.CalculateLevelOfDetailUnclamped(samp, "invalid");
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-GetDimensions.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-GetDimensions.hlsl
new file mode 100644
index 0000000000000..21f69d4fe837f
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-GetDimensions.hlsl
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
+
+Texture2DArray<float4> tex;
+
+void main() {
+  uint u_w, u_h, u_l;
+  float f_w, f_h, f_l;
+
+  // Valid calls
+  tex.GetDimensions(u_w, u_h);
+  tex.GetDimensions(0, u_w, u_h, u_l);
+  tex.GetDimensions(f_w, f_h);
+  tex.GetDimensions(0, f_w, f_h, f_l);
+
+  // Invalid number of arguments
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions();
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 0 were provided}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 0 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(u_w);
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 1 was provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(u_w, u_h, u_l);
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(0, u_w, u_h, u_l, 0);
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 5 were provided}}
+
+  // Invalid types
+  int i_w, i_h;
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(i_w, i_h);
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'unsigned int &__restrict' for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'float &__restrict' for 1st argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(u_w, i_h);
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'unsigned int &__restrict' for 2nd argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 1st argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+
+  // Invalid lvalues
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(0u, u_h);
+  // expected-note@*:* {{candidate function not viable: expects an lvalue for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'unsigned int' to 'float &__restrict' for 1st argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(u_w, 0u);
+  // expected-note@*:* {{candidate function not viable: expects an lvalue for 2nd argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 1st argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(0, 0u, u_h, u_l);
+  // expected-note@*:* {{candidate function not viable: expects an lvalue for 2nd argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'unsigned int' to 'float &__restrict' for 2nd argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(0, u_w, 0u, u_l);
+  // expected-note@*:* {{candidate function not viable: expects an lvalue for 3rd argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 2nd argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
+
+  // expected-error at +1 {{no matching member function for call to 'GetDimensions'}}
+  tex.GetDimensions(0, u_w, u_h, 0u);
+  // expected-note@*:* {{candidate function not viable: expects an lvalue for 4th argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 2nd argument}}
+  // expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-SampleBias.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleBias.hlsl
new file mode 100644
index 0000000000000..53d2d417f8dfb
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleBias.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
+
+Texture2DArray<float4> tex;
+SamplerState samp;
+
+void main() {
+  float3 loc = float3(0, 0, 0);
+  float bias = 0;
+  int2 offset = int2(0, 0);
+  float clamp = 0;
+
+  tex.SampleBias(samp, loc, bias);
+  tex.SampleBias(samp, loc, bias, offset);
+  tex.SampleBias(samp, loc, bias, offset, clamp);
+
+  // Too few arguments.
+  tex.SampleBias(samp, loc); // expected-error {{no matching member function for call to 'SampleBias'}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 2 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 2 were provided}}
+
+  // Too many arguments.
+  tex.SampleBias(samp, loc, bias, offset, clamp, 0); // expected-error {{no matching member function for call to 'SampleBias'}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 6 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 6 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 6 were provided}}
+
+  // Invalid argument types.
+  tex.SampleBias(samp, loc, bias, offset, "invalid"); // expected-error {{no matching member function for call to 'SampleBias'}}
+  // expected-note@*:* {{no known conversion from 'const char[8]' to 'float' for 5th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 5 were provided}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmp.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmp.hlsl
new file mode 100644
index 0000000000000..50e6ff5142e04
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmp.hlsl
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -fsyntax-only -finclude-default-header -verify %s
+
+
+Texture2DArray<float4> t;
+Texture2DArray<int4> t_int;
+SamplerComparisonState s;
+SamplerState s2;
+
+void main(float3 loc, float cmp) {
+  t.SampleCmp(s, loc, cmp);
+  t.SampleCmp(s, loc, cmp, int2(1, 2));
+  t.SampleCmp(s, loc, cmp, int2(1, 2), 1.0f);
+
+  // expected-error@* {{'SampleCmp' and 'SampleCmpLevelZero' require resource to contain a floating point type}}
+  // expected-note@*:* {{in instantiation of member function 'hlsl::Texture2DArray<vector<int, 4>>::SampleCmp' requested here}}
+  t_int.SampleCmp(s, loc, cmp);
+
+  // expected-error at +4 {{no matching member function for call to 'SampleCmp'}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 1 was provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 1 was provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 1 was provided}}
+  t.SampleCmp(loc);
+
+  // expected-error at +4 {{no matching member function for call to 'SampleCmp'}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 6 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 6 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 6 were provided}}
+  t.SampleCmp(s, loc, cmp, int2(1, 2), 1.0f, 1.0f);
+
+  // expected-error at +4 {{no matching member function for call to 'SampleCmp'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerState' to 'hlsl::SamplerComparisonState' for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 3 were provided}}
+  t.SampleCmp(s2, loc, cmp);
+
+  // expected-error at +4 {{no matching member function for call to 'SampleCmp'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerComparisonState' to 'vector<int, 2>' (vector of 2 'int' values) for 4th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 4 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 4 were provided}}
+  t.SampleCmp(s, loc, cmp, s);
+
+  // expected-error at +4 {{no matching member function for call to 'SampleCmp'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerComparisonState' to 'float' for 5th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 5 were provided}}
+  t.SampleCmp(s, loc, cmp, int2(1, 2), s);
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmpLevelZero.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmpLevelZero.hlsl
new file mode 100644
index 0000000000000..6908b9fb85b1f
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmpLevelZero.hlsl
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -fsyntax-only -finclude-default-header -verify %s
+
+// expected-error@* {{'SampleCmp' and 'SampleCmpLevelZero' require resource to contain a floating point type}}
+
+Texture2DArray<float4> t;
+Texture2DArray<int4> t_int;
+SamplerComparisonState s;
+SamplerState s2;
+
+void main(float3 loc, float cmp) {
+  t.SampleCmpLevelZero(s, loc, cmp);
+  t.SampleCmpLevelZero(s, loc, cmp, int2(1, 2));
+
+  // expected-note@*:* {{in instantiation of member function 'hlsl::Texture2DArray<vector<int, 4>>::SampleCmpLevelZero' requested here}}
+  t_int.SampleCmpLevelZero(s, loc, cmp);
+
+  // expected-error at +3 {{no matching member function for call to 'SampleCmpLevelZero'}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 1 was provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 1 was provided}}
+  t.SampleCmpLevelZero(loc);
+
+  // expected-error at +3 {{no matching member function for call to 'SampleCmpLevelZero'}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 5 were provided}}
+  t.SampleCmpLevelZero(s, loc, cmp, int2(1, 2), 1.0f);
+
+  // expected-error at +3 {{no matching member function for call to 'SampleCmpLevelZero'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerState' to 'hlsl::SamplerComparisonState' for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+  t.SampleCmpLevelZero(s2, loc, cmp);
+
+  // expected-error at +3 {{no matching member function for call to 'SampleCmpLevelZero'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerComparisonState' to 'vector<int, 2>' (vector of 2 'int' values) for 4th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 4 were provided}}
+  t.SampleCmpLevelZero(s, loc, cmp, s);
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-SampleGrad.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleGrad.hlsl
new file mode 100644
index 0000000000000..36f6564473a2c
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleGrad.hlsl
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
+
+Texture2DArray<float4> tex;
+SamplerState samp;
+
+void main() {
+  float3 loc = float3(0, 0, 0);
+  float2 ddx = float2(0, 0);
+  float2 ddy = float2(0, 0);
+  int2 offset = int2(0, 0);
+  float clamp = 0;
+
+  tex.SampleGrad(samp, loc, ddx, ddy);
+  tex.SampleGrad(samp, loc, ddx, ddy, offset);
+  tex.SampleGrad(samp, loc, ddx, ddy, offset, clamp);
+
+  // Too few arguments.
+  tex.SampleGrad(samp, loc, ddx); // expected-error {{no matching member function for call to 'SampleGrad'}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 3 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 6 arguments, but 3 were provided}}
+
+  // Too many arguments.
+  tex.SampleGrad(samp, loc, ddx, ddy, offset, clamp, 0); // expected-error {{no matching member function for call to 'SampleGrad'}}
+  // expected-note@*:* {{candidate function not viable: requires 6 arguments, but 7 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 7 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 7 were provided}}
+
+  // Invalid argument types.
+  tex.SampleGrad(samp, loc, ddx, ddy, offset, "invalid"); // expected-error {{no matching member function for call to 'SampleGrad'}}
+  // expected-note@*:* {{no known conversion from 'const char[8]' to 'float' for 6th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 5 arguments, but 6 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 6 were provided}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-SampleLevel.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleLevel.hlsl
new file mode 100644
index 0000000000000..c62eccdb7688e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-SampleLevel.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
+
+Texture2DArray<float4> tex;
+SamplerState samp;
+
+void main() {
+  float3 loc = float3(0, 0, 0);
+  float lod = 0;
+  int2 offset = int2(0, 0);
+
+  tex.SampleLevel(samp, loc, lod);
+  tex.SampleLevel(samp, loc, lod, offset);
+
+  // Too few arguments.
+  tex.SampleLevel(samp, loc); // expected-error {{no matching member function for call to 'SampleLevel'}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 2 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 2 were provided}}
+
+  // Too many arguments.
+  tex.SampleLevel(samp, loc, lod, offset, 0); // expected-error {{no matching member function for call to 'SampleLevel'}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 5 were provided}}
+
+  // Invalid argument types.
+  tex.SampleLevel(samp, loc, "invalid"); // expected-error {{no matching member function for call to 'SampleLevel'}}
+  // expected-note@*:* {{no known conversion from 'const char[8]' to 'float' for 3rd argument}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-Sema.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-Sema.hlsl
new file mode 100644
index 0000000000000..8d0dda855eab4
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-Sema.hlsl
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -fsyntax-only -finclude-default-header -verify %s
+
+Texture2DArray<float4> t;
+SamplerState s;
+
+void main(float3 loc) {
+  t.Sample(s, loc);
+  t.Sample(s, loc, int2(1, 2));
+
+  // expected-error at +4 {{no matching member function for call to 'Sample'}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 1 was provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 1 was provided}}
+  t.Sample(loc);
+
+  t.Sample(s, loc, int2(1, 2), 1.0);
+
+  // expected-error at +4 {{no matching member function for call to 'Sample'}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 5 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 5 were provided}}
+  t.Sample(s, loc, int2(1, 2), 1.0, 1.0);
+
+  // expected-error at +4 {{no matching member function for call to 'Sample'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerState' to 'vector<int, 2>' (vector of 2 'int' values) for 3rd argument}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 4 arguments, but 3 were provided}}
+  t.Sample(s, loc, s);
+
+  // expected-error at +4 {{no matching member function for call to 'Sample'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'SamplerState' to 'float' for 4th argument}}
+  // expected-note@*:* {{candidate function not viable: requires 3 arguments, but 4 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 4 were provided}}
+  t.Sample(s, loc, int2(1, 2), s);
+
+  // Test with wrong coordinate dimension.
+  // Note: float implicitly converts to float3 (splat), so no error here.
+  t.Sample(s, loc.x);
+
+  // Test with wrong offset dimension.
+  // Note: int implicitly converts to int2 (splat), so no error here.
+  t.Sample(s, loc, 1);
+}
diff --git a/clang/test/SemaHLSL/Resources/Texture2DArray-Subscript.hlsl b/clang/test/SemaHLSL/Resources/Texture2DArray-Subscript.hlsl
new file mode 100644
index 0000000000000..addb46275dc31
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Texture2DArray-Subscript.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify -o - %s
+
+Texture2DArray<float4> Tex;
+
+struct S { int a; };
+
+void main() {
+  uint3 valid_index = uint3(1, 2, 0);
+  float4 val1 = Tex[valid_index]; // OK
+
+  S s = { 1 };
+  // expected-error at +2 {{no viable overloaded operator[] for type 'Texture2DArray<float4>'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'S' to 'vector<unsigned int, 3>'}}
+  float4 val2 = Tex[s];
+
+  int i = 1;
+  float4 val3 = Tex[i]; // expected-warning {{implicit conversion changes signedness: 'int' to 'vector<unsigned int, 3>' (vector of 3 'unsigned int' values)}}
+
+  int4 i4 = int4(1, 2, 3, 4);
+  // expected-warning at +2 {{implicit conversion truncates vector: 'int4' (aka 'vector<int, 4>') to 'vector<unsigned int, 3>' (vector of 3 'unsigned int' values)}}
+  // expected-warning at +1 {{implicit conversion changes signedness: 'int4' (aka 'vector<int, 4>') to 'vector<unsigned int, 3>' (vector of 3 'unsigned int' values)}}
+  float4 val4 = Tex[i4];
+
+  uint2 too_few = uint2(1, 2);
+  // expected-error at +2 {{no viable overloaded operator[] for type 'Texture2DArray<float4>'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'uint2' (aka 'vector<uint, 2>') to 'vector<unsigned int, 3>'}}
+  float4 val5 = Tex[too_few];
+}
diff --git a/clang/test/SemaHLSL/Texture2DArray-Gather.hlsl b/clang/test/SemaHLSL/Texture2DArray-Gather.hlsl
new file mode 100644
index 0000000000000..9adcb4d8f22e7
--- /dev/null
+++ b/clang/test/SemaHLSL/Texture2DArray-Gather.hlsl
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -fsyntax-only -verify -finclude-default-header %s
+
+Texture2DArray<float4> Tex;
+SamplerState Samp;
+SamplerComparisonState SampCmp;
+
+void main() {
+  float3 uv = float3(0.5, 0.5, 0.0);
+  int2 offset = int2(1, 1);
+  float compare = 0.5;
+
+  // Gather
+  // Expected: Gather(SamplerState, float3, [int2])
+  Tex.Gather(Samp, uv);
+  Tex.Gather(Samp, uv, offset);
+
+  // Invalid Overloads
+  Tex.Gather(Samp); // expected-error {{no matching member function for call to 'Gather'}}
+  Tex.Gather(Samp, uv, offset, 1); // expected-error {{no matching member function for call to 'Gather'}}
+
+  // Gather variants
+  Tex.GatherRed(Samp, uv);
+  Tex.GatherGreen(Samp, uv, offset);
+  Tex.GatherBlue(Samp, uv);
+  Tex.GatherAlpha(Samp, uv, offset);
+
+  // GatherCmp
+  // Expected: GatherCmp(SamplerComparisonState, float3, float, [int2])
+  Tex.GatherCmp(SampCmp, uv, compare);
+  Tex.GatherCmp(SampCmp, uv, compare, offset);
+
+  // Invalid Overloads
+  Tex.GatherCmp(SampCmp, uv); // expected-error {{no matching member function for call to 'GatherCmp'}}
+  Tex.GatherCmp(SampCmp, uv, compare, offset, 1); // expected-error {{no matching member function for call to 'GatherCmp'}}
+
+  // GatherCmp variants
+  Tex.GatherCmpRed(SampCmp, uv, compare);
+  Tex.GatherCmpGreen(SampCmp, uv, compare);
+  Tex.GatherCmpBlue(SampCmp, uv, compare, offset);
+  Tex.GatherCmpAlpha(SampCmp, uv, compare);
+
+  // Type checks
+  // Offset must be int2 (SamplerState fails)
+  Tex.Gather(Samp, uv, Samp); // expected-error {{no matching member function for call to 'Gather'}}
+
+  // Compare value must be scalar float
+  Tex.GatherCmp(SampCmp, uv, Samp); // expected-error {{no matching member function for call to 'GatherCmp'}}
+}
+
+// expected-note@* 0+{{candidate function not viable}}
diff --git a/clang/test/SemaHLSL/Texture2DArray-GatherCmp-Vulkan.hlsl b/clang/test/SemaHLSL/Texture2DArray-GatherCmp-Vulkan.hlsl
new file mode 100644
index 0000000000000..e8a9a64ef473e
--- /dev/null
+++ b/clang/test/SemaHLSL/Texture2DArray-GatherCmp-Vulkan.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -fsyntax-only -verify -finclude-default-header %s
+
+Texture2DArray<float4> Tex;
+SamplerComparisonState SampCmp;
+
+void main() {
+  float3 uv = float3(0.5, 0.5, 0.0);
+  float compare = 0.5;
+
+  Tex.GatherCmp(SampCmp, uv, compare);
+  Tex.GatherCmpRed(SampCmp, uv, compare);
+
+  // expected-error@* {{gatherCmpGreen operations on the Vulkan target are not supported; only GatherCmp and GatherCmpRed are allowed}}
+  Tex.GatherCmpGreen(SampCmp, uv, compare);
+
+  // expected-error@* {{gatherCmpBlue operations on the Vulkan target are not supported; only GatherCmp and GatherCmpRed are allowed}}
+  Tex.GatherCmpBlue(SampCmp, uv, compare);
+
+  // expected-error@* {{gatherCmpAlpha operations on the Vulkan target are not supported; only GatherCmp and GatherCmpRed are allowed}}
+  Tex.GatherCmpAlpha(SampCmp, uv, compare);
+}
+
+// expected-note@* 0+{{in instantiation of member function}}
diff --git a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl b/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
new file mode 100644
index 0000000000000..36427aab0e604
--- /dev/null
+++ b/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify %s
+
+Texture2DArray<float4> t;
+
+float4 test_too_few_args() {
+  return t.Load(); // expected-error {{no matching member function for call to 'Load'}}
+  // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but no arguments were provided}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 0 were provided}}
+}
+
+float4 test_too_many_args(int3 loc) {
+  return t.Load(int4(loc, 0), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but 3 arguments were provided}}
+}
+
+float4 test_invalid_coord_type(float3 loc) {
+  return t.Load(float4(loc, 0)); // expected-warning {{implicit conversion turns floating-point number into integer: 'float4' (aka 'vector<float, 4>') to 'vector<int, 4>'}}
+}
+
+float4 test_invalid_offset_type(int3 loc, float2 offset) {
+  return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector<float, 2>') to 'vector<int, 2>'}}
+}
+
+float4 test_invalid_location_count(int2 loc) {
+  return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector<int, 2>') to 'vector<int, 4>' (vector of 4 'int' values) for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+}
+
+float4 test_short_location_count(int3 loc) {
+  return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}}
+  // expected-note@*:* {{candidate function not viable: no known conversion from 'int3' (aka 'vector<int, 3>') to 'vector<int, 4>' (vector of 4 'int' values) for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+}
+
+float4 test_splatted_offset_count(int4 loc, int offset) {
+  // No errors expected. The vector will be generated by splatting `offset`.
+  return t.Load(loc, offset);
+}
+
+float4 test_truncated_offset_count(int3 loc, int3 offset) {
+  return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector<int, 3>') to 'vector<int, 2>' (vector of 2 'int' values)}}
+}
diff --git a/clang/test/SemaHLSL/Texture2DArray-mips-errors.hlsl b/clang/test/SemaHLSL/Texture2DArray-mips-errors.hlsl
new file mode 100644
index 0000000000000..c9a988a1a0537
--- /dev/null
+++ b/clang/test/SemaHLSL/Texture2DArray-mips-errors.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm-only -disable-llvm-passes -finclude-default-header -verify %s
+
+Texture2DArray<float4> t;
+
+template<class T>
+float4 foo(T t) {
+  int3 c = {0, 0, 0};
+  return t[c];
+}
+
+[shader("pixel")]
+float4 test_mips() : SV_Target {
+  // expected-error at +4 {{'mips_type' is a private member of 'hlsl::Texture2DArray<>'}}
+  // expected-note@*:* {{implicitly declared private here}}
+  // expected-error at +2 {{calling a protected constructor of class 'hlsl::Texture2DArray<>::mips_type'}}
+  // expected-note@*:* {{implicitly declared protected here}}
+  Texture2DArray<float4>::mips_type a;
+
+  // expected-error at +4 {{'mips_slice_type' is a private member of 'hlsl::Texture2DArray<>'}}
+  // expected-note@*:* {{implicitly declared private here}}
+  // expected-error at +2 {{calling a protected constructor of class 'hlsl::Texture2DArray<>::mips_slice_type'}}
+  // expected-note@*:* {{implicitly declared protected here}}
+  Texture2DArray<float4>::mips_slice_type b;
+
+  // expected-warning at +3 {{'auto' type specifier is a HLSL 202y extension}}
+  // expected-error at +2 {{calling a protected constructor of class 'hlsl::Texture2DArray<>::mips_type'}}
+  // expected-note@*:* {{implicitly declared protected here}}
+  auto c = t.mips;
+
+  // expected-error at +2 {{calling a protected constructor of class 'hlsl::Texture2DArray<>::mips_slice_type'}}
+  // expected-note@*:* {{implicitly declared protected here}}
+  return t.mips[0][int3(0, 0, 0)] + foo(t.mips[0]);
+}
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
new file mode 100644
index 0000000000000..0bb17a2f0f836
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
@@ -0,0 +1,109 @@
+; RUN: opt -S -dxil-op-lower %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel6.6-pixel"
+
+declare void @use_float4(<4 x float>)
+
+; Test SampleBias on a Texture2DArray with float4 result.
+; CHECK-LABEL: define void @samplebias_texture2darray_float4(
+define void @samplebias_texture2darray_float4(<3 x float> %coords, float %bias) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[COORD0:.*]] = extractelement <3 x float> %coords, i64 0
+  ; CHECK: %[[COORD1:.*]] = extractelement <3 x float> %coords, i64 1
+  ; CHECK: %[[COORD2:.*]] = extractelement <3 x float> %coords, i64 2
+  ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
+  ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %bias,
+  ; CHECK-SAME: float undef)
+  %data = call <4 x float>
+      @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, float %bias, <2 x i32> zeroinitializer)
+
+  ; CHECK: extractvalue %dx.types.ResRet.f32 %[[SAMPLE]], 0
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+; Test SampleBias with constant non-zero offsets on a Texture2DArray.
+; CHECK-LABEL: define void @samplebias_texture2darray_with_offset(
+define void @samplebias_texture2darray_with_offset(<3 x float> %coords, float %bias) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[COORD0:.*]] = extractelement <3 x float> %coords, i64 0
+  ; CHECK: %[[COORD1:.*]] = extractelement <3 x float> %coords, i64 1
+  ; CHECK: %[[COORD2:.*]] = extractelement <3 x float> %coords, i64 2
+  ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
+  ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %bias,
+  ; CHECK-SAME: float undef)
+  %data = call <4 x float>
+      @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, float %bias, <2 x i32> <i32 1, i32 -2>)
+
+  ; CHECK: extractvalue %dx.types.ResRet.f32 %[[SAMPLE]], 0
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+; Test SampleBias with clamp on a Texture2DArray.
+; CHECK-LABEL: define void @samplebias_texture2darray_with_clamp(
+define void @samplebias_texture2darray_with_clamp(<3 x float> %coords, float %bias, float %clamp) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
+  ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %bias,
+  ; CHECK-SAME: float %clamp)
+  %data = call <4 x float>
+      @llvm.dx.resource.samplebias.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, float %bias, <2 x i32> zeroinitializer, float %clamp)
+
+  ; CHECK: extractvalue %dx.types.ResRet.f32 %[[SAMPLE]], 0
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
+declare target("dx.Sampler", 0)
+    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
+declare <4 x float>
+    @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
+        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>)
+declare <4 x float>
+    @llvm.dx.resource.samplebias.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
+        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>, float)
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
new file mode 100644
index 0000000000000..106b6c2d8bc92
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
@@ -0,0 +1,81 @@
+; RUN: opt -S -dxil-op-lower %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel6.6-pixel"
+
+declare void @use_float4(<4 x float>)
+
+; Test basic SampleGrad on a Texture2DArray with float4 result.
+; CHECK-LABEL: define void @samplegrad_texture2darray_float4(
+define void @samplegrad_texture2darray_float4(<3 x float> %coords, <2 x float> %ddx, <2 x float> %ddy) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[COORD0:.*]] = extractelement <3 x float> %coords, i64 0
+  ; CHECK: %[[COORD1:.*]] = extractelement <3 x float> %coords, i64 1
+  ; CHECK: %[[COORD2:.*]] = extractelement <3 x float> %coords, i64 2
+  ; CHECK: %[[DDX0:.*]] = extractelement <2 x float> %ddx, i64 0
+  ; CHECK: %[[DDX1:.*]] = extractelement <2 x float> %ddx, i64 1
+  ; CHECK: %[[DDY0:.*]] = extractelement <2 x float> %ddy, i64 0
+  ; CHECK: %[[DDY1:.*]] = extractelement <2 x float> %ddy, i64 1
+  ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
+  ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
+  %data = call <4 x float>
+      @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, <2 x float> %ddx, <2 x float> %ddy,
+          <2 x i32> zeroinitializer)
+
+  ; CHECK: extractvalue %dx.types.ResRet.f32 %[[SAMPLE]], 0
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+; Test SampleGrad with constant non-zero offsets on a Texture2DArray.
+; CHECK-LABEL: define void @samplegrad_texture2darray_with_offset(
+define void @samplegrad_texture2darray_with_offset(<3 x float> %coords, <2 x float> %ddx, <2 x float> %ddy) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
+  ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: float undef)
+  %data = call <4 x float>
+      @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, <2 x float> %ddx, <2 x float> %ddy,
+          <2 x i32> <i32 1, i32 -2>)
+
+  ; CHECK: extractvalue %dx.types.ResRet.f32 %[[SAMPLE]], 0
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
+declare target("dx.Sampler", 0)
+    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
+declare <4 x float>
+    @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
+        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
+        target("dx.Sampler", 0), <3 x float>, <2 x float>, <2 x float>, <2 x i32>)
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
new file mode 100644
index 0000000000000..9cd17381d2e39
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S -passes=dxil-translate-metadata,dxil-op-lower %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel6.6-pixel"
+
+declare void @use_float4(<4 x float>)
+
+; Test that a Texture2DArray handle gets ResourceKind::Texture2DArray metadata.
+; CHECK-LABEL: define void @annotate_texture2darray_float4(
+define void @annotate_texture2darray_float4(<3 x float> %coords, float %bias) {
+  %texture = call target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+      @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(
+          i32 0, i32 5, i32 1, i32 0, ptr null)
+  %sampler = call target("dx.Sampler", 0)
+      @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(
+          i32 0, i32 0, i32 1, i32 0, ptr null)
+
+  ; CHECK: %[[TEX:.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 5, i32 5, i32 0, i8 0 }, i32 5, i1 false)
+  ; CHECK: %[[TEX_ANNOT:.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %[[TEX]], %dx.types.ResourceProperties { i32 7, i32 1033 })
+  ; CHECK: call %dx.types.ResRet.f32 @dx.op.sampleBias.f32(i32 61, %dx.types.Handle %[[TEX_ANNOT]]
+  %data = call <4 x float>
+      @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+          target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
+          target("dx.Sampler", 0) %sampler,
+          <3 x float> %coords, float %bias, <2 x i32> zeroinitializer)
+
+  call void @use_float4(<4 x float> %data)
+  ret void
+}
+
+declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
+    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
+declare target("dx.Sampler", 0)
+    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
+declare <4 x float>
+    @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
+        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
+        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
new file mode 100644
index 0000000000000..533cf2e07a538
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
@@ -0,0 +1,44 @@
+; RUN: llc -O0 -mtriple=spirv-vulkan1.3-compute %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan1.3-compute %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Shader
+
+; CHECK-DAG: %[[float:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[v4float:[0-9]+]] = OpTypeVector %[[float]] 4
+; CHECK-DAG: %[[image:[0-9]+]] = OpTypeImage %[[float]] 2D 2 1 0 1 Unknown
+; CHECK-DAG: %[[sampled_image:[0-9]+]] = OpTypeSampledImage %[[image]]
+; CHECK-DAG: %[[sampler:[0-9]+]] = OpTypeSampler
+; CHECK-DAG: %[[v3float:[0-9]+]] = OpTypeVector %[[float]] 3
+; CHECK-DAG: %[[int:[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: %[[v2int:[0-9]+]] = OpTypeVector %[[int]] 2
+; CHECK-DAG: %[[coord:[0-9]+]] = OpConstantNull %[[v3float]]
+; CHECK-DAG: %[[component0:[0-9]+]] = OpConstant %[[int]] 0
+; CHECK-DAG: %[[const1:[0-9]+]] = OpConstant %[[int]] 1
+; CHECK-DAG: %[[offset:[0-9]+]] = OpConstantComposite %[[v2int]] %[[const1]] %[[const1]]
+
+ at .str = private unnamed_addr constant [4 x i8] c"img\00", align 1
+ at .str.1 = private unnamed_addr constant [5 x i8] c"samp\00", align 1
+
+define void @main() {
+entry:
+  %img = tail call target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32 0, i32 0, i32 1, i32 0, ptr @.str)
+  %sampler = tail call target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32 0, i32 1, i32 1, i32 0, ptr @.str.1)
+
+; CHECK-DAG: %[[img_val:[0-9]+]] = OpLoad %[[image]] %[[image_var:[0-9]+]]
+; CHECK-DAG: %[[sampler_val:[0-9]+]] = OpLoad %[[sampler]] %[[sampler_var:[0-9]+]]
+; CHECK: %[[si:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val]] %[[sampler_val]]
+; CHECK: %[[res0:[0-9]+]] = OpImageGather %[[v4float]] %[[si]] %[[coord]] %[[component0]]
+  %res0 = call <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> zeroinitializer, i32 0, <2 x i32> zeroinitializer)
+
+; CHECK: %[[img_val2:[0-9]+]] = OpLoad %[[image]] %[[image_var]]
+; CHECK: %[[sampler_val2:[0-9]+]] = OpLoad %[[sampler]] %[[sampler_var]]
+; CHECK: %[[si2:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val2]] %[[sampler_val2]]
+; CHECK: %[[res1:[0-9]+]] = OpImageGather %[[v4float]] %[[si2]] %[[coord]] %[[const1]] ConstOffset %[[offset]]
+  %res1 = call <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> zeroinitializer, i32 1, <2 x i32> <i32 1, i32 1>)
+
+  ret void
+}
+
+declare target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32, i32, i32, i32, ptr)
+declare target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32, i32, i32, i32, ptr)
+declare <4 x float> @llvm.spv.resource.gather.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0), target("spirv.Sampler"), <3 x float>, i32, <2 x i32>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/LoadLevel2DArray.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/LoadLevel2DArray.ll
new file mode 100644
index 0000000000000..9f2cc2c3cfefd
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/LoadLevel2DArray.ll
@@ -0,0 +1,41 @@
+; RUN: llc -O0 -mtriple=spirv1.6-vulkan1.3-compute %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-vulkan1.3-compute %s -o - -filetype=obj | spirv-val --allow-offset-texture-operand --target-env vulkan1.3 %}
+
+; CHECK-DAG: OpCapability Shader
+
+; CHECK-DAG: %[[float:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[v4float:[0-9]+]] = OpTypeVector %[[float]] 4
+; CHECK-DAG: %[[uint:[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: %[[v2uint:[0-9]+]] = OpTypeVector %[[uint]] 2
+; CHECK-DAG: %[[v3uint:[0-9]+]] = OpTypeVector %[[uint]] 3
+; CHECK-DAG: %[[image_2darray:[0-9]+]] = OpTypeImage %[[float]] 2D 2 1 0 1 Unknown
+
+; CHECK-DAG: %[[lod0:[0-9]+]] = OpConstant %[[uint]] 0
+; CHECK-DAG: %[[uint_1:[0-9]+]] = OpConstant %[[uint]] 1
+; CHECK-DAG: %[[coord_2darray:[0-9]+]] = OpConstantNull %[[v3uint]]
+; CHECK-DAG: %[[offset_2d:[0-9]+]] = OpConstantComposite %[[v2uint]] %[[uint_1]] %[[uint_1]]
+
+ at .str = private unnamed_addr constant [6 x i8] c"img2d\00", align 1
+
+define void @test_load_2darray() #0 {
+entry:
+  %img = tail call target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32 0, i32 0, i32 1, i32 0, ptr @.str)
+; CHECK: %[[img_val_2darray:[0-9]+]] = OpLoad %[[image_2darray]]
+; CHECK: %[[res_2darray:[0-9]+]] = OpImageFetch %[[v4float]] %[[img_val_2darray]] %[[coord_2darray]] Lod %[[lod0]]
+  %res = call <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, <3 x i32> zeroinitializer, i32 0, <2 x i32> zeroinitializer)
+  ret void
+}
+
+define void @test_load_2darray_offset() #0 {
+entry:
+  %img = tail call target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32 0, i32 0, i32 1, i32 0, ptr @.str)
+; CHECK: %[[img_val_2darray_off:[0-9]+]] = OpLoad %[[image_2darray]]
+; CHECK: %[[res_2darray_off:[0-9]+]] = OpImageFetch %[[v4float]] %[[img_val_2darray_off]] %[[coord_2darray]] Lod|ConstOffset %[[lod0]] %[[offset_2d]]
+  %res = call <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, <3 x i32> zeroinitializer, i32 0, <2 x i32> <i32 1, i32 1>)
+  ret void
+}
+
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+declare target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32, i32, i32, i32, ptr)
+declare <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.v3i32.i32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0), <3 x i32>, i32, <2 x i32>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/Sample2DArray.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/Sample2DArray.ll
new file mode 100644
index 0000000000000..0e06caf4fd544
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/Sample2DArray.ll
@@ -0,0 +1,68 @@
+; RUN: llc -O0 -mtriple=spirv-vulkan-compute %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-compute %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Shader
+
+; CHECK-DAG: %[[float:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[v4float:[0-9]+]] = OpTypeVector %[[float]] 4
+; CHECK-DAG: %[[image:[0-9]+]] = OpTypeImage %[[float]] 2D 2 1 0 1 Unknown
+; CHECK-DAG: %[[sampled_image:[0-9]+]] = OpTypeSampledImage %[[image]]
+; CHECK-DAG: %[[sampler:[0-9]+]] = OpTypeSampler
+; CHECK-DAG: %[[v3float:[0-9]+]] = OpTypeVector %[[float]] 3
+; CHECK-DAG: %[[v2int:[0-9]+]] = OpTypeVector %[[int:[0-9]+]] 2
+; CHECK-DAG: %[[coord0:[0-9]+]] = OpConstantNull %[[v3float]]
+; CHECK-DAG: %[[coord1_val:[0-9]+]] = OpConstant %[[float]] 0.5
+; CHECK-DAG: %[[coord1:[0-9]+]] = OpConstantComposite %[[v3float]] %[[coord1_val]] %[[coord1_val]] %[[float0:[0-9]+]]
+; CHECK-DAG: %[[offset1_val:[0-9]+]] = OpConstant %[[int]] 1
+; CHECK-DAG: %[[offset1:[0-9]+]] = OpConstantComposite %[[v2int]] %[[offset1_val]] %[[offset1_val]]
+; CHECK-DAG: %[[bias:[0-9]+]] = OpConstant %[[float]] 2
+
+ at .str = private unnamed_addr constant [4 x i8] c"img\00", align 1
+ at .str.1 = private unnamed_addr constant [5 x i8] c"samp\00", align 1
+ at .str.2 = private unnamed_addr constant [4 x i8] c"out\00", align 1
+
+define void @main() {
+entry:
+  %img = tail call target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32 0, i32 0, i32 1, i32 0, ptr @.str)
+  %sampler = tail call target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32 0, i32 1, i32 1, i32 0, ptr @.str.1)
+
+; CHECK: %[[img_val:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val]] %[[sampler_val]]
+; CHECK: %[[res0:[0-9]+]] = OpImageSampleImplicitLod %[[v4float]] %[[si]] %[[coord0]]{{[ ]*$}}
+  %res0 = call <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.0, float 0.0, float 0.0>, <2 x i32> zeroinitializer)
+
+; CHECK: %[[img_val2:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val2:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si2:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val2]] %[[sampler_val2]]
+; CHECK: %[[res1:[0-9]+]] = OpImageSampleImplicitLod %[[v4float]] %[[si2]] %[[coord1]] ConstOffset %[[offset1]]{{[ ]*$}}
+  %res1 = call <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.5, float 0.5, float 1.0>, <2 x i32> <i32 1, i32 1>)
+
+; CHECK: %[[img_val3:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val3:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si3:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val3]] %[[sampler_val3]]
+; CHECK: %[[res2:[0-9]+]] = OpImageSampleImplicitLod %[[v4float]] %[[si3]] %[[coord0]] Bias %[[bias]]{{[ ]*$}}
+  %res2 = call <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.0, float 0.0, float 0.0>, float 2.0, <2 x i32> zeroinitializer)
+
+; CHECK: %[[img_val4:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val4:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si4:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val4]] %[[sampler_val4]]
+; CHECK: %[[res3:[0-9]+]] = OpImageSampleImplicitLod %[[v4float]] %[[si4]] %[[coord1]] Bias|ConstOffset %[[bias]] %[[offset1]]{{[ ]*$}}
+  %res3 = call <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.5, float 0.5, float 1.0>, float 2.0, <2 x i32> <i32 1, i32 1>)
+
+  %tmp0 = fadd <4 x float> %res0, %res1
+  %tmp1 = fadd <4 x float> %res2, %res3
+  %res = fadd <4 x float> %tmp0, %tmp1
+
+  %out = tail call target("spirv.Image", float, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_5_2_0_0_2_1t(i32 0, i32 2, i32 1, i32 0, ptr @.str.2)
+  %out_ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_5_2_0_0_2_1t(target("spirv.Image", float, 5, 2, 0, 0, 2, 1) %out, i32 0)
+  store <4 x float> %res, ptr addrspace(11) %out_ptr
+  ret void
+}
+
+declare target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32, i32, i32, i32, ptr)
+declare target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32, i32, i32, i32, ptr)
+declare <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0), target("spirv.Sampler"), <3 x float>, <2 x i32>)
+declare <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0), target("spirv.Sampler"), <3 x float>, float, <2 x i32>)
+declare target("spirv.Image", float, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_5_2_0_0_2_1t(i32, i32, i32, i32, ptr)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_5_2_0_0_2_1t(target("spirv.Image", float, 5, 2, 0, 0, 2, 1), i32)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleGrad2DArray.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleGrad2DArray.ll
new file mode 100644
index 0000000000000..498d37bdb8787
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleGrad2DArray.ll
@@ -0,0 +1,53 @@
+; RUN: llc -O0 -mtriple=spirv-vulkan-compute %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-compute %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Shader
+
+; CHECK-DAG: %[[float:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[v4float:[0-9]+]] = OpTypeVector %[[float]] 4
+; CHECK-DAG: %[[image:[0-9]+]] = OpTypeImage %[[float]] 2D 2 1 0 1 Unknown
+; CHECK-DAG: %[[sampled_image:[0-9]+]] = OpTypeSampledImage %[[image]]
+; CHECK-DAG: %[[sampler:[0-9]+]] = OpTypeSampler
+; CHECK-DAG: %[[v3float:[0-9]+]] = OpTypeVector %[[float]] 3
+; CHECK-DAG: %[[v2float:[0-9]+]] = OpTypeVector %[[float]] 2
+; CHECK-DAG: %[[v2int:[0-9]+]] = OpTypeVector %[[int:[0-9]+]] 2
+; CHECK-DAG: %[[coord0:[0-9]+]] = OpConstantNull %[[v3float]]
+; CHECK-DAG: %[[ddx:[0-9]+]] = OpConstantComposite %[[v2float]] %[[float_val:[0-9]+]] %[[float_val]]
+; CHECK-DAG: %[[ddy:[0-9]+]] = OpConstantComposite %[[v2float]] %[[float_val2:[0-9]+]] %[[float_val2]]
+; CHECK-DAG: %[[offset1_val:[0-9]+]] = OpConstant %[[int]] 1
+; CHECK-DAG: %[[offset1:[0-9]+]] = OpConstantComposite %[[v2int]] %[[offset1_val]] %[[offset1_val]]
+
+ at .str = private unnamed_addr constant [4 x i8] c"img\00", align 1
+ at .str.1 = private unnamed_addr constant [5 x i8] c"samp\00", align 1
+ at .str.2 = private unnamed_addr constant [4 x i8] c"out\00", align 1
+
+define void @main() {
+entry:
+  %img = tail call target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32 0, i32 0, i32 1, i32 0, ptr @.str)
+  %sampler = tail call target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32 0, i32 1, i32 1, i32 0, ptr @.str.1)
+
+; CHECK: %[[img_val:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val]] %[[sampler_val]]
+; CHECK: %[[res0:[0-9]+]] = OpImageSampleExplicitLod %[[v4float]] %[[si]] %[[coord0]] Grad %[[ddx]] %[[ddy]]{{[ ]*$}}
+  %res0 = call <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.0, float 0.0, float 0.0>, <2 x float> <float 0.5, float 0.5>, <2 x float> <float 0.25, float 0.25>, <2 x i32> zeroinitializer)
+
+; CHECK: %[[img_val2:[0-9]+]] = OpLoad %[[image]]
+; CHECK: %[[sampler_val2:[0-9]+]] = OpLoad %[[sampler]]
+; CHECK: %[[si2:[0-9]+]] = OpSampledImage %[[sampled_image]] %[[img_val2]] %[[sampler_val2]]
+; CHECK: %[[res1:[0-9]+]] = OpImageSampleExplicitLod %[[v4float]] %[[si2]] %[[coord1:[0-9]+]] Grad|ConstOffset %[[ddx]] %[[ddy]] %[[offset1]]{{[ ]*$}}
+  %res1 = call <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %img, target("spirv.Sampler") %sampler, <3 x float> <float 0.5, float 0.5, float 1.0>, <2 x float> <float 0.5, float 0.5>, <2 x float> <float 0.25, float 0.25>, <2 x i32> <i32 1, i32 1>)
+
+  %res = fadd <4 x float> %res0, %res1
+
+  %out = tail call target("spirv.Image", float, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_5_2_0_0_2_1t(i32 0, i32 2, i32 1, i32 0, ptr @.str.2)
+  %out_ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_5_2_0_0_2_1t(target("spirv.Image", float, 5, 2, 0, 0, 2, 1) %out, i32 0)
+  store <4 x float> %res, ptr addrspace(11) %out_ptr
+  ret void
+}
+
+declare target("spirv.Image", float, 1, 2, 1, 0, 1, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_1_2_1_0_1_0t(i32, i32, i32, i32, ptr)
+declare target("spirv.Sampler") @llvm.spv.resource.handlefrombinding.tspirv.Samplert(i32, i32, i32, i32, ptr)
+declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_1_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 1, 0, 1, 0), target("spirv.Sampler"), <3 x float>, <2 x float>, <2 x float>, <2 x i32>)
+declare target("spirv.Image", float, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_5_2_0_0_2_1t(i32, i32, i32, i32, ptr)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_f32_5_2_0_0_2_1t(target("spirv.Image", float, 5, 2, 0, 0, 2, 1), i32)

>From 5544dbd4a09a8db98068bb10c9f7ada888eb24e9 Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Mon, 15 Jun 2026 18:32:47 +0100
Subject: [PATCH 2/6] Amend DXIL lowering to avoid Undef values

Amended the DXIL Sample lowering to use poison values instead of
undef values for unknown values, and amended sample tests accordingly.
This avoids undef deprecator code formatter errors.
---
 llvm/lib/Target/DirectX/DXILOpLowering.cpp    | 20 ++---
 llvm/test/CodeGen/DirectX/Sample.ll           | 50 +++++------
 llvm/test/CodeGen/DirectX/SampleBias.ll       | 50 +++++------
 llvm/test/CodeGen/DirectX/SampleGrad.ll       | 82 +++++++++----------
 llvm/test/CodeGen/DirectX/SampleLevel.ll      | 28 +++----
 .../DirectX/Texture2DArray-SampleBias.ll      | 16 ++--
 .../DirectX/Texture2DArray-SampleGrad.ll      | 20 ++---
 7 files changed, 133 insertions(+), 133 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index efac3dd7900c1..a0ea65c6a087f 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -676,11 +676,11 @@ class OpLowerer {
       Type *OldTy = CI->getType();
       Type *NewRetTy = OpBuilder.getResRetType(OldTy->getScalarType());
 
-      Value *UndefF = UndefValue::get(IRB.getFloatTy());
-      Value *UndefI = UndefValue::get(IRB.getInt32Ty());
+      Value *PoisonF = PoisonValue::get(IRB.getFloatTy());
+      Value *PoisonI = PoisonValue::get(IRB.getInt32Ty());
       // Common prefix: Handle, Sampler, Coord0..3, Offset0..2
-      SmallVector<Value *, 17> Args{Handle, Sampler, UndefF, UndefF, UndefF,
-                                    UndefF, UndefI,  UndefI, UndefI};
+      SmallVector<Value *, 17> Args{Handle, Sampler, PoisonF, PoisonF, PoisonF,
+                                    PoisonF, PoisonI, PoisonI, PoisonI};
 
       // Copy coordinates and offsets into Args.
       extractElementsIntoArgs(IRB, Args, 2, Coords, 4);
@@ -707,7 +707,7 @@ class OpLowerer {
                            // Clamp
                            Args.push_back(
                                HasClamp ? CI->getArgOperand(4)
-                                        : UndefValue::get(IRB.getFloatTy()));
+                                        : PoisonValue::get(IRB.getFloatTy()));
                          });
   }
 
@@ -720,7 +720,7 @@ class OpLowerer {
           Args.push_back(CI->getArgOperand(3));
           // Clamp
           Args.push_back(HasClamp ? CI->getArgOperand(5)
-                                  : UndefValue::get(IRB.getFloatTy()));
+                                  : PoisonValue::get(IRB.getFloatTy()));
         });
   }
 
@@ -740,17 +740,17 @@ class OpLowerer {
                    SmallVectorImpl<Value *> &Args) {
           Value *DDX = CI->getArgOperand(3);
           Value *DDY = CI->getArgOperand(4);
-          Value *UndefF = UndefValue::get(IRB.getFloatTy());
+          Value *PoisonF = PoisonValue::get(IRB.getFloatTy());
           // DDX0..2
           size_t DDXStart = Args.size();
-          Args.append(3, UndefF);
+          Args.append(3, PoisonF);
           extractElementsIntoArgs(IRB, Args, DDXStart, DDX, 3);
           // DDY0..2
           size_t DDYStart = Args.size();
-          Args.append(3, UndefF);
+          Args.append(3, PoisonF);
           extractElementsIntoArgs(IRB, Args, DDYStart, DDY, 3);
           // Clamp
-          Args.push_back(HasClamp ? CI->getArgOperand(6) : UndefF);
+          Args.push_back(HasClamp ? CI->getArgOperand(6) : PoisonF);
         });
   }
 
diff --git a/llvm/test/CodeGen/DirectX/Sample.ll b/llvm/test/CodeGen/DirectX/Sample.ll
index 779df2beb347d..3e355af24170a 100644
--- a/llvm/test/CodeGen/DirectX/Sample.ll
+++ b/llvm/test/CodeGen/DirectX/Sample.ll
@@ -22,9 +22,9 @@ define void @sample_texture2d_float4(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -52,8 +52,8 @@ define void @sample_texture2d_with_clamp(<2 x float> %coords, float %clamp) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -82,9 +82,9 @@ define void @sample_texture2d_with_offset(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -114,9 +114,9 @@ define void @sample_texture2d_with_dynamic_offset(<2 x float> %coords, <2 x i32>
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -144,8 +144,8 @@ define void @sample_texture2d_with_offset_and_clamp(<2 x float> %coords, float %
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -172,9 +172,9 @@ define void @sample_texture1d_float4(float %coord) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -203,9 +203,9 @@ define void @sample_texture3d_float4(<3 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -233,9 +233,9 @@ define void @sample_texture2d_scalar(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call float
       @llvm.dx.resource.sample.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -263,9 +263,9 @@ define void @sample_texture2d_half4(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f16(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x half>
       @llvm.dx.resource.sample.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleBias.ll b/llvm/test/CodeGen/DirectX/SampleBias.ll
index 47cded9a65275..eb270ebff02b3 100644
--- a/llvm/test/CodeGen/DirectX/SampleBias.ll
+++ b/llvm/test/CodeGen/DirectX/SampleBias.ll
@@ -22,10 +22,10 @@ define void @samplebias_texture2d_float4(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -53,8 +53,8 @@ define void @samplebias_texture2d_with_clamp(<2 x float> %coords, float %bias, f
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
@@ -84,10 +84,10 @@ define void @samplebias_texture2d_with_offset(<2 x float> %coords, float %bias)
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -117,10 +117,10 @@ define void @samplebias_texture2d_with_dynamic_offset(<2 x float> %coords, float
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -148,8 +148,8 @@ define void @samplebias_texture2d_with_offset_and_clamp(<2 x float> %coords, flo
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
@@ -177,10 +177,10 @@ define void @samplebias_texture1d_float4(float %coord, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -209,10 +209,10 @@ define void @samplebias_texture3d_float4(<3 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -240,10 +240,10 @@ define void @samplebias_texture2d_scalar(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call float
       @llvm.dx.resource.samplebias.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -271,10 +271,10 @@ define void @samplebias_texture2d_half4(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f16(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x half>
       @llvm.dx.resource.samplebias.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleGrad.ll b/llvm/test/CodeGen/DirectX/SampleGrad.ll
index 0371079c9f29d..6353bb9f1a2b7 100644
--- a/llvm/test/CodeGen/DirectX/SampleGrad.ll
+++ b/llvm/test/CodeGen/DirectX/SampleGrad.ll
@@ -26,11 +26,11 @@ define void @samplegrad_texture2d_float4(<2 x float> %coords, <2 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -63,10 +63,10 @@ define void @samplegrad_texture2d_with_clamp(<2 x float> %coords, <2 x float> %d
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
@@ -100,11 +100,11 @@ define void @samplegrad_texture2d_with_offset(<2 x float> %coords, <2 x float> %
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -139,11 +139,11 @@ define void @samplegrad_texture2d_with_dynamic_offset(<2 x float> %coords, <2 x
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -176,10 +176,10 @@ define void @samplegrad_texture2d_with_offset_and_clamp(<2 x float> %coords, <2
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
@@ -207,11 +207,11 @@ define void @samplegrad_texture1d_float4(float %coord, float %ddx_scalar, float
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %ddx_scalar, float undef, float undef,
-  ; CHECK-SAME: float %ddy_scalar, float undef, float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %ddx_scalar, float poison, float poison,
+  ; CHECK-SAME: float %ddy_scalar, float poison, float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.f32.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -246,11 +246,11 @@ define void @samplegrad_texture3d_float4(<3 x float> %coords, <3 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float %[[DDX2]],
   ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float %[[DDY2]],
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3f32.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -283,11 +283,11 @@ define void @samplegrad_texture2d_scalar(<2 x float> %coords, <2 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call float
       @llvm.dx.resource.samplegrad.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -320,11 +320,11 @@ define void @samplegrad_texture2d_half4(<2 x float> %coords, <2 x float> %ddx, <
   ; CHECK-SAME: @dx.op.sampleGrad.f16(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x half>
       @llvm.dx.resource.samplegrad.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleLevel.ll b/llvm/test/CodeGen/DirectX/SampleLevel.ll
index 3cfbc544418d9..3a4e257f254e3 100644
--- a/llvm/test/CodeGen/DirectX/SampleLevel.ll
+++ b/llvm/test/CodeGen/DirectX/SampleLevel.ll
@@ -22,8 +22,8 @@ define void @samplelevel_texture2d_float4(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -52,8 +52,8 @@ define void @samplelevel_texture2d_with_offset(<2 x float> %coords, float %lod)
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -84,8 +84,8 @@ define void @samplelevel_texture2d_with_dynamic_offset(<2 x float> %coords, floa
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -112,8 +112,8 @@ define void @samplelevel_texture1d_float4(float %coord, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
@@ -143,8 +143,8 @@ define void @samplelevel_texture3d_float4(<3 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
@@ -173,8 +173,8 @@ define void @samplelevel_texture2d_scalar(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call float
       @llvm.dx.resource.samplelevel.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -203,8 +203,8 @@ define void @samplelevel_texture2d_half4(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f16(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %lod)
   %data = call <4 x half>
       @llvm.dx.resource.samplelevel.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
index 0bb17a2f0f836..6c694e0f47fe7 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
@@ -21,10 +21,10 @@ define void @samplebias_texture2darray_float4(<3 x float> %coords, float %bias)
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -53,10 +53,10 @@ define void @samplebias_texture2darray_with_offset(<3 x float> %coords, float %b
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -80,8 +80,8 @@ define void @samplebias_texture2darray_with_clamp(<3 x float> %coords, float %bi
 
   ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
index 106b6c2d8bc92..44b50e3c745b5 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
@@ -25,11 +25,11 @@ define void @samplegrad_texture2darray_float4(<3 x float> %coords, <2 x float> %
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
-  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
+  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -54,11 +54,11 @@ define void @samplegrad_texture2darray_with_offset(<3 x float> %coords, <2 x flo
 
   ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
-  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
-  ; CHECK-SAME: float undef)
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float poison,
+  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float poison,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float poison,
+  ; CHECK-SAME: float poison)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,

>From bd1193506c9af2ade13070d4c397b3422bab7762 Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Mon, 15 Jun 2026 19:19:17 +0100
Subject: [PATCH 3/6] Fix formatting issue

Fix a format error introduced by the previous change.
---
 llvm/lib/Target/DirectX/DXILOpLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index a0ea65c6a087f..dddbfcab75217 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -679,7 +679,7 @@ class OpLowerer {
       Value *PoisonF = PoisonValue::get(IRB.getFloatTy());
       Value *PoisonI = PoisonValue::get(IRB.getInt32Ty());
       // Common prefix: Handle, Sampler, Coord0..3, Offset0..2
-      SmallVector<Value *, 17> Args{Handle, Sampler, PoisonF, PoisonF, PoisonF,
+      SmallVector<Value *, 17> Args{Handle,  Sampler, PoisonF, PoisonF, PoisonF,
                                     PoisonF, PoisonI, PoisonI, PoisonI};
 
       // Copy coordinates and offsets into Args.

>From 57a7fc1e71badd44a8b627a5cef3998671a43f94 Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Tue, 16 Jun 2026 11:13:45 +0100
Subject: [PATCH 4/6] Update test Gather2DArray.ll

Update test Gather2DArray.ll to fix test failure.
---
 llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
index 533cf2e07a538..b26e27d40015f 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
@@ -11,7 +11,7 @@
 ; CHECK-DAG: %[[v3float:[0-9]+]] = OpTypeVector %[[float]] 3
 ; CHECK-DAG: %[[int:[0-9]+]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[v2int:[0-9]+]] = OpTypeVector %[[int]] 2
-; CHECK-DAG: %[[coord:[0-9]+]] = OpConstantNull %[[v3float]]
+; CHECK-DAG: %[[coord:[0-9]+]] = OpConstantComposite %[[v3float]]
 ; CHECK-DAG: %[[component0:[0-9]+]] = OpConstant %[[int]] 0
 ; CHECK-DAG: %[[const1:[0-9]+]] = OpConstant %[[int]] 1
 ; CHECK-DAG: %[[offset:[0-9]+]] = OpConstantComposite %[[v2int]] %[[const1]] %[[const1]]

>From a8f5a9ed2977bab7759d3b70eb21537c9653faab Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Mon, 22 Jun 2026 10:13:27 +0100
Subject: [PATCH 5/6] Revert "Amend DXIL lowering to avoid Undef values"

This reverts commit 5544dbd4a09a8db98068bb10c9f7ada888eb24e9.
---
 llvm/lib/Target/DirectX/DXILOpLowering.cpp    | 20 ++---
 llvm/test/CodeGen/DirectX/Sample.ll           | 50 +++++------
 llvm/test/CodeGen/DirectX/SampleBias.ll       | 50 +++++------
 llvm/test/CodeGen/DirectX/SampleGrad.ll       | 82 +++++++++----------
 llvm/test/CodeGen/DirectX/SampleLevel.ll      | 28 +++----
 .../DirectX/Texture2DArray-SampleBias.ll      | 16 ++--
 .../DirectX/Texture2DArray-SampleGrad.ll      | 20 ++---
 7 files changed, 133 insertions(+), 133 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index dddbfcab75217..efac3dd7900c1 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -676,11 +676,11 @@ class OpLowerer {
       Type *OldTy = CI->getType();
       Type *NewRetTy = OpBuilder.getResRetType(OldTy->getScalarType());
 
-      Value *PoisonF = PoisonValue::get(IRB.getFloatTy());
-      Value *PoisonI = PoisonValue::get(IRB.getInt32Ty());
+      Value *UndefF = UndefValue::get(IRB.getFloatTy());
+      Value *UndefI = UndefValue::get(IRB.getInt32Ty());
       // Common prefix: Handle, Sampler, Coord0..3, Offset0..2
-      SmallVector<Value *, 17> Args{Handle,  Sampler, PoisonF, PoisonF, PoisonF,
-                                    PoisonF, PoisonI, PoisonI, PoisonI};
+      SmallVector<Value *, 17> Args{Handle, Sampler, UndefF, UndefF, UndefF,
+                                    UndefF, UndefI,  UndefI, UndefI};
 
       // Copy coordinates and offsets into Args.
       extractElementsIntoArgs(IRB, Args, 2, Coords, 4);
@@ -707,7 +707,7 @@ class OpLowerer {
                            // Clamp
                            Args.push_back(
                                HasClamp ? CI->getArgOperand(4)
-                                        : PoisonValue::get(IRB.getFloatTy()));
+                                        : UndefValue::get(IRB.getFloatTy()));
                          });
   }
 
@@ -720,7 +720,7 @@ class OpLowerer {
           Args.push_back(CI->getArgOperand(3));
           // Clamp
           Args.push_back(HasClamp ? CI->getArgOperand(5)
-                                  : PoisonValue::get(IRB.getFloatTy()));
+                                  : UndefValue::get(IRB.getFloatTy()));
         });
   }
 
@@ -740,17 +740,17 @@ class OpLowerer {
                    SmallVectorImpl<Value *> &Args) {
           Value *DDX = CI->getArgOperand(3);
           Value *DDY = CI->getArgOperand(4);
-          Value *PoisonF = PoisonValue::get(IRB.getFloatTy());
+          Value *UndefF = UndefValue::get(IRB.getFloatTy());
           // DDX0..2
           size_t DDXStart = Args.size();
-          Args.append(3, PoisonF);
+          Args.append(3, UndefF);
           extractElementsIntoArgs(IRB, Args, DDXStart, DDX, 3);
           // DDY0..2
           size_t DDYStart = Args.size();
-          Args.append(3, PoisonF);
+          Args.append(3, UndefF);
           extractElementsIntoArgs(IRB, Args, DDYStart, DDY, 3);
           // Clamp
-          Args.push_back(HasClamp ? CI->getArgOperand(6) : PoisonF);
+          Args.push_back(HasClamp ? CI->getArgOperand(6) : UndefF);
         });
   }
 
diff --git a/llvm/test/CodeGen/DirectX/Sample.ll b/llvm/test/CodeGen/DirectX/Sample.ll
index 3e355af24170a..779df2beb347d 100644
--- a/llvm/test/CodeGen/DirectX/Sample.ll
+++ b/llvm/test/CodeGen/DirectX/Sample.ll
@@ -22,9 +22,9 @@ define void @sample_texture2d_float4(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -52,8 +52,8 @@ define void @sample_texture2d_with_clamp(<2 x float> %coords, float %clamp) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -82,9 +82,9 @@ define void @sample_texture2d_with_offset(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -114,9 +114,9 @@ define void @sample_texture2d_with_dynamic_offset(<2 x float> %coords, <2 x i32>
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -144,8 +144,8 @@ define void @sample_texture2d_with_offset_and_clamp(<2 x float> %coords, float %
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -172,9 +172,9 @@ define void @sample_texture1d_float4(float %coord) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -203,9 +203,9 @@ define void @sample_texture3d_float4(<3 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -233,9 +233,9 @@ define void @sample_texture2d_scalar(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f32(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call float
       @llvm.dx.resource.sample.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -263,9 +263,9 @@ define void @sample_texture2d_half4(<2 x float> %coords) {
   ; CHECK-SAME: @dx.op.sample.f16(i32 60,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x half>
       @llvm.dx.resource.sample.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleBias.ll b/llvm/test/CodeGen/DirectX/SampleBias.ll
index eb270ebff02b3..47cded9a65275 100644
--- a/llvm/test/CodeGen/DirectX/SampleBias.ll
+++ b/llvm/test/CodeGen/DirectX/SampleBias.ll
@@ -22,10 +22,10 @@ define void @samplebias_texture2d_float4(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -53,8 +53,8 @@ define void @samplebias_texture2d_with_clamp(<2 x float> %coords, float %bias, f
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
@@ -84,10 +84,10 @@ define void @samplebias_texture2d_with_offset(<2 x float> %coords, float %bias)
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -117,10 +117,10 @@ define void @samplebias_texture2d_with_dynamic_offset(<2 x float> %coords, float
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -148,8 +148,8 @@ define void @samplebias_texture2d_with_offset_and_clamp(<2 x float> %coords, flo
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
@@ -177,10 +177,10 @@ define void @samplebias_texture1d_float4(float %coord, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -209,10 +209,10 @@ define void @samplebias_texture3d_float4(<3 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -240,10 +240,10 @@ define void @samplebias_texture2d_scalar(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call float
       @llvm.dx.resource.samplebias.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -271,10 +271,10 @@ define void @samplebias_texture2d_half4(<2 x float> %coords, float %bias) {
   ; CHECK-SAME: @dx.op.sampleBias.f16(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x half>
       @llvm.dx.resource.samplebias.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleGrad.ll b/llvm/test/CodeGen/DirectX/SampleGrad.ll
index 6353bb9f1a2b7..0371079c9f29d 100644
--- a/llvm/test/CodeGen/DirectX/SampleGrad.ll
+++ b/llvm/test/CodeGen/DirectX/SampleGrad.ll
@@ -26,11 +26,11 @@ define void @samplegrad_texture2d_float4(<2 x float> %coords, <2 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -63,10 +63,10 @@ define void @samplegrad_texture2d_with_clamp(<2 x float> %coords, <2 x float> %d
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
@@ -100,11 +100,11 @@ define void @samplegrad_texture2d_with_offset(<2 x float> %coords, <2 x float> %
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -139,11 +139,11 @@ define void @samplegrad_texture2d_with_dynamic_offset(<2 x float> %coords, <2 x
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 2) %texture,
@@ -176,10 +176,10 @@ define void @samplegrad_texture2d_with_offset_and_clamp(<2 x float> %coords, <2
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 3, i32 -1, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 3, i32 -1, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
@@ -207,11 +207,11 @@ define void @samplegrad_texture1d_float4(float %coord, float %ddx_scalar, float
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %ddx_scalar, float poison, float poison,
-  ; CHECK-SAME: float %ddy_scalar, float poison, float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %ddx_scalar, float undef, float undef,
+  ; CHECK-SAME: float %ddy_scalar, float undef, float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.f32.f32.i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 1) %texture,
@@ -246,11 +246,11 @@ define void @samplegrad_texture3d_float4(<3 x float> %coords, <3 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float %[[DDX2]],
   ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float %[[DDY2]],
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3f32.v3f32.v3i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 4) %texture,
@@ -283,11 +283,11 @@ define void @samplegrad_texture2d_scalar(<2 x float> %coords, <2 x float> %ddx,
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call float
       @llvm.dx.resource.samplegrad.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", float, 0, 0, 0, 2) %texture,
@@ -320,11 +320,11 @@ define void @samplegrad_texture2d_half4(<2 x float> %coords, <2 x float> %ddx, <
   ; CHECK-SAME: @dx.op.sampleGrad.f16(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x half>
       @llvm.dx.resource.samplegrad.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x half>, 0, 0, 0, 2) %texture,
diff --git a/llvm/test/CodeGen/DirectX/SampleLevel.ll b/llvm/test/CodeGen/DirectX/SampleLevel.ll
index 3a4e257f254e3..3cfbc544418d9 100644
--- a/llvm/test/CodeGen/DirectX/SampleLevel.ll
+++ b/llvm/test/CodeGen/DirectX/SampleLevel.ll
@@ -22,8 +22,8 @@ define void @samplelevel_texture2d_float4(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -52,8 +52,8 @@ define void @samplelevel_texture2d_with_offset(<2 x float> %coords, float %lod)
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -84,8 +84,8 @@ define void @samplelevel_texture2d_with_dynamic_offset(<2 x float> %coords, floa
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 %[[OFF0]], i32 %[[OFF1]], i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -112,8 +112,8 @@ define void @samplelevel_texture1d_float4(float %coord, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %coord, float poison, float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %coord, float undef, float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_1t.tdx.Sampler_0t.f32.i32(
@@ -143,8 +143,8 @@ define void @samplelevel_texture3d_float4(<3 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x float>
       @llvm.dx.resource.samplelevel.v4f32.tdx.Texture_v4f32_0_0_0_4t.tdx.Sampler_0t.v3f32.v3i32(
@@ -173,8 +173,8 @@ define void @samplelevel_texture2d_scalar(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f32(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call float
       @llvm.dx.resource.samplelevel.f32.tdx.Texture_f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
@@ -203,8 +203,8 @@ define void @samplelevel_texture2d_half4(<2 x float> %coords, float %lod) {
   ; CHECK-SAME: @dx.op.sampleLevel.f16(i32 62,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float poison, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float undef, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %lod)
   %data = call <4 x half>
       @llvm.dx.resource.samplelevel.v4f16.tdx.Texture_v4f16_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
index 6c694e0f47fe7..0bb17a2f0f836 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
@@ -21,10 +21,10 @@ define void @samplebias_texture2darray_float4(<3 x float> %coords, float %bias)
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -53,10 +53,10 @@ define void @samplebias_texture2darray_with_offset(<3 x float> %coords, float %b
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
   ; CHECK-SAME: float %bias,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -80,8 +80,8 @@ define void @samplebias_texture2darray_with_clamp(<3 x float> %coords, float %bi
 
   ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
   ; CHECK-SAME: @dx.op.sampleBias.f32(i32 61,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
   ; CHECK-SAME: float %bias,
   ; CHECK-SAME: float %clamp)
   %data = call <4 x float>
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
index 44b50e3c745b5..106b6c2d8bc92 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
@@ -25,11 +25,11 @@ define void @samplegrad_texture2darray_float4(<3 x float> %coords, <2 x float> %
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
   ; CHECK-SAME: %dx.types.Handle %{{[^,]*}},
-  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float poison,
-  ; CHECK-SAME: i32 poison, i32 poison, i32 poison,
-  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float poison,
-  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %[[COORD0]], float %[[COORD1]], float %[[COORD2]], float undef,
+  ; CHECK-SAME: i32 undef, i32 undef, i32 undef,
+  ; CHECK-SAME: float %[[DDX0]], float %[[DDX1]], float undef,
+  ; CHECK-SAME: float %[[DDY0]], float %[[DDY1]], float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,
@@ -54,11 +54,11 @@ define void @samplegrad_texture2darray_with_offset(<3 x float> %coords, <2 x flo
 
   ; CHECK: %[[SAMPLE:.*]] = call %dx.types.ResRet.f32
   ; CHECK-SAME: @dx.op.sampleGrad.f32(i32 63,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float poison,
-  ; CHECK-SAME: i32 1, i32 -2, i32 poison,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float poison,
-  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float poison,
-  ; CHECK-SAME: float poison)
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: i32 1, i32 -2, i32 undef,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: float %{{[^,]*}}, float %{{[^,]*}}, float undef,
+  ; CHECK-SAME: float undef)
   %data = call <4 x float>
       @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
           target("dx.Texture", <4 x float>, 0, 0, 0, 7) %texture,

>From a6df6867759996b48dbfd68dca64153697b54dcb Mon Sep 17 00:00:00 2001
From: Tim Corringham <tcorring at amd.com>
Date: Tue, 23 Jun 2026 12:03:59 +0100
Subject: [PATCH 6/6] Update tests

Remove some unnecessary sections from tests, and add missing metadata
checks to a test.
---
 .../CodeGen/DirectX/Texture2DArray-SampleBias.ll   | 13 -------------
 .../CodeGen/DirectX/Texture2DArray-SampleGrad.ll   |  9 ---------
 .../DirectX/Texture2DArray-annotateHandle.ll       | 14 +++++---------
 3 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
index 0bb17a2f0f836..84a77920bcbed 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
@@ -94,16 +94,3 @@ define void @samplebias_texture2darray_with_clamp(<3 x float> %coords, float %bi
   call void @use_float4(<4 x float> %data)
   ret void
 }
-
-declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
-    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
-declare target("dx.Sampler", 0)
-    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
-declare <4 x float>
-    @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
-        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
-        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>)
-declare <4 x float>
-    @llvm.dx.resource.samplebias.clamp.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
-        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
-        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>, float)
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
index 106b6c2d8bc92..214906036542a 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
@@ -70,12 +70,3 @@ define void @samplegrad_texture2darray_with_offset(<3 x float> %coords, <2 x flo
   call void @use_float4(<4 x float> %data)
   ret void
 }
-
-declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
-    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
-declare target("dx.Sampler", 0)
-    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
-declare <4 x float>
-    @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2f32.v2f32.v2i32(
-        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
-        target("dx.Sampler", 0), <3 x float>, <2 x float>, <2 x float>, <2 x i32>)
diff --git a/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
index 9cd17381d2e39..c5973f609ee90 100644
--- a/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
@@ -4,6 +4,8 @@ target triple = "dxil-pc-shadermodel6.6-pixel"
 
 declare void @use_float4(<4 x float>)
 
+; CHECK: @[[TEX2DARR:[0-9]+]] = external constant %"Texture2DArray<float4>"
+
 ; Test that a Texture2DArray handle gets ResourceKind::Texture2DArray metadata.
 ; CHECK-LABEL: define void @annotate_texture2darray_float4(
 define void @annotate_texture2darray_float4(<3 x float> %coords, float %bias) {
@@ -26,12 +28,6 @@ define void @annotate_texture2darray_float4(<3 x float> %coords, float %bias) {
   call void @use_float4(<4 x float> %data)
   ret void
 }
-
-declare target("dx.Texture", <4 x float>, 0, 0, 0, 7)
-    @llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_0_0_0_7t(i32, i32, i32, i32, ptr)
-declare target("dx.Sampler", 0)
-    @llvm.dx.resource.handlefrombinding.tdx.Sampler_0t(i32, i32, i32, i32, ptr)
-declare <4 x float>
-    @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_7t.tdx.Sampler_0t.v3f32.v2i32(
-        target("dx.Texture", <4 x float>, 0, 0, 0, 7),
-        target("dx.Sampler", 0), <3 x float>, float, <2 x i32>)
+; Test that the metadata ResourceKind is Texture2DArray (=7), and element type is F32
+; CHECK: !{{[0-9]+}} = !{i32 0, ptr @[[TEX2DARR]], !"", i32 0, i32 5, i32 1, i32 7, i32 0, ![[TAG:[0-9]+]]}
+; CHECK: ![[TAG]] = !{i32 0, i32 9}



More information about the cfe-commits mailing list