Author: Tim Corringham
Date: 2026-07-10T09:08:44+01:00
New Revision: 4516eb3a1fbdf2897db5cbe677de7458e06a1776

URL: 
https://github.com/llvm/llvm-project/commit/4516eb3a1fbdf2897db5cbe677de7458e06a1776
DIFF: 
https://github.com/llvm/llvm-project/commit/4516eb3a1fbdf2897db5cbe677de7458e06a1776.diff

LOG: [HLSL] Implement RWTexture2D (#208267)

Add HLSL front-end support for RWTexture2D and related test cases.

Where appropriate test cases have been parameterized across the
Texture2D types (and redundant Texture2DArray tests removed).

Assisted by Cursor

Fixes: #194742

---------

Co-authored-by: Tim Corringham <[email protected]>

Added: 
    clang/test/AST/HLSL/Texture2D-AST.hlsl
    clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl
    clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl
    clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl

Modified: 
    clang/lib/Sema/HLSLExternalSemaSource.cpp
    clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
    clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl
    clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl

Removed: 
    clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
    clang/test/SemaHLSL/Texture2D-Load-errors.hlsl
    clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl


################################################################################
diff  --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 1d2a3983a639d..115795ca74bae 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -281,6 +281,22 @@ static BuiltinTypeDeclBuilder 
setupTextureType(CXXRecordDecl *Decl, Sema &S,
       .addGatherCmpMethods(Dim, IsArray);
 }
 
+/// Set up RWTexture type: UAV texture with only operator[] (uint2, 
read/write),
+/// Load and GetDimensions (no sample/gather/mips/LOD).
+static BuiltinTypeDeclBuilder setupRWTextureType(CXXRecordDecl *Decl, Sema &S,
+                                                 bool IsArray,
+                                                 ResourceDimension Dim) {
+  return BuiltinTypeDeclBuilder(S, Decl)
+      .addTextureHandle(ResourceClass::UAV, /*IsROV=*/false, IsArray, Dim)
+      .addTextureLoadMethods(Dim, IsArray)
+      .addArraySubscriptOperators(Dim, IsArray)
+      .addGetDimensionsMethods(Dim)
+      .addDefaultHandleConstructor()
+      .addCopyConstructor()
+      .addCopyAssignmentOperator()
+      .addStaticInitializationFunctions(false);
+}
+
 // Add a partial specialization for a template. The `TextureTemplate` is
 // `Texture<element_type>`, and it will be specialized for vectors:
 // `Texture<vector<element_type, element_count>>`.
@@ -691,6 +707,25 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
         .completeDefinition();
   });
 
