https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/218728

>From a61433a8d490ddc6d02291a40a887b7f30d37357 Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Mon, 24 Aug 2026 16:00:32 -0700
Subject: [PATCH 1/5] rwtexture-load

---
 clang/lib/CodeGen/CGHLSLBuiltins.cpp          |  37 +-
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp |  23 ++
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h   |   2 +
 clang/lib/Sema/HLSLExternalSemaSource.cpp     |   2 +-
 clang/lib/Sema/SemaHLSL.cpp                   |  15 +-
 .../CodeGenHLSL/resources/Textures-Load.hlsl  | 383 ++++++++++--------
 .../Resources/Textures-Load-errors.hlsl       |  56 ++-
 7 files changed, 312 insertions(+), 206 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 36f729a98539a..e1999ec36e382 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -804,22 +804,31 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
   case Builtin::BI__builtin_hlsl_resource_load_level: {
     Value *HandleOp = EmitScalarExpr(E->getArg(0));
     Value *CoordLODOp = EmitScalarExpr(E->getArg(1));
-
-    auto *CoordLODVecTy = cast<llvm::FixedVectorType>(CoordLODOp->getType());
-    unsigned NumElts = CoordLODVecTy->getNumElements();
-    assert(NumElts >= 2 && "CoordLOD must have at least 2 elements");
-
-    // Split CoordLOD into Coord and LOD
-    SmallVector<int, 4> Mask;
-    for (unsigned I = 0; I < NumElts - 1; ++I)
-      Mask.push_back(I);
-
-    Value *CoordOp =
-        Builder.CreateShuffleVector(CoordLODOp, Mask, "hlsl.load.coord");
-    Value *LODOp =
-        Builder.CreateExtractElement(CoordLODOp, NumElts - 1, "hlsl.load.lod");
     const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
+    Value *CoordOp = nullptr;
+    Value *LODOp = nullptr;
+    if (RT->getAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV) {
+      // A UAV descriptor binds a single mip slice, so a RWTexture location is
+      // all coordinate and there is no mip level to select.
+      CoordOp = CoordLODOp;
+      LODOp = llvm::ConstantInt::get(Int32Ty, 0);
+    } else {
+      auto *CoordLODVecTy = cast<llvm::FixedVectorType>(CoordLODOp->getType());
+      unsigned NumElts = CoordLODVecTy->getNumElements();
+      assert(NumElts >= 2 && "CoordLOD must have at least 2 elements");
+
+      // Split CoordLOD into Coord and LOD
+      SmallVector<int, 4> Mask;
+      for (unsigned I = 0; I < NumElts - 1; ++I)
+        Mask.push_back(I);
+
+      CoordOp =
+          Builder.CreateShuffleVector(CoordLODOp, Mask, "hlsl.load.coord");
+      LODOp = Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
+                                           "hlsl.load.lod");
+    }
+
     SmallVector<Value *, 4> Args;
     Args.push_back(HandleOp);
     Args.push_back(CoordOp);
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 06b0a25102ada..34e883264b5b3 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1630,6 +1630,29 @@ 
BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim,
   return *this;
 }
 
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addRWTextureLoadMethods(ResourceDimension Dim,
+                                                bool IsArray) {
+  assert(!Record->isCompleteDefinition() && "record is already complete");
+
+  ASTContext &AST = Record->getASTContext();
+  // A UAV binds a single mip slice: no mip component, no offset overload.
+  uint32_t CoordSize = getResourceDimensions(Dim) + (IsArray ? 1 : 0);
+  QualType LocationTy = AST.getExtVectorType(AST.IntTy, CoordSize);
+  QualType ReturnType = getHandleElementType();
+
+  using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+
+  // T Load(int2 location)
+  BuiltinTypeMethodBuilder(*this, "Load", ReturnType)
+      .addParam("Location", LocationTy)
+      .callBuiltin("__builtin_hlsl_resource_load_level", ReturnType, 
PH::Handle,
+                   PH::_0)
+      .finalize();
+
+  return *this;
+}
+
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addTextureLoadMSMethods(ResourceDimension Dim,
                                                 bool IsArray) {
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index c9bc92b7d0f15..62dea7fab8064 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -112,6 +112,8 @@ class BuiltinTypeDeclBuilder {
                                                 bool IsArray = false);
   BuiltinTypeDeclBuilder &addTextureLoadMSMethods(ResourceDimension Dim,
                                                   bool IsArray = false);
+  BuiltinTypeDeclBuilder &addRWTextureLoadMethods(ResourceDimension Dim,
+                                                  bool IsArray = false);
   BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods();
   BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods();
   BuiltinTypeDeclBuilder &addByteAddressBufferInterlockedMethods();
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 08e7367766fcb..768155e30f558 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -287,7 +287,7 @@ static BuiltinTypeDeclBuilder 
setupRWTextureType(CXXRecordDecl *Decl, Sema &S,
                                                  ResourceDimension Dim) {
   return BuiltinTypeDeclBuilder(S, Decl)
       .addTextureHandle(ResourceClass::UAV, /*IsROV=*/false, IsArray, Dim)
-      .addTextureLoadMethods(Dim, IsArray)
+      .addRWTextureLoadMethods(Dim, IsArray)
       .addArraySubscriptOperators(Dim, IsArray)
       .addGetDimensionsMethods(Dim)
       .addDefaultHandleConstructor()
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index e08ab96a13773..06828b9ec7fc0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4027,12 +4027,23 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr 
*TheCall) {
   auto *ResourceTy =
       TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
 
-  // Check the location + lod (int3 for Texture2D, int4 for Texture2DArray).
+  // A UAV descriptor binds a single mip slice, so a RWTexture location has no
+  // mip component to select, and TextureLoad on a UAV takes no offset.
+  bool IsUAV =
+      ResourceTy->getAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV;
+  if (IsUAV && S.checkArgCount(TheCall, 2))
+    return true;
+
+  // Check the location: int3 for Texture2D and int4 for Texture2DArray, which
+  // both carry a trailing mip level; int2 and int3 for the RWTexture forms,
+  // which do not.
   unsigned ResourceDim =
       getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
   unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 
0);
+  if (!IsUAV)
+    ++LocationDim;
   QualType CoordLODTy = TheCall->getArg(1)->getType();
-  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim + 1,
+  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim,
                               TheCall->getArg(1)->getBeginLoc()))
     return true;
 
diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl 
b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
index fb643ee0533ee..bf53f2ed7370a 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
@@ -1,95 +1,93 @@
 // Texture2D
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2D -DLOAD_TYPE=int3 \
-// RUN:   -DZEROS=0 -o - %s \
+// RUN:   -DHAS_OFFSET -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2D \
+// RUN:   -DLOAD_ARG="int3(loc, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D \
-// RUN:   -DLOAD_DIM=3 -DCOORD_DIM=2 -DCOORD_MASK="<i32 0, i32 1>" -DDXIL_TY=2 
\
-// RUN:   -DRW=0 -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,SRV,WIDE-LOC,DXIL,DXIL-SRV \
+// RUN:   -DTEXTURE=Texture2D -D#LOAD_DIM=3 -DCOORD_DIM=2 \
+// RUN:   -DCOORD_MASK="<i32 0, i32 1>" -DDXIL_TY=2 -DRW=0 -DENTRY_DIM=2 
-DDIM=2
 // RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2D -DLOAD_TYPE=int3 \
-// RUN:   -DZEROS=0 -o - %s \
+// RUN:   -DHAS_OFFSET -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2D \
+// RUN:   -DLOAD_ARG="int3(loc, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D \
-// RUN:   -DLOAD_DIM=3 -DCOORD_DIM=2 -DCOORD_MASK="<i32 0, i32 1>" -DARRAYED=0 
\
-// RUN:   -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 \
-// RUN:   -DFORMAT24=0 -DFORMAT25=0 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,SRV,WIDE-LOC,SPIRV,SPIRV-SRV \
+// RUN:   -DTEXTURE=Texture2D -D#LOAD_DIM=3 -DCOORD_DIM=2 \
+// RUN:   -DCOORD_MASK="<i32 0, i32 1>" -DARRAYED=0 -DSAMPLED=1 -DFORMAT1=0 \
+// RUN:   -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 \
+// RUN:   -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
 
 // Texture2DArray
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2DArray -DLOAD_TYPE=int4 \
-// RUN:   -DZEROS=" 0, 0" -o - %s \
+// RUN:   -DHAS_OFFSET -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2DArray \
+// RUN:   -DLOAD_ARG="int4(loc, 0, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray \
-// RUN:   -DLOAD_DIM=4 -DCOORD_DIM=3 -DCOORD_MASK="<i32 0, i32 1, i32 2>" \
-// RUN:   -DDXIL_TY=7 -DRW=0 -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,SRV,WIDE-LOC,DXIL,DXIL-SRV \
+// RUN:   -DTEXTURE=Texture2DArray -D#LOAD_DIM=4 -DCOORD_DIM=3 \
+// RUN:   -DCOORD_MASK="<i32 0, i32 1, i32 2>" -DDXIL_TY=7 -DRW=0 
-DENTRY_DIM=2 \
+// RUN:   -DDIM=2
 // RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2DArray -DLOAD_TYPE=int4 \
-// RUN:   -DZEROS=" 0, 0" -o - %s \
+// RUN:   -DHAS_OFFSET -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=Texture2DArray \
+// RUN:   -DLOAD_ARG="int4(loc, 0, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray 
\
-// RUN:   -DLOAD_DIM=4 -DCOORD_DIM=3 -DCOORD_MASK="<i32 0, i32 1, i32 2>" \
-// RUN:   -DARRAYED=1 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 \
-// RUN:   -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DSPV_DIM=1 -DENTRY_DIM=2 \
-// RUN:   -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,SRV,WIDE-LOC,SPIRV,SPIRV-SRV \
+// RUN:   -DTEXTURE=Texture2DArray -D#LOAD_DIM=4 -DCOORD_DIM=3 \
+// RUN:   -DCOORD_MASK="<i32 0, i32 1, i32 2>" -DARRAYED=1 -DSAMPLED=1 \
+// RUN:   -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 \
+// RUN:   -DFORMAT25=0 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
 
-// RWTexture2D
+// RWTexture2D.
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=RWTexture2D -DLOAD_TYPE=int3 \
-// RUN:   -DZEROS=0 -o - %s \
+// RUN:   -DTEXTURE=RWTexture2D -DLOAD_ARG="loc" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D \
-// RUN:   -DLOAD_DIM=3 -DCOORD_DIM=2 -DCOORD_MASK="<i32 0, i32 1>" -DDXIL_TY=2 
\
-// RUN:   -DRW=1 -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,UAV,EXACT-LOC,DXIL,DXIL-UAV \
+// RUN:   -DTEXTURE=RWTexture2D -D#LOAD_DIM=2 -DCOORD_DIM=2 -DDXIL_TY=2 -DRW=1 
\
+// RUN:   -DENTRY_DIM=2 -DDIM=2
 // RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=RWTexture2D -DLOAD_TYPE=int3 \
-// RUN:   -DZEROS=0 -o - %s \
+// RUN:   -DTEXTURE=RWTexture2D -DLOAD_ARG="loc" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D \
-// RUN:   -DLOAD_DIM=3 -DCOORD_DIM=2 -DCOORD_MASK="<i32 0, i32 1>" -DARRAYED=0 
\
+// RUN:   | FileCheck %s --check-prefixes=CHECK,UAV,EXACT-LOC,SPIRV,SPIRV-UAV \
+// RUN:   -DTEXTURE=RWTexture2D -D#LOAD_DIM=2 -DCOORD_DIM=2 -DARRAYED=0 \
 // RUN:   -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 -DFORMAT21=21 \
 // RUN:   -DFORMAT24=24 -DFORMAT25=25 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
 
-// RWTexture2DArray
+// RWTexture2DArray.
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=RWTexture2DArray \
-// RUN:   -DLOAD_TYPE=int4 -DZEROS=" 0, 0" -o - %s \
+// RUN:   -DTEXTURE=RWTexture2DArray -DLOAD_ARG="int3(loc, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,DXIL \
-// RUN:   -DTEXTURE=RWTexture2DArray -DLOAD_DIM=4 -DCOORD_DIM=3 \
-// RUN:   -DCOORD_MASK="<i32 0, i32 1, i32 2>" -DDXIL_TY=7 -DRW=1 \
-// RUN:   -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,UAV,WIDE-LOC,DXIL,DXIL-UAV \
+// RUN:   -DTEXTURE=RWTexture2DArray -D#LOAD_DIM=3 -DCOORD_DIM=3 \
+// RUN:   -DDXIL_TY=7 -DRW=1 -DENTRY_DIM=2 -DDIM=2
 // RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
-// RUN:   -DOFFSET_ARG="int2(1, 1)" -DTEXTURE=RWTexture2DArray \
-// RUN:   -DLOAD_TYPE=int4 -DZEROS=" 0, 0" -o - %s \
+// RUN:   -DTEXTURE=RWTexture2DArray -DLOAD_ARG="int3(loc, 0)" -o - %s \
 // RUN:   | llvm-cxxfilt \
-// RUN:   | FileCheck %s --check-prefixes=CHECK,SPIRV \
-// RUN:   -DTEXTURE=RWTexture2DArray -DLOAD_DIM=4 -DCOORD_DIM=3 \
-// RUN:   -DCOORD_MASK="<i32 0, i32 1, i32 2>" -DARRAYED=1 -DSAMPLED=2 \
-// RUN:   -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 -DFORMAT21=21 -DFORMAT24=24 \
-// RUN:   -DFORMAT25=25 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
+// RUN:   | FileCheck %s --check-prefixes=CHECK,UAV,WIDE-LOC,SPIRV,SPIRV-UAV \
+// RUN:   -DTEXTURE=RWTexture2DArray -D#LOAD_DIM=3 -DCOORD_DIM=3 \
+// RUN:   -DARRAYED=1 -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 \
+// RUN:   -DFORMAT21=21 -DFORMAT24=24 -DFORMAT25=25 -DSPV_DIM=1 -DENTRY_DIM=2 \
+// RUN:   -DDIM=2
 
 // Parameterized over the texture types in the RUN lines above; adding a 
texture
 // of another dimension only requires new RUN lines.
 //
 //   ENTRY_TYPE         the entry point's own coordinate type
+//   HAS_OFFSET         defined for read-only (SRV) textures, which have a
+//                      second Load overload taking an offset
 //   OFFSET_ARG         a literal offset argument
 //   TEXTURE            resource type name
-//   LOAD_TYPE          Load location type
-//   ZEROS              the trailing components padding ENTRY_TYPE out to
-//                      LOAD_TYPE
-//   LOAD_DIM           Load location components (COORD_DIM plus the mip level)
+//   LOAD_ARG           the Load location, built from the entry point's `loc`
+//   LOAD_DIM           Load location components; a FileCheck numeric variable,
+//                      so the last component's index is [[#LOAD_DIM-1]]
 //   COORD_DIM          sample location components (DIM plus the array slice)
 //   COORD_MASK         shufflevector mask extracting the coordinate from a
-//                      location
+//                      location; only needed where LOAD_DIM > COORD_DIM
 //   DXIL_TY            dx.Texture resource-kind operand
 //   RW                 dx.Texture UAV operand
 //   ENTRY_DIM          the entry point's own coordinate components
@@ -100,59 +98,78 @@
 //   SPV_DIM            spirv.Image Dim operand
 //   FORMAT<n>          spirv.Image Image Format operand for the element
 //                      type of the texture declared on line <n>
+//
+// Check prefixes:
+//   SRV                read-only textures. Their location carries a trailing
+//                      mip level, which is split back out of the location, and
+//                      they have the offset overload.
+//   UAV                writable textures. A UAV descriptor binds a single mip
+//                      slice, so the location is all coordinate and the level
+//                      operand is a placeholder that the backends discard.
+//   WIDE-LOC           types whose Load location is wider than the entry
+//                      point's coordinate, so LOAD_ARG appends the array slice
+//                      and/or the mip level to `loc`
+//   EXACT-LOC          types whose Load location is exactly `loc`
 
 TEXTURE<float4> t;
 
 // CHECK: define hidden {{.*}} <4 x float> @test_load(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[COORD:.*]] = insertelement <[[LOAD_DIM]] x i32> {{.*}}, i32 0, 
i32 [[COORD_DIM]]
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t, <[[LOAD_DIM]] x i32> 
noundef %[[COORD]])
+// WIDE-LOC: %[[COORD:.*]] = insertelement <[[#LOAD_DIM]] x i32> {{.*}}, i32 
0, i32 [[#LOAD_DIM-1]]
+// WIDE-LOC: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t, <[[#LOAD_DIM]] x 
i32> noundef %[[COORD]])
+// EXACT-LOC: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t, <[[#LOAD_DIM]] x 
i32> noundef %{{.*}})
 // CHECK: ret <4 x float> %[[CALL]]
 
 float4 test_load(ENTRY_TYPE loc : LOC) : SV_Target {
-  return t.Load(LOAD_TYPE(loc, ZEROS));
+  return t.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x float> 
@hlsl::[[TEXTURE]]<float vector[4]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// CHECK: define linkonce_odr hidden {{.*}} <4 x float> 
@hlsl::[[TEXTURE]]<float vector[4]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
 // CHECK: %[[THIS_ADDR:.*]] = alloca ptr
-// CHECK: %[[LOAD_ADDR:.*]] = alloca <[[LOAD_DIM]] x i32>
+// CHECK: %[[LOAD_ADDR:.*]] = alloca <[[#LOAD_DIM]] x i32>
 // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
-// CHECK: store <[[LOAD_DIM]] x i32> %[[LOAD]], ptr %[[LOAD_ADDR]]
+// CHECK: store <[[#LOAD_DIM]] x i32> %[[LOAD]], ptr %[[LOAD_ADDR]]
 // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
 // 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: %[[LOAD_VAL:.*]] = load <[[LOAD_DIM]] x i32>, ptr %[[LOAD_ADDR]]
-// CHECK: %[[COORD:.*]] = shufflevector <[[LOAD_DIM]] x i32> %[[LOAD_VAL]], 
<[[LOAD_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]]
-// CHECK: %[[LOD:.*]] = extractelement <[[LOAD_DIM]] x i32> %[[LOAD_VAL]], i64 
[[COORD_DIM]]
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
+// CHECK: %[[LOAD_VAL:.*]] = load <[[#LOAD_DIM]] x i32>, ptr %[[LOAD_ADDR]]
+// UAV-NOT: shufflevector
+// UAV-NOT: extractelement
+// SRV: %[[COORD:.*]] = shufflevector <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], 
<[[#LOAD_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]]
+// SRV: %[[LOD:.*]] = extractelement <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], i64 
[[COORD_DIM]]
+// DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
+// DXIL-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[LOAD_VAL]], i32 0, <[[DIM]] x i32> zeroinitializer)
+// SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
+// SPIRV-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[LOAD_VAL]], i32 0, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <4 x float> %[[RES]]
 
-// CHECK: define hidden {{.*}} <4 x float> @test_load_offset(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[COORD:.*]] = insertelement <[[LOAD_DIM]] x i32> {{.*}}, i32 0, 
i32 [[COORD_DIM]]
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t, 
<[[LOAD_DIM]] x i32> noundef %[[COORD]], <[[DIM]] x i32> noundef splat (i32 1))
-// CHECK: ret <4 x float> %[[CALL]]
+// SRV: define hidden {{.*}} <4 x float> @test_load_offset(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[COORD:.*]] = insertelement <[[#LOAD_DIM]] x i32> {{.*}}, i32 0, i32 
[[#LOAD_DIM-1]]
+// SRV: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t, 
<[[#LOAD_DIM]] x i32> noundef %[[COORD]], <[[DIM]] x i32> noundef splat (i32 1))
+// SRV: ret <4 x float> %[[CALL]]
 
+#ifdef HAS_OFFSET
 float4 test_load_offset(ENTRY_TYPE loc : LOC) : SV_Target {
-  return t.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t.Load(LOAD_ARG, OFFSET_ARG);
 }
-
-// CHECK: define linkonce_odr hidden {{.*}} <4 x float> 
@hlsl::[[TEXTURE]]<float vector[4]>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
-// CHECK: %[[LOAD_ADDR:.*]] = alloca <[[LOAD_DIM]] x i32>
-// CHECK: %[[OFFSET_ADDR:.*]] = alloca <[[DIM]] x i32>
-// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
-// CHECK: store <[[LOAD_DIM]] x i32> %[[LOAD]], ptr %[[LOAD_ADDR]]
-// CHECK: store <[[DIM]] x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
-// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
-// 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: %[[LOAD_VAL:.*]] = load <[[LOAD_DIM]] x i32>, ptr %[[LOAD_ADDR]]
-// CHECK: %[[COORD:.*]] = shufflevector <[[LOAD_DIM]] x i32> %[[LOAD_VAL]], 
<[[LOAD_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]]
-// CHECK: %[[LOD:.*]] = extractelement <[[LOAD_DIM]] x i32> %[[LOAD_VAL]], i64 
[[COORD_DIM]]
-// CHECK: %[[OFFSET_VAL:.*]] = load <[[DIM]] x i32>, ptr %[[OFFSET_ADDR]]
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> %[[OFFSET_VAL]])
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> %[[OFFSET_VAL]])
-// CHECK: ret <4 x float> %[[RES]]
+#endif
+
+// SRV: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float 
vector[4]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] x i32> {{.*}} 
%[[OFFSET:.*]])
+// SRV: %[[THIS_ADDR:.*]] = alloca ptr
+// SRV: %[[LOAD_ADDR:.*]] = alloca <[[#LOAD_DIM]] x i32>
+// SRV: %[[OFFSET_ADDR:.*]] = alloca <[[DIM]] x i32>
+// SRV: store ptr %[[THIS]], ptr %[[THIS_ADDR]]
+// SRV: store <[[#LOAD_DIM]] x i32> %[[LOAD]], ptr %[[LOAD_ADDR]]
+// SRV: store <[[DIM]] x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]]
+// SRV: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// SRV: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw 
%"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0
+// SRV: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), 
ptr %[[HANDLE_GEP]]
+// SRV: %[[LOAD_VAL:.*]] = load <[[#LOAD_DIM]] x i32>, ptr %[[LOAD_ADDR]]
+// SRV: %[[COORD:.*]] = shufflevector <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], 
<[[#LOAD_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]]
+// SRV: %[[LOD:.*]] = extractelement <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], i64 
[[COORD_DIM]]
+// SRV: %[[OFFSET_VAL:.*]] = load <[[DIM]] x i32>, ptr %[[OFFSET_ADDR]]
+// DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> %[[OFFSET_VAL]])
+// SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> %[[OFFSET_VAL]])
+// SRV: ret <4 x float> %[[RES]]
 
 
 // For the rest of the types, we just check that the call to the member
@@ -161,178 +178,192 @@ float4 test_load_offset(ENTRY_TYPE loc : LOC) : 
SV_Target {
 TEXTURE<float> t_float;
 
 // CHECK: define hidden {{.*}} float @test_load_float(int 
vector[[[ENTRY_DIM]]])
-// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
[[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
[[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret float %[[RES]]
 float test_load_float(ENTRY_TYPE loc : LOC) {
-  return t_float.Load(LOAD_TYPE(loc, ZEROS));
+  return t_float.Load(LOAD_ARG);
 }
 
-// CHECK: define hidden {{.*}} float @test_load_offset_float(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float>::Load(int 
vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t_float, <[[LOAD_DIM]] x 
i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat (i32 1))
-// CHECK: ret float %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} float @test_load_offset_float(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float>::Load(int 
vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t_float, <[[#LOAD_DIM]] 
x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat (i32 1))
+// SRV: ret float %[[CALL]]
 float test_load_offset_float(ENTRY_TYPE loc : LOC) {
-  return t_float.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_float.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
[[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret float %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} float 
@hlsl::[[TEXTURE]]<float>::Load(int vector[[[#LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, 
[[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float 
@llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 
[[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret float %[[RES]]
 
 TEXTURE<float2> t_float2;
 
 // CHECK: define hidden {{.*}} <2 x float> @test_load_float2(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t_float2, <[[LOAD_DIM]] 
x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_float2, 
<[[#LOAD_DIM]] x i32> noundef %{{.*}})
 // CHECK: ret <2 x float> %[[CALL]]
 float2 test_load_float2(ENTRY_TYPE loc : LOC) {
-  return t_float2.Load(LOAD_TYPE(loc, ZEROS));
+  return t_float2.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x float> 
@hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <2 x float> 
@hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <2 x float> %[[RES]]
 
-// CHECK: define hidden {{.*}} <2 x float> @test_load_offset_float2(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_float2, <[[LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
-// CHECK: ret <2 x float> %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} <2 x float> @test_load_offset_float2(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_float2, <[[#LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
+// SRV: ret <2 x float> %[[CALL]]
 float2 test_load_offset_float2(ENTRY_TYPE loc : LOC) {
-  return t_float2.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_float2.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} <2 x float> 
@hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret <2 x float> %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float 
vector[2]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] x i32> {{.*}} 
%[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, 
<[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret <2 x float> %[[RES]]
 
 TEXTURE<float3> t_float3;
 
 // CHECK: define hidden {{.*}} <3 x float> @test_load_float3(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t_float3, <[[LOAD_DIM]] 
x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_float3, 
<[[#LOAD_DIM]] x i32> noundef %{{.*}})
 // CHECK: ret <3 x float> %[[CALL]]
 float3 test_load_float3(ENTRY_TYPE loc : LOC) {
-  return t_float3.Load(LOAD_TYPE(loc, ZEROS));
+  return t_float3.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x float> 
@hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <3 x float> 
@hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <3 x float> %[[RES]]
 
-// CHECK: define hidden {{.*}} <3 x float> @test_load_offset_float3(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_float3, <[[LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
-// CHECK: ret <3 x float> %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} <3 x float> @test_load_offset_float3(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_float3, <[[#LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
+// SRV: ret <3 x float> %[[CALL]]
 float3 test_load_offset_float3(ENTRY_TYPE loc : LOC) {
-  return t_float3.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_float3.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x float> 
@hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret <3 x float> %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float 
vector[3]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] x i32> {{.*}} 
%[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x 
float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> 
@llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", 
float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret <3 x float> %[[RES]]
 
 TEXTURE<int> t_int;
 
 // CHECK: define hidden {{.*}} i32 @test_load_int(int vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[LOAD_DIM]]])(ptr {{.*}} @t_int, <[[LOAD_DIM]] x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_int, <[[#LOAD_DIM]] x i32> noundef %{{.*}})
 // CHECK: ret i32 %[[CALL]]
 int test_load_int(ENTRY_TYPE loc : LOC) {
-  return t_int.Load(LOAD_TYPE(loc, ZEROS));
+  return t_int.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] 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]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] 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]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret i32 %[[RES]]
 
-// CHECK: define hidden {{.*}} i32 @test_load_offset_int(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t_int, <[[LOAD_DIM]] x 
i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat (i32 1))
-// CHECK: ret i32 %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} i32 @test_load_offset_int(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]<int>::Load(int 
vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} @t_int, <[[#LOAD_DIM]] x 
i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat (i32 1))
+// SRV: ret i32 %[[CALL]]
 int test_load_offset_int(ENTRY_TYPE loc : LOC) {
-  return t_int.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_int.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret i32 %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} i32 
@hlsl::[[TEXTURE]]<int>::Load(int vector[[[#LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call i32 
@llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, 
[[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, 
<[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call i32 
@llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret i32 %[[RES]]
 
 TEXTURE<int2> t_int2;
 
 // CHECK: define hidden {{.*}} <[[DIM]] x i32> @test_load_int2(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <[[DIM]] x i32> @hlsl::[[TEXTURE]]<int 
vector[[[DIM]]]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t_int2, 
<[[LOAD_DIM]] x i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <[[DIM]] x i32> @hlsl::[[TEXTURE]]<int 
vector[[[DIM]]]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_int2, 
<[[#LOAD_DIM]] x i32> noundef %{{.*}})
 // CHECK: ret <[[DIM]] x i32> %[[CALL]]
 int2 test_load_int2(ENTRY_TYPE loc : LOC) {
-  return t_int2.Load(LOAD_TYPE(loc, ZEROS));
+  return t_int2.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <[[DIM]] x i32> 
@hlsl::[[TEXTURE]]<int vector[[[DIM]]]>::Load(int vector[[[LOAD_DIM]]])(ptr 
{{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", 
<[[DIM]] x i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <[[DIM]] x i32> 
@hlsl::[[TEXTURE]]<int vector[[[DIM]]]>::Load(int vector[[[#LOAD_DIM]]])(ptr 
{{.*}} %[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", 
<[[DIM]] x i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <[[DIM]] x i32> %[[RES]]
 
-// CHECK: define hidden {{.*}} <[[DIM]] x i32> @test_load_offset_int2(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <[[DIM]] x i32> @hlsl::[[TEXTURE]]<int 
vector[[[DIM]]]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr 
{{.*}} @t_int2, <[[LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef 
splat (i32 1))
-// CHECK: ret <[[DIM]] x i32> %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} <[[DIM]] x i32> @test_load_offset_int2(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} <[[DIM]] x i32> @hlsl::[[TEXTURE]]<int 
vector[[[DIM]]]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr 
{{.*}} @t_int2, <[[#LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef 
splat (i32 1))
+// SRV: ret <[[DIM]] x i32> %[[CALL]]
 int2 test_load_offset_int2(ENTRY_TYPE loc : LOC) {
-  return t_int2.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_int2.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} <[[DIM]] x i32> 
@hlsl::[[TEXTURE]]<int vector[[[DIM]]]>::Load(int vector[[[LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
-// DXIL: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", 
<[[DIM]] x i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// SPIRV: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret <[[DIM]] x i32> %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} <[[DIM]] x i32> 
@hlsl::[[TEXTURE]]<int vector[[[DIM]]]>::Load(int vector[[[#LOAD_DIM]]], int 
vector[[[DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} 
%[[LOAD:.*]], <[[DIM]] x i32> {{.*}} %[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", 
<[[DIM]] x i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call <[[DIM]] x i32> 
@llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret <[[DIM]] x i32> %[[RES]]
 
 TEXTURE<int3> t_int3;
 
 // CHECK: define hidden {{.*}} <3 x i32> @test_load_int3(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t_int3, <[[LOAD_DIM]] x 
i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_int3, <[[#LOAD_DIM]] 
x i32> noundef %{{.*}})
 // CHECK: ret <3 x i32> %[[CALL]]
 int3 test_load_int3(ENTRY_TYPE loc : LOC) {
-  return t_int3.Load(LOAD_TYPE(loc, ZEROS));
+  return t_int3.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} %[[THIS:.*]], 
<[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] 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) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} %[[THIS:.*]], 
<[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] 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) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <3 x i32> %[[RES]]
 
-// CHECK: define hidden {{.*}} <3 x i32> @test_load_offset_int3(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_int3, <[[LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
-// CHECK: ret <3 x i32> %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} <3 x i32> @test_load_offset_int3(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_int3, <[[#LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
+// SRV: ret <3 x i32> %[[CALL]]
 int3 test_load_offset_int3(ENTRY_TYPE loc : LOC) {
-  return t_int3.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_int3.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] 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, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] 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) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret <3 x i32> %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]<int 
vector[3]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] x i32> {{.*}} 
%[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call <3 x i32> 
@llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call <3 x i32> 
@llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] x i32> 
%{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret <3 x i32> %[[RES]]
 
 TEXTURE<int4> t_int4;
 
 // CHECK: define hidden {{.*}} <4 x i32> @test_load_int4(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} @t_int4, <[[LOAD_DIM]] x 
i32> noundef %{{.*}})
+// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} @t_int4, <[[#LOAD_DIM]] 
x i32> noundef %{{.*}})
 // CHECK: ret <4 x i32> %[[CALL]]
 int4 test_load_int4(ENTRY_TYPE loc : LOC) {
-  return t_int4.Load(LOAD_TYPE(loc, ZEROS));
+  return t_int4.Load(LOAD_ARG);
 }
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOAD_DIM]]])(ptr {{.*}} %[[THIS:.*]], 
<[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
-// DXIL: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] 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]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> zeroinitializer)
+// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[#LOAD_DIM]]])(ptr {{.*}} %[[THIS:.*]], 
<[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]])
+// DXIL: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
{{[^,]*}}, <[[DIM]] 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]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 {{[^,]*}}, <[[DIM]] x i32> zeroinitializer)
 // CHECK: ret <4 x i32> %[[RES]]
 
-// CHECK: define hidden {{.*}} <4 x i32> @test_load_offset_int4(int 
vector[[[ENTRY_DIM]]])
-// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_int4, <[[LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
-// CHECK: ret <4 x i32> %[[CALL]]
+#ifdef HAS_OFFSET
+// SRV: define hidden {{.*}} <4 x i32> @test_load_offset_int4(int 
vector[[[ENTRY_DIM]]])
+// SRV: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
@t_int4, <[[#LOAD_DIM]] x i32> noundef %{{.*}}, <[[DIM]] x i32> noundef splat 
(i32 1))
+// SRV: ret <4 x i32> %[[CALL]]
 int4 test_load_offset_int4(ENTRY_TYPE loc : LOC) {
-  return t_int4.Load(LOAD_TYPE(loc, ZEROS), OFFSET_ARG);
+  return t_int4.Load(LOAD_ARG, OFFSET_ARG);
 }
+#endif
 
-// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] 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, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] 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]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
-// CHECK: ret <4 x i32> %[[RES]]
+// SRV: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]<int 
vector[4]>::Load(int vector[[[#LOAD_DIM]]], int vector[[[DIM]]])(ptr {{.*}} 
%[[THIS:.*]], <[[#LOAD_DIM]] x i32> {{.*}} %[[LOAD:.*]], <[[DIM]] x i32> {{.*}} 
%[[OFFSET:.*]])
+// DXIL-SRV: %[[RES:.*]] = call <4 x i32> 
@llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x 
i32>, [[RW]], 0, 1, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 
%{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SPIRV-SRV: %[[RES:.*]] = call <4 x i32> 
@llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage",
 i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORD_DIM]] 
x i32> %{{.*}}, i32 %{{.*}}, <[[DIM]] x i32> %{{.*}})
+// SRV: ret <4 x i32> %[[RES]]
diff --git a/clang/test/SemaHLSL/Resources/Textures-Load-errors.hlsl 
b/clang/test/SemaHLSL/Resources/Textures-Load-errors.hlsl
index c2f9f9999db9f..3a13b1d1e13ff 100644
--- a/clang/test/SemaHLSL/Resources/Textures-Load-errors.hlsl
+++ b/clang/test/SemaHLSL/Resources/Textures-Load-errors.hlsl
@@ -1,21 +1,21 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl \
-// RUN:   -finclude-default-header -DTEXTURE=Texture2D -DLOAD_TYPE=int3 \
-// RUN:   -DLOAD_FLOAT_TYPE=float3 -DNARROW_LOAD_TYPE=int2 \
+// RUN:   -finclude-default-header -DTEXTURE=Texture2D -DHAS_OFFSET \
+// RUN:   -DLOAD_TYPE=int3 -DLOAD_FLOAT_TYPE=float3 -DNARROW_LOAD_TYPE=int2 \
 // RUN:   -DWIDE_LOAD_TYPE=int4 -DOFFSET_TYPE=int2 -DOFFSET_FLOAT_TYPE=float2 \
 // RUN:   -DWIDE_OFFSET_TYPE=int3 -verify %s
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl \
-// RUN:   -finclude-default-header -DTEXTURE=Texture2DArray -DLOAD_TYPE=int4 \
-// RUN:   -DLOAD_FLOAT_TYPE=float4 -DNARROW_LOAD_TYPE=int3 -DOFFSET_TYPE=int2 \
-// RUN:   -DOFFSET_FLOAT_TYPE=float2 -DWIDE_OFFSET_TYPE=int3 -verify %s
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl \
-// RUN:   -finclude-default-header -DTEXTURE=RWTexture2D -DLOAD_TYPE=int3 \
-// RUN:   -DLOAD_FLOAT_TYPE=float3 -DNARROW_LOAD_TYPE=int2 \
-// RUN:   -DWIDE_LOAD_TYPE=int4 -DOFFSET_TYPE=int2 -DOFFSET_FLOAT_TYPE=float2 \
+// RUN:   -finclude-default-header -DTEXTURE=Texture2DArray -DHAS_OFFSET \
+// RUN:   -DLOAD_TYPE=int4 -DLOAD_FLOAT_TYPE=float4 -DNARROW_LOAD_TYPE=int3 \
+// RUN:   -DOFFSET_TYPE=int2 -DOFFSET_FLOAT_TYPE=float2 \
 // RUN:   -DWIDE_OFFSET_TYPE=int3 -verify %s
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl \
-// RUN:   -finclude-default-header -DTEXTURE=RWTexture2DArray -DLOAD_TYPE=int4 
\
-// RUN:   -DLOAD_FLOAT_TYPE=float4 -DNARROW_LOAD_TYPE=int3 -DOFFSET_TYPE=int2 \
-// RUN:   -DOFFSET_FLOAT_TYPE=float2 -DWIDE_OFFSET_TYPE=int3 -verify %s
+// RUN:   -finclude-default-header -DTEXTURE=RWTexture2D -DLOAD_TYPE=int2 \
+// RUN:   -DLOAD_FLOAT_TYPE=float2 -DNARROW_LOAD_TYPE=int1 \
+// RUN:   -DWIDE_LOAD_TYPE=int3 -DOFFSET_TYPE=int2 -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl \
+// RUN:   -finclude-default-header -DTEXTURE=RWTexture2DArray -DLOAD_TYPE=int3 
\
+// RUN:   -DLOAD_FLOAT_TYPE=float3 -DNARROW_LOAD_TYPE=int2 \
+// RUN:   -DWIDE_LOAD_TYPE=int4 -DOFFSET_TYPE=int2 -verify %s
 
 // Parameterized over the texture types in the RUN lines above; adding a 
texture
 // of another dimension only requires new RUN lines.
@@ -29,6 +29,14 @@
 //   OFFSET_TYPE        offset type, one component per resource dimension
 //   OFFSET_FLOAT_TYPE  offset type, but floating point
 //   WIDE_OFFSET_TYPE   an offset with one component too many
+//   HAS_OFFSET         defined for read-only (SRV) textures, whose location
+//                      carries a trailing mip level and which have a second
+//                      Load overload taking an offset
+//
+// A UAV descriptor binds a single mip slice, so a RWTexture location has no 
mip
+// component, and DXIL's TextureLoad takes no offset on a UAV. Those types
+// therefore have one Load overload instead of two, which changes the
+// diagnostics from overload resolution failures to plain arity errors.
 //
 // The diagnostics that name a vector width use `-re` directives so that the
 // same assertions apply to every texture type.
@@ -41,45 +49,67 @@ float4 test_exact_location(LOAD_TYPE loc) {
 }
 
 float4 test_too_few_args() {
+#ifdef HAS_OFFSET
   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}}
+#else
+  return t.Load(); // expected-error {{too few arguments to function call, 
single argument 'Location' was not specified}}
+  // expected-note@*:* {{'Load' declared here}}
+#endif
 }
 
 float4 test_too_many_args(LOAD_TYPE loc, OFFSET_TYPE offset) {
+#ifdef HAS_OFFSET
   return t.Load(loc, offset, 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}}
+#else
+  // There is no offset overload on a UAV, so even two arguments is too many.
+  return t.Load(loc, offset); // expected-error {{too many arguments to 
function call, expected single argument 'Location', have 2 arguments}}
+  // expected-note@*:* {{'Load' declared here}}
+#endif
 }
 
 float4 test_invalid_coord_type(LOAD_FLOAT_TYPE loc) {
   return t.Load(loc); // expected-warning {{implicit conversion turns 
floating-point number into integer: }}
 }
 
+#ifdef HAS_OFFSET
 float4 test_invalid_offset_type(LOAD_TYPE loc, OFFSET_FLOAT_TYPE offset) {
   // expected-warning-re@+1 {{implicit conversion turns floating-point number 
into integer: '{{float[0-9]}}' (aka 'vector<float, {{[0-9]}}>') to 'vector<int, 
{{[0-9]}}>' (vector of {{[0-9]}} 'int' values)}}
   return t.Load(loc, offset);
 }
+#endif
 
 float4 test_invalid_location_count(NARROW_LOAD_TYPE loc) {
+#ifdef HAS_OFFSET
   return t.Load(loc); // expected-error {{no matching member function for call 
to 'Load'}}
   // expected-note@*:* {{candidate function not viable: no known conversion 
from }}
   // expected-note@*:* {{candidate function not viable: requires 2 arguments, 
but 1 was provided}}
+#else
+  // expected-error-re@+1 {{cannot initialize a parameter of type 'vector<int, 
{{[0-9]}}>' (vector of {{[0-9]}} 'int' values) with an lvalue of type 
'{{int[0-9]?}}'{{( \(aka 'vector<int, [0-9]>'\))?}}}}
+  return t.Load(loc);
+#endif
 }
 
 #ifdef WIDE_LOAD_TYPE
 float4 test_truncated_location_count(WIDE_LOAD_TYPE loc) {
+  // On a UAV this is exactly a location that still carries a mip component: it
+  // truncates like any other over-wide HLSL vector argument.
   // expected-warning-re@+1 {{implicit conversion truncates vector: 
'{{int[0-9]}}' (aka 'vector<int, {{[0-9]}}>') to 'vector<int, {{[0-9]}}>' 
(vector of {{[0-9]}} 'int' values)}}
   return t.Load(loc);
 }
 #endif
 
+#ifdef HAS_OFFSET
 float4 test_splatted_offset_count(LOAD_TYPE loc, int offset) {
   // No errors expected. The vector will be generated by splatting `offset`.
   return t.Load(loc, offset);
 }
 
-float4 test_truncated_offset_count(LOAD_TYPE loc, WIDE_OFFSET_TYPE offset) {
+float4 test_invalid_offset_count(LOAD_TYPE loc, WIDE_OFFSET_TYPE offset) {
   // expected-warning-re@+1 {{implicit conversion truncates vector: 
'{{int[0-9]}}' (aka 'vector<int, {{[0-9]}}>') to 'vector<int, {{[0-9]}}>' 
(vector of {{[0-9]}} 'int' values)}}
   return t.Load(loc, offset);
 }
+#endif

>From 63bedc99ecc6f6eb51e00e70fb21a09ad67cbb7d Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Fri, 28 Aug 2026 15:14:08 -0700
Subject: [PATCH 2/5] Use poison instead of 0 for unused mip level

---
 clang/lib/CodeGen/CGHLSLBuiltins.cpp                | 2 +-
 clang/test/CodeGenHLSL/resources/Textures-Load.hlsl | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index e1999ec36e382..062faadcdcab2 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -812,7 +812,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
       // A UAV descriptor binds a single mip slice, so a RWTexture location is
       // all coordinate and there is no mip level to select.
       CoordOp = CoordLODOp;
-      LODOp = llvm::ConstantInt::get(Int32Ty, 0);
+      LODOp = llvm::PoisonValue::get(Int32Ty);
     } else {
       auto *CoordLODVecTy = cast<llvm::FixedVectorType>(CoordLODOp->getType());
       unsigned NumElts = CoordLODVecTy->getNumElements();
diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl 
b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
index bf53f2ed7370a..fb280af49d9c5 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
@@ -137,9 +137,9 @@ float4 test_load(ENTRY_TYPE loc : LOC) : SV_Target {
 // SRV: %[[COORD:.*]] = shufflevector <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], 
<[[#LOAD_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]]
 // SRV: %[[LOD:.*]] = extractelement <[[#LOAD_DIM]] x i32> %[[LOAD_VAL]], i64 
[[COORD_DIM]]
 // DXIL-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
-// DXIL-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[LOAD_VAL]], i32 0, <[[DIM]] x i32> zeroinitializer)
+// DXIL-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture",
 <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> 
%[[LOAD_VAL]], i32 poison, <[[DIM]] x i32> zeroinitializer)
 // SPIRV-SRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <[[DIM]] x i32> zeroinitializer)
-// SPIRV-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[LOAD_VAL]], i32 0, <[[DIM]] x i32> zeroinitializer)
+// SPIRV-UAV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> 
@llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image",
 float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], 
<[[COORD_DIM]] x i32> %[[LOAD_VAL]], i32 poison, <[[DIM]] x i32> 
zeroinitializer)
 // CHECK: ret <4 x float> %[[RES]]
 
 // SRV: define hidden {{.*}} <4 x float> @test_load_offset(int 
vector[[[ENTRY_DIM]]])

>From 870400fd33385bf3292aa102bf88a689dd2ec70a Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Fri, 28 Aug 2026 15:14:12 -0700
Subject: [PATCH 3/5] Add AST test

---
 clang/test/AST/HLSL/Textures-AST.hlsl | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/clang/test/AST/HLSL/Textures-AST.hlsl 
b/clang/test/AST/HLSL/Textures-AST.hlsl
index d491055cda1e0..6e5655f0cbafd 100644
--- a/clang/test/AST/HLSL/Textures-AST.hlsl
+++ b/clang/test/AST/HLSL/Textures-AST.hlsl
@@ -50,6 +50,23 @@
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
 // CHECK-SAME: {{\[\[}}hlsl::dimension("[[DIM_NAME]]"){{\]\]}}
 
+// UAV: CXXMethodDecl {{.*}} Load 'element_type (vector<int, [[INDEX_DIM]]>)' 
inline
+// UAV-NEXT: ParmVarDecl {{.*}} Location 'vector<int, [[INDEX_DIM]]>'
+// UAV-NEXT: CompoundStmt
+// UAV-NEXT: ReturnStmt
+// UAV-NEXT: CStyleCastExpr {{.*}} 'element_type' <Dependent>
+// UAV-NEXT: CallExpr {{.*}} '<dependent type>'
+// UAV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_load_level' 'void (...) noexcept'
+// UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// UAV-SAME{LITERAL}: [[hlsl::resource_class("UAV")]]
+// UAV-ARRAY-SAME{LITERAL}: [[hlsl::is_array]]
+// UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// UAV-SAME: {{\[\[}}hlsl::dimension("[[DIM_NAME]]"){{\]\]}}
+// UAV-SAME: ' lvalue .__handle
+// UAV-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]<element_type>' lvalue 
implicit this
+// UAV-NEXT: DeclRefExpr {{.*}} 'vector<int, [[INDEX_DIM]]>' lvalue ParmVar 
{{.*}} 'Location' 'vector<int, [[INDEX_DIM]]>'
+// UAV-NEXT: AlwaysInlineAttr
+
 // SRV: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type 
&(vector<unsigned int, [[INDEX_DIM]]>) const' inline
 // SRV-NEXT: ParmVarDecl {{.*}} Index 'vector<unsigned int, [[INDEX_DIM]]>'
 // SRV-NEXT: CompoundStmt

>From d55447d66bc594070d1feda16251bf72c5b9f99c Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Fri, 28 Aug 2026 15:18:39 -0700
Subject: [PATCH 4/5] Remove unnecessary added trailing periods

---
 clang/test/CodeGenHLSL/resources/Textures-Load.hlsl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl 
b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
index fb280af49d9c5..890efbdfeb02e 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
@@ -39,7 +39,7 @@
 // RUN:   -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 \
 // RUN:   -DFORMAT25=0 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
 
-// RWTexture2D.
+// RWTexture2D
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
 // RUN:   -DTEXTURE=RWTexture2D -DLOAD_ARG="loc" -o - %s \
@@ -56,7 +56,7 @@
 // RUN:   -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 -DFORMAT21=21 \
 // RUN:   -DFORMAT24=24 -DFORMAT25=25 -DSPV_DIM=1 -DENTRY_DIM=2 -DDIM=2
 
-// RWTexture2DArray.
+// RWTexture2DArray
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -finclude-default-header -DENTRY_TYPE=int2 \
 // RUN:   -DTEXTURE=RWTexture2DArray -DLOAD_ARG="int3(loc, 0)" -o - %s \

>From 39d1c4450c790c611f09f382f0a24765b01d92cf Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Fri, 28 Aug 2026 15:18:49 -0700
Subject: [PATCH 5/5] Revise description of HAS_OFFSET

---
 clang/test/CodeGenHLSL/resources/Textures-Load.hlsl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl 
b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
index 890efbdfeb02e..26692a276287d 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl
@@ -78,8 +78,8 @@
 // of another dimension only requires new RUN lines.
 //
 //   ENTRY_TYPE         the entry point's own coordinate type
-//   HAS_OFFSET         defined for read-only (SRV) textures, which have a
-//                      second Load overload taking an offset
+//   HAS_OFFSET         defined for types whose Load has an overload taking an
+//                      offset
 //   OFFSET_ARG         a literal offset argument
 //   TEXTURE            resource type name
 //   LOAD_ARG           the Load location, built from the entry point's `loc`

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

Reply via email to