Author: Deric C. Date: 2026-08-31T18:04:45-07:00 New Revision: b04534c1df27bd06fe3ae108a2795e8498e96c5b
URL: https://github.com/llvm/llvm-project/commit/b04534c1df27bd06fe3ae108a2795e8498e96c5b DIFF: https://github.com/llvm/llvm-project/commit/b04534c1df27bd06fe3ae108a2795e8498e96c5b.diff LOG: [HLSL] Add UAV-specific texture load method (#218728) Fixes https://github.com/llvm/llvm-project/issues/218535 UAV texture resources were using the SRV version of the .Load() method and resulted in no matching member function calls when attempted to be used. This PR fixes that issue by adding addRWTextureLoadMethods() to HLSLBuiltinTypeDeclBuilder.cpp and fixing the codegen for BI__builtin_hlsl_resource_load_level to handle UAVs. Assisted by: Claude Opus 5 --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> Added: Modified: clang/lib/CodeGen/CGHLSLBuiltins.cpp clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h clang/lib/Sema/HLSLExternalSemaSource.cpp clang/lib/Sema/SemaHLSL.cpp clang/test/AST/HLSL/Textures-AST.hlsl clang/test/CodeGenHLSL/resources/Textures-Load.hlsl clang/test/SemaHLSL/Resources/Textures-Load-errors.hlsl Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 36f729a98539a..062faadcdcab2 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::PoisonValue::get(Int32Ty); + } 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/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 diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl index fb643ee0533ee..26692a276287d 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 // 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 // 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 types whose Load has an 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 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 poison, <[[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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