+  Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWTexture2D")
+             .addSimpleTemplateParams({"element_type"}, {Float4Ty},
+                                      TypedBufferConcept)
+             .finalizeForwardDeclaration();
+
+  onCompletion(Decl, [this](CXXRecordDecl *Decl) {
+    setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false,
+                       ResourceDimension::Dim2D)
+        .completeDefinition();
+  });
+
+  auto *PartialSpecRW = addVectorTexturePartialSpecialization(
+      *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
+  onCompletion(PartialSpecRW, [this](CXXRecordDecl *Decl) {
+    setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false,
+                       ResourceDimension::Dim2D)
+        .completeDefinition();
+  });
+
   // Texture2DArray — same as Texture2D but IsArray=true
   Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2DArray")
              .addSimpleTemplateParams({"element_type"}, {Float4Ty},

diff  --git a/clang/test/AST/HLSL/Texture2D-AST.hlsl 
b/clang/test/AST/HLSL/Texture2D-AST.hlsl
new file mode 100644
index 0000000000000..23d0b8138b39b
--- /dev/null
+++ b/clang/test/AST/HLSL/Texture2D-AST.hlsl
@@ -0,0 +1,178 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | 
FileCheck %s --check-prefixes=CHECK,SRV -DTEXTURE=Texture2D -DSZ=2 -DKIND=SRV
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s 
| FileCheck %s --check-prefixes=CHECK,SRV,SRV-ARR -DTEXTURE=Texture2DArray 
-DSZ=3 -DKIND=SRV
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump 
-disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DRW=1 -o - 
%s | FileCheck %s --check-prefixes=CHECK,UAV,UAV-STORE,UAV-TRUNC 
-DTEXTURE=RWTexture2D -DSZ=2 -DKIND=UAV
+
+// CHECK: ClassTemplateDecl {{.*}} [[TEXTURE]]
+// CHECK: TemplateTypeParmDecl {{.*}} element_type
+// CHECK: CXXRecordDecl {{.*}} [[TEXTURE]] definition
+// CHECK: FinalAttr {{.*}} Implicit final
+// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+
+// SRV: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type 
&(vector<unsigned int, [[SZ]]>) const' inline
+// SRV-NEXT: ParmVarDecl {{.*}} Index 'vector<unsigned int, [[SZ]]>'
+// SRV-NEXT: CompoundStmt
+// SRV-NEXT: ReturnStmt
+// SRV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' 
cannot overflow
+// SRV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' <Dependent>
+// SRV-NEXT: CallExpr {{.*}} '<dependent type>'
+// SRV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// SRV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// SRV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// SRV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// SRV-SAME: ' lvalue .__handle
+// SRV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]<element_type>' lvalue 
implicit this
+// SRV-NEXT: DeclRefExpr {{.*}} 'vector<unsigned int, [[SZ]]>' lvalue ParmVar 
{{.*}} 'Index' 'vector<unsigned int, [[SZ]]>'
+// SRV-NEXT: AlwaysInlineAttr
+
+// UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type 
&(vector<unsigned int, [[SZ]]>) const' inline
+// UAV-NEXT: ParmVarDecl {{.*}} Index 'vector<unsigned int, [[SZ]]>'
+// UAV-NEXT: CompoundStmt
+// UAV-NEXT: ReturnStmt
+// UAV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' 
cannot overflow
+// UAV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' <Dependent>
+// UAV-NEXT: CallExpr {{.*}} '<dependent type>'
+// UAV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
+// UAV-SAME: ' lvalue .__handle
+// UAV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]<element_type>' lvalue 
implicit this
+// UAV-NEXT: DeclRefExpr {{.*}} 'vector<unsigned int, [[SZ]]>' lvalue ParmVar 
{{.*}} 'Index' 'vector<unsigned int, [[SZ]]>'
+// UAV-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
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-ARR-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::[[TEXTURE]]<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
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-ARR-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::[[TEXTURE]]<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
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-ARR-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::[[TEXTURE]]<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
+// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-ARR-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::[[TEXTURE]]<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: ClassTemplatePartialSpecializationDecl {{.*}} class [[TEXTURE]] 
explicit_specialization
+// CHECK: TemplateTypeParmDecl {{.*}} element_type
+// CHECK: NonTypeTemplateParmDecl {{.*}} element_count
+
+// SRV-NOT: BinaryOperator {{.*}} 'hlsl_device float' lvalue '='
+
+// UAV-STORE-LABEL: FunctionDecl {{.*}} main 'void ()'
+// UAV-STORE: BinaryOperator {{.*}} 'hlsl_device float' lvalue '='
+// UAV-STORE-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl_device float' lvalue '[]'
+// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float 
&(*)(vector<unsigned int, [[SZ]]>) const' <FunctionToPointerDecay>
+// UAV-STORE-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(vector<unsigned 
int, [[SZ]]>) const' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float 
&(vector<unsigned int, [[SZ]]>) const'
+// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[TEXTURE]]<float>' 
lvalue <NoOp>
+// UAV-STORE-NEXT: DeclRefExpr {{.*}} 
'[[TEXTURE]]<float>':'hlsl::[[TEXTURE]]<float>' lvalue Var {{.*}} 't' 
'[[TEXTURE]]<float>':'hlsl::[[TEXTURE]]<float>'
+// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'vector<uint, 2>' 
<HLSLVectorTruncation>
+// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector<uint, 3>' 
<LValueToRValue>
+// UAV-TRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector<uint, 3>' lvalue Var 
{{.*}} 'i' 'uint3':'vector<uint, 3>'
+// UAV-NOTRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector<uint, 3>' 
<LValueToRValue>
+// UAV-NOTRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector<uint, 3>' lvalue Var 
{{.*}} 'i' 'uint3':'vector<uint, 3>'
+// UAV-STORE-NEXT: FloatingLiteral {{.*}} 'float' {{.*}}
+
+TEXTURE<float> t;
+
+void main() {
+  uint3 i = uint3(0, 0, 0);
+#if RW
+  t[i] = 1.0f;
+#endif
+  float x = t[i];
+  (void)x;
+  uint w, h;
+  t.GetDimensions(w, h);
+}

diff  --git a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl 
b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
index 87b6506c663b0..25f123a47649b 100644
--- a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
@@ -1,24 +1,33 @@
-// 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
+// Texture2D
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | 
llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D 
-DDXILTY=2 -DRW=0
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | 
llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D 
-DARRAYED=0 -DSAMPLED=1 -DFORMAT=0
 
-Texture2D<float4> Tex : register(t0);
+// Texture2DArray
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s 
| llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL 
-DTEXTURE=Texture2DArray -DDXILTY=7 -DRW=0
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s 
| llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV 
-DTEXTURE=Texture2DArray -DARRAYED=1 -DSAMPLED=1 -DFORMAT=0
 
-// CHECK: define {{.*}} void @test_uint_dims()
-// CHECK: call void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned 
int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
+// RWTexture2D
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | 
llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D 
-DDXILTY=2 -DRW=1
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | 
llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D 
-DARRAYED=0 -DSAMPLED=2 -DFORMAT=1
+
+// When RWTexture2DArray is implemented, add DXIL/SPIRV runs with DXILTY=7, 
RW=1, ARRAYED=1, SAMPLED=2, FORMAT=1.
+
+TEXTURE<float4> Tex;
+
+// CHECK: define {{.*}} void @test_uint_dims{{(\(\))?}}()
+// CHECK: call void @hlsl::[[TEXTURE]]<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::Texture2D<float 
vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} 
%[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
+// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]<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::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
-// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), 
ptr %[[HANDLE_GEP]]
-// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 
0), ptr %[[HANDLE_GEP]]
-// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]])
-// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]])
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, 
[[DXILTY]]), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 
[[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]]
+// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]])
+// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[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]]
@@ -26,21 +35,21 @@ void test_uint_dims() {
 // 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::Texture2D<float vector[4]>::GetDimensions(unsigned 
int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef 
%{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
+// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %{{.*}})
+// CHECK: call void @hlsl::[[TEXTURE]]<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::Texture2D<float 
vector[4]>::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned 
int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} 
%[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
+// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]<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::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
-// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), 
ptr %[[HANDLE_GEP]]
-// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 
0), ptr %[[HANDLE_GEP]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, 
[[DXILTY]]), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 
[[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), 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_2t(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]])
-// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
+// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]])
+// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[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]]
@@ -51,20 +60,20 @@ void test_uint_levels_dims(uint mipLevel) {
 // 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::Texture2D<float vector[4]>::GetDimensions(float&, 
float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
+// CHECK: define {{.*}} void @test_float_dims{{(\(\))?}}()
+// CHECK: call void @hlsl::[[TEXTURE]]<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::Texture2D<float 
vector[4]>::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} 
%[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
+// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]<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::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
-// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), 
ptr %[[HANDLE_GEP]]
-// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 
0), ptr %[[HANDLE_GEP]]
-// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]])
-// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]])
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, 
[[DXILTY]]), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 
[[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]]
+// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]])
+// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[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
@@ -74,21 +83,21 @@ void test_float_dims() {
 // 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::Texture2D<float vector[4]>::GetDimensions(unsigned 
int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, 
ptr {{.*}}, ptr {{.*}})
+// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %{{.*}})
+// CHECK: call void @hlsl::[[TEXTURE]]<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::Texture2D<float 
vector[4]>::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} 
%[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} 
%[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
+// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]<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::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
-// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), 
ptr %[[HANDLE_GEP]]
-// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 
0), ptr %[[HANDLE_GEP]]
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
+// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, 
[[DXILTY]]), ptr %[[HANDLE_GEP]]
+// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 
[[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), 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_2t(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]])
-// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
+// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]])
+// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[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

diff  --git a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl 
b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl
index 7c30a211149e7..d69a0f6ddaa89 100644
--- a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl
@@ -1,238 +1,247 @@
-// 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
+// Texture2D
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 
-DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL 
-DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DDXILTY=2 -DRW=0
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 
-DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV 
-DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DARRAYED=0 -DSAMPLED=1 
-DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 
-DRW=0
 
-Texture2D<float4> t;
+// Texture2DArray
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray 
-DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s 
--check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 
-DARG3=", i32 2" -DDXILTY=7 -DRW=0
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray 
-DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s 
--check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 
-DARG3=", i32 2" -DARRAYED=1 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 
-DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DRW=0
+
+// RWTexture2D
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D 
-DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s 
--check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= 
-DDXILTY=2 -DRW=1
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D 
-DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s 
--check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 
-DARG3= -DARRAYED=0 -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 
-DFORMAT21=21 -DFORMAT24=24 -DFORMAT25=25
+
+TEXTURE<float4> t;
 
 // CHECK: define hidden {{.*}} <4 x float> @test_load(int vector[2])
-// CHECK: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D<float 
vector[4]>::Load(int vector[3])(ptr {{.*}} @t, <3 x i32> noundef %[[COORD]])
+// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 
[[COORDSZ]]
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t, <[[LOCSZ]] x i32> 
noundef %[[COORD]])
 // CHECK: ret <4 x float> %[[CALL]]
 
 float4 test_load(int2 loc : LOC) : SV_Target {
-  return t.Load(int3(loc, 0));
+  return t.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D<float 
vector[4]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> 
@hlsl::[[TEXTURE]]<float vector[4]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]])
 // CHECK: %[[THIS_ADDR:.*]] = alloca ptr
-// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32>
+// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32>
 // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
-// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]]
+// CHECK: store <[[LOCSZ]] x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]]
 // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
-// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", 
{{.*}}), ptr %[[HANDLE_GEP]]
-// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]]
-// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> 
poison, <2 x i32> <i32 0, i32 1>
-// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2
-// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 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_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x 
i32> zeroinitializer)
+// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]]
+// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], 
<[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> <i32 0, i32 1[[ARG3]]>
+// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], 
i64 [[COORDSZ]]
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] x i32> 
%[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORDSZ]] 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: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D<float 
vector[4]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t, <3 x i32> noundef 
%[[COORD]], <2 x i32> noundef splat (i32 1))
+// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 
[[COORDSZ]]
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t, 
<[[LOCSZ]] x i32> noundef %[[COORD]], <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(int3(loc, 0), int2(1, 1));
+  return t.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D<float 
vector[4]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x 
i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> 
@hlsl::[[TEXTURE]]<float vector[4]>::Load(int vector[[[LOCSZ]]], int 
vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], 
<2 x i32> {{.*}} %[[OFFSET:.*]])
 // CHECK: %[[THIS_ADDR:.*]] = alloca ptr
-// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32>
+// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32>
 // CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32>
 // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
-// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]]
+// CHECK: store <[[LOCSZ]] 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::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
+// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", 
{{.*}}), ptr %[[HANDLE_GEP]]
-// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]]
-// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> 
poison, <2 x i32> <i32 0, i32 1>
-// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2
+// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]]
+// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], 
<[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> <i32 0, i32 1[[ARG3]]>
+// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], 
i64 [[COORDSZ]]
 // 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 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_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x 
i32> %[[OFFSET_VAL]])
+// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] 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_{{.*}}("spirv.Image", 
float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORDSZ]] 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.
 
-Texture2D<float> t_float;
+TEXTURE<float> t_float;
 
 // CHECK: define hidden {{.*}} float @test_load_float(int vector[2])
-// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::Texture2D<float>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> 
{{.*}} %[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call {{.*}} float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture",
 float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call {{.*}} float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], 
<[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 
x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> 
%{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer)
 // CHECK: ret float %[[RES]]
 float test_load_float(int2 loc : LOC) {
-  return t_float.Load(int3(loc, 0));
+  return t_float.Load(LOCTY(loc, ZEROS));
 }
 
 // CHECK: define hidden {{.*}} float @test_load_offset_float(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2D<float>::Load(int 
vector[3], int vector[2])(ptr {{.*}} @t_float, <3 x i32> noundef %{{.*}}, <2 x 
i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float>::Load(int 
vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float, <[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_float.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::Texture2D<float>::Load(int vector[3], int vector[2])(ptr {{.*}} 
%[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} 
%[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call {{.*}} float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture",
 float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call {{.*}} float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr 
{{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> 
{{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 
x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> 
%{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret float %[[RES]]
 
-Texture2D<float2> t_float2;
+TEXTURE<float2> t_float2;
 
 // CHECK: define hidden {{.*}} <2 x float> @test_load_float2(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2D<float 
vector[2]>::Load(int vector[3])(ptr {{.*}} @t_float2, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float2, <[[LOCSZ]] x i32> 
noundef %{{.*}})
 // CHECK: ret <2 x float> %[[CALL]]
 float2 test_load_float2(int2 loc : LOC) {
-  return t_float2.Load(int3(loc, 0));
+  return t_float2.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D<float 
vector[2]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture",
 <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <2 x float> 
@hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] 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::Texture2D<float 
vector[2]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float2, <3 x i32> 
noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float2, 
<[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_float2.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D<float 
vector[2]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
-// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} <2 x float> 
@hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOCSZ]]], int 
vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], 
<2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] x 
i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret <2 x float> %[[RES]]
 
-Texture2D<float3> t_float3;
+TEXTURE<float3> t_float3;
 
 // CHECK: define hidden {{.*}} <3 x float> @test_load_float3(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2D<float 
vector[3]>::Load(int vector[3])(ptr {{.*}} @t_float3, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float3, <[[LOCSZ]] x i32> 
noundef %{{.*}})
 // CHECK: ret <3 x float> %[[CALL]]
 float3 test_load_float3(int2 loc : LOC) {
-  return t_float3.Load(int3(loc, 0));
+  return t_float3.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D<float 
vector[3]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture",
 <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <3 x float> 
@hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] 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::Texture2D<float 
vector[3]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float3, <3 x i32> 
noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float3, 
<[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_float3.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D<float 
vector[3]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
-// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image",
 float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} <3 x float> 
@hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOCSZ]]], int 
vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], 
<2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> 
%{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret <3 x float> %[[RES]]
 
-Texture2D<int> t_int;
+TEXTURE<int> t_int;
 
 // CHECK: define hidden {{.*}} i32 @test_load_int(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2D<int>::Load(int 
vector[3])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[LOCSZ]]])(ptr {{.*}} @t_int, <[[LOCSZ]] x i32> noundef %{{.*}})
 // CHECK: ret i32 %[[CALL]]
 int test_load_int(int2 loc : LOC) {
-  return t_int.Load(int3(loc, 0));
+  return t_int.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::Texture2D<int>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> 
{{.*}} %[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture",
 i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], 
<[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 
x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] 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::Texture2D<int>::Load(int 
vector[3], int vector[2])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}}, <2 x 
i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int, <[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_int.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::Texture2D<int>::Load(int vector[3], int vector[2])(ptr {{.*}} 
%[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} 
%[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture",
 i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} 
%[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} 
%[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 
x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] x 
i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret i32 %[[RES]]
 
-Texture2D<int2> t_int2;
+TEXTURE<int2> t_int2;
 
 // CHECK: define hidden {{.*}} <2 x i32> @test_load_int2(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2D<int 
vector[2]>::Load(int vector[3])(ptr {{.*}} @t_int2, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]<int 
vector[2]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int2, <[[LOCSZ]] x i32> 
noundef %{{.*}})
 // CHECK: ret <2 x i32> %[[CALL]]
 int2 test_load_int2(int2 loc : LOC) {
-  return t_int2.Load(int3(loc, 0));
+  return t_int2.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D<int 
vector[2]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture",
 <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]<int 
vector[2]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x 
i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] 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::Texture2D<int 
vector[2]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int2, <3 x i32> 
noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]<int 
vector[2]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int2, 
<[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_int2.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D<int 
vector[2]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
-// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]<int 
vector[2]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], 
<[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <2 x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <2 x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] x 
i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret <2 x i32> %[[RES]]
 
-Texture2D<int3> t_int3;
+TEXTURE<int3> t_int3;
 
 // CHECK: define hidden {{.*}} <3 x i32> @test_load_int3(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2D<int 
vector[3]>::Load(int vector[3])(ptr {{.*}} @t_int3, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int3, <[[LOCSZ]] x i32> 
noundef %{{.*}})
 // CHECK: ret <3 x i32> %[[CALL]]
 int3 test_load_int3(int2 loc : LOC) {
-  return t_int3.Load(int3(loc, 0));
+  return t_int3.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D<int 
vector[3]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture",
 <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x 
i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] 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::Texture2D<int 
vector[3]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int3, <3 x i32> 
noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int3, 
<[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_int3.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D<int 
vector[3]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
-// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], 
<[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> 
%{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret <3 x i32> %[[RES]]
 
-Texture2D<int4> t_int4;
+TEXTURE<int4> t_int4;
 
 // CHECK: define hidden {{.*}} <4 x i32> @test_load_int4(int vector[2])
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2D<int 
vector[4]>::Load(int vector[3])(ptr {{.*}} @t_int4, <3 x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int4, <[[LOCSZ]] x i32> 
noundef %{{.*}})
 // CHECK: ret <4 x i32> %[[CALL]]
 int4 test_load_int4(int2 loc : LOC) {
-  return t_int4.Load(int3(loc, 0));
+  return t_int4.Load(LOCTY(loc, ZEROS));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D<int 
vector[4]>::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} 
%[[LOCATION:.*]])
-// DXIL: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture",
 <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
-// SPIRV: %[[RES:.*]] = call <4 x i32> 
@llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x 
i32> {{.*}} %[[LOCATION:.*]])
+// DXIL: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <4 x i32> 
@llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] 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::Texture2D<int 
vector[4]>::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int4, <3 x i32> 
noundef %{{.*}}, <2 x i32> noundef splat (i32 1))
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int4, 
<[[LOCSZ]] 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(int3(loc, 0), int2(1, 1));
+  return t_int4.Load(LOCTY(loc, ZEROS), int2(1, 1));
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D<int 
vector[4]>::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 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_2t.v2i32.i32.v2i32(target("dx.Texture",
 <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
-// SPIRV: %[[RES:.*]] = call <4 x i32> 
@llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage",
 i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> 
%{{.*}})
+// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], 
<[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x 
i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 
%{{.*}}, <2 x i32> %{{.*}})
+// SPIRV: %[[RES:.*]] = call <4 x i32> 
@llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] x 
i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
 // CHECK: ret <4 x i32> %[[RES]]

diff  --git 
a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl 
b/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
deleted file mode 100644
index f295839be4887..0000000000000
--- a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl 
b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl
new file mode 100644
index 0000000000000..34f704043e55e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -DTEXTURE=RWTexture2D -verify %s
+
+// RWTexture2D has no mips view (contrast with Texture2D-mips-errors.hlsl,
+// which exercises private/protected mips_type on Texture2D).
+
+TEXTURE<float4> t;
+
+void test_no_mips_member() {
+  // expected-error@+1 {{no member named 'mips' in 'hlsl::RWTexture2D}}
+  (void)t.mips;
+}
+
+void test_no_mips_type() {
+  // expected-error@+1 {{no type named 'mips_type' in 'hlsl::RWTexture2D}}
+  TEXTURE<float4>::mips_type a;
+
+  // expected-error@+1 {{no type named 'mips_slice_type' in 
'hlsl::RWTexture2D}}
+  TEXTURE<float4>::mips_slice_type b;
+}

diff  --git 
a/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl 
b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl
new file mode 100644
index 0000000000000..61c7497217284
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -DTEXTURE=RWTexture2D -verify %s
+
+// SRV-style texture methods are not available on RWTexture2D or 
RWTexture2DArray (UAV).
+
+TEXTURE<float4> Tex;
+SamplerState Samp;
+SamplerComparisonState SampCmp;
+
+void main(float2 uv) {
+  int2 offset = int2(0, 0);
+  float compare = 0.5f;
+
+  // expected-error@+1 {{no member named 'SampleLevel' in 'hlsl::RWTexture2D}}
+  Tex.SampleLevel(Samp, uv, 0.0f);
+  // expected-error@+1 {{no member named 'SampleBias' in 'hlsl::RWTexture2D}}
+  Tex.SampleBias(Samp, uv, 0.0f);
+  // expected-error@+1 {{no member named 'SampleGrad' in 'hlsl::RWTexture2D}}
+  Tex.SampleGrad(Samp, uv, float2(0), float2(0));
+  // expected-error@+1 {{no member named 'SampleCmp' in 'hlsl::RWTexture2D}}
+  Tex.SampleCmp(SampCmp, uv, compare);
+  // expected-error@+1 {{no member named 'SampleCmpLevelZero' in 
'hlsl::RWTexture2D}}
+  Tex.SampleCmpLevelZero(SampCmp, uv, compare);
+
+  // expected-error@+1 {{no member named 'Gather' in 'hlsl::RWTexture2D}}
+  Tex.Gather(Samp, uv);
+  // expected-error@+1 {{no member named 'GatherRed' in 'hlsl::RWTexture2D}}
+  Tex.GatherRed(Samp, uv);
+  // expected-error@+1 {{no member named 'GatherGreen' in 'hlsl::RWTexture2D}}
+  Tex.GatherGreen(Samp, uv, offset);
+  // expected-error@+1 {{no member named 'GatherCmp' in 'hlsl::RWTexture2D}}
+  Tex.GatherCmp(SampCmp, uv, compare);
+
+  // expected-error@+1 {{no member named 'CalculateLevelOfDetail' in 
'hlsl::RWTexture2D}}
+  (void)Tex.CalculateLevelOfDetail(Samp, uv);
+  // expected-error@+1 {{no member named 'CalculateLevelOfDetailUnclamped' in 
'hlsl::RWTexture2D}}
+  (void)Tex.CalculateLevelOfDetailUnclamped(Samp, uv);
+}

diff  --git a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl 
b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl
index c6886f975ea59..6a6c2b1e2da4e 100644
--- a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl
+++ b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library 
-finclude-default-header -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library 
-finclude-default-header -fsyntax-only -DTEXTURE=Texture2D -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library 
-finclude-default-header -fsyntax-only -DTEXTURE=Texture2DArray -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library 
-finclude-default-header -fsyntax-only -DTEXTURE=RWTexture2D -verify %s
 
-Texture2D<float4> tex;
+TEXTURE<float4> tex;
 
 void main() {
   uint u_w, u_h, u_l;

diff  --git a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl 
b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl
similarity index 52%
rename from clang/test/SemaHLSL/Texture2D-Load-errors.hlsl
rename to clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl
index 9027c2ea144b8..88e1f81d07094 100644
--- a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl
+++ b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl
@@ -1,6 +1,18 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -verify %s
-
-Texture2D<float4> t;
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -DTEXTURE=Texture2D -DARRAYED=0 -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -DTEXTURE=Texture2DArray -DARRAYED=1 -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -DTEXTURE=RWTexture2D -DARRAYED=0 -verify %s
+
+#if ARRAYED
+#define ITY int4
+#define FTY float4
+#define ZEROS 0, 0
+#else
+#define ITY int3
+#define FTY float3
+#define ZEROS 0
+#endif
+
+TEXTURE<float4> t;
 
 float4 test_too_few_args() {
   return t.Load(); // expected-error {{no matching member function for call to 
'Load'}}
@@ -9,35 +21,38 @@ float4 test_too_few_args() {
 }
 
 float4 test_too_many_args(int2 loc) {
-  return t.Load(int3(loc, 0), int2(1, 1), 1); // expected-error {{no matching 
member function for call to 'Load'}}
+  return t.Load(ITY(loc, ZEROS), 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(float2 loc) {
-  return t.Load(float3(loc, 0)); // expected-warning {{implicit conversion 
turns floating-point number into integer: 'float3' (aka 'vector<float, 3>') to 
'vector<int, 3>'}}
+  return t.Load(FTY(loc, ZEROS)); // expected-warning {{implicit conversion 
turns floating-point number into integer: }}
 }
 
 float4 test_invalid_offset_type(int2 loc, float2 offset) {
-  return t.Load(int3(loc, 0), offset); // expected-warning {{implicit 
conversion turns floating-point number into integer: 'float2' (aka 
'vector<float, 2>') to 'vector<int, 2>'}}
+  return t.Load(ITY(loc, ZEROS), offset); // expected-warning {{implicit 
conversion turns floating-point number into integer: 'float2' (aka 
'vector<float, 2>') to 'vector<int, 2>' (vector of 2 'int' values)}}
 }
 
 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, 3>' (vector of 3 'int' 
values) for 1st argument}}
+  // expected-note@*:* {{candidate function not viable: no known conversion 
from 'int2' (aka 'vector<int, 2>') to }}
   // expected-note@*:* {{candidate function not viable: requires 2 arguments, 
but 1 was provided}}
 }
 
 float4 test_truncated_location_count(int4 loc) {
+#if ARRAYED
+  return t.Load(loc); // no warning expected for array textures which take an 
int4 argument
+#else
   return t.Load(loc); // expected-warning {{implicit conversion truncates 
vector: 'int4' (aka 'vector<int, 4>') to 'vector<int, 3>' (vector of 3 'int' 
values)}}
+#endif
 }
 
-float4 test_splatted_offset_count(int3 loc, int offset) {
+float4 test_splatted_offset_count(ITY loc, int offset) {
   // No errors expected. The vector will be generated by splatting `offset`.
   return t.Load(loc, offset);
 }
 
-
 float4 test_truncated_offset_count(int2 loc, int3 offset) {
-  return t.Load(int3(loc, 0), offset); // expected-warning {{implicit 
conversion truncates vector: 'int3' (aka 'vector<int, 3>') to 'vector<int, 2>' 
(vector of 2 'int' values)}}
+  return t.Load(ITY(loc, ZEROS), 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-Load-errors.hlsl 
b/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
deleted file mode 100644
index 36427aab0e604..0000000000000
--- a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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)}}
-}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to