[clang] 829440b - [HLSL] Implement Texture2DArray for HLSL (#203951)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 29 06:53:38 PDT 2026


Author: Tim Corringham
Date: 2026-06-29T14:53:29+01:00
New Revision: 829440b9e63eb3127e2af595aa45fa4b28b7a49a

URL: https://github.com/llvm/llvm-project/commit/829440b9e63eb3127e2af595aa45fa4b28b7a49a
DIFF: https://github.com/llvm/llvm-project/commit/829440b9e63eb3127e2af595aa45fa4b28b7a49a.diff

LOG: [HLSL] Implement Texture2DArray for HLSL (#203951)

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

Assisted by Cursor

Fixes #194944

---------

Co-authored-by: Tim Corringham <tcorring at amd.com>

Added: 
    clang/test/AST/HLSL/Texture2DArray-scalar-AST.hlsl
    clang/test/AST/HLSL/Texture2DArray-shorthand-AST.hlsl
    clang/test/AST/HLSL/Texture2DArray-vector-AST.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-CalculateLevelOfDetail.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-Gather.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-Load.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-Mips.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-Sample.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-SampleBias.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmp.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-SampleCmpLevelZero.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-SampleGrad.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-SampleLevel.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-Subscript.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-default-explicit-binding.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-default.hlsl
    clang/test/CodeGenHLSL/resources/Texture2DArray-shorthand-contexts.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-CalculateLevelOfDetail.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-GetDimensions.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-SampleBias.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmp.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-SampleCmpLevelZero.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-SampleGrad.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-SampleLevel.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-Sema.hlsl
    clang/test/SemaHLSL/Resources/Texture2DArray-Subscript.hlsl
    clang/test/SemaHLSL/Texture2DArray-Gather.hlsl
    clang/test/SemaHLSL/Texture2DArray-GatherCmp-Vulkan.hlsl
    clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
    clang/test/SemaHLSL/Texture2DArray-mips-errors.hlsl
    llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
    llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
    llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
    llvm/test/CodeGen/SPIRV/hlsl-resources/Gather2DArray.ll
    llvm/test/CodeGen/SPIRV/hlsl-resources/LoadLevel2DArray.ll
    llvm/test/CodeGen/SPIRV/hlsl-resources/Sample2DArray.ll
    llvm/test/CodeGen/SPIRV/hlsl-resources/SampleGrad2DArray.ll

Modified: 
    clang/lib/CodeGen/Targets/DirectX.cpp
    clang/lib/CodeGen/Targets/SPIR.cpp
    clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
    clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
    clang/lib/Sema/HLSLExternalSemaSource.cpp
    clang/lib/Sema/SemaHLSL.cpp

Removed: 
    


################################################################################
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 075dc97b0aef2..11e8d3c5dbf3c 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3686,7 +3686,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(),
@@ -3741,7 +3742,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) {
@@ -3763,7 +3765,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()))
@@ -3776,7 +3779,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);
@@ -3882,11 +3887,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;
 
@@ -3899,10 +3905,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..84a77920bcbed
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleBias.ll
@@ -0,0 +1,96 @@
+; 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
+}

diff  --git a/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
new file mode 100644
index 0000000000000..214906036542a
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-SampleGrad.ll
@@ -0,0 +1,72 @@
+; 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
+}

diff  --git a/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
new file mode 100644
index 0000000000000..c5973f609ee90
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Texture2DArray-annotateHandle.ll
@@ -0,0 +1,33 @@
+; 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>)
+
+; 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) {
+  %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
+}
+; 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}

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..b26e27d40015f
--- /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]+]] = 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]]
+
+ 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)


        


More information about the cfe-commits mailing list