https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/146785
>From a49aa19297811e5800ffce364d8d6a225109d93f Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 26 Jun 2025 19:28:01 +0000 Subject: [PATCH 01/13] refactoring --- .../lib/Target/DirectX/DXContainerGlobals.cpp | 4 ++- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 14 +++----- llvm/lib/Target/DirectX/DXILRootSignature.h | 33 +++++++++---------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 6c8ae8eaaea77..e076283b65193 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -160,11 +160,13 @@ void DXContainerGlobals::addRootSignature(Module &M, assert(MMI.EntryPropertyVec.size() == 1); + auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; const auto &RS = RSA.getDescForFunction(EntryFunction); + const auto &RS = RSA.getDescForFunction(EntryFunction); - if (!RS) + if (!RS ) return; SmallString<256> Data; diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 5a53ea8a3631b..4094df160ef6f 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -554,12 +554,9 @@ analyzeModule(Module &M) { AnalysisKey RootSignatureAnalysis::Key; -RootSignatureAnalysis::Result -RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) { - if (!AnalysisResult) - AnalysisResult = std::make_unique<RootSignatureBindingInfo>( - RootSignatureBindingInfo(analyzeModule(M))); - return *AnalysisResult; +RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M, + ModuleAnalysisManager &AM) { + return RootSignatureBindingInfo(analyzeModule(M)); } //===----------------------------------------------------------------------===// @@ -638,9 +635,8 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M, //===----------------------------------------------------------------------===// bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { - if (!FuncToRsMap) - FuncToRsMap = std::make_unique<RootSignatureBindingInfo>( - RootSignatureBindingInfo(analyzeModule(M))); + FuncToRsMap = std::make_unique<RootSignatureBindingInfo>( + RootSignatureBindingInfo(analyzeModule(M))); return false; } diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 3832182277050..24b1a8d3d2abe 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -37,30 +37,28 @@ enum class RootSignatureElementKind { }; class RootSignatureBindingInfo { -private: - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; + private: + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; -public: + public: using iterator = - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; - RootSignatureBindingInfo() = default; - RootSignatureBindingInfo( - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) - : FuncToRsMap(Map) {}; + RootSignatureBindingInfo () = default; + RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {}; iterator find(const Function *F) { return FuncToRsMap.find(F); } iterator end() { return FuncToRsMap.end(); } - std::optional<mcdxbc::RootSignatureDesc> - getDescForFunction(const Function *F) { + std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) { const auto FuncRs = find(F); if (FuncRs == end()) return std::nullopt; return FuncRs->second; } + }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { @@ -68,14 +66,13 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { static AnalysisKey Key; public: - RootSignatureAnalysis() = default; - - using Result = RootSignatureBindingInfo; - Result run(Module &M, ModuleAnalysisManager &AM); +RootSignatureAnalysis() = default; -private: - std::unique_ptr<RootSignatureBindingInfo> AnalysisResult; + using Result = RootSignatureBindingInfo; + + RootSignatureBindingInfo + run(Module &M, ModuleAnalysisManager &AM); }; /// Wrapper pass for the legacy pass manager. @@ -92,8 +89,8 @@ class RootSignatureAnalysisWrapper : public ModulePass { RootSignatureAnalysisWrapper() : ModulePass(ID) {} - RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; } - + RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;} + bool runOnModule(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; >From d90676feb6bfc0ca8bbdaee5c347ecc49e396b5b Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 26 Jun 2025 21:37:11 +0000 Subject: [PATCH 02/13] init refactoring --- .../SemaHLSL/RootSignature-Validation.hlsl | 42 +++++++++++++++++ .../lib/Target/DirectX/DXContainerGlobals.cpp | 2 +- .../DXILPostOptimizationValidation.cpp | 47 +++++++++++++++++-- llvm/lib/Target/DirectX/DXILRootSignature.h | 30 ++++++------ 4 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 clang/test/SemaHLSL/RootSignature-Validation.hlsl diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl new file mode 100644 index 0000000000000..8a4a97f87cb65 --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl @@ -0,0 +1,42 @@ +// RUN: %clang_dxc -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify + +#define ROOT_SIGNATURE \ + "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ + "CBV(b0, visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(SRV(t0, numDescriptors=3), visibility=SHADER_VISIBILITY_PIXEL), " \ + "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL), " \ + "DescriptorTable(UAV(u0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)" + +cbuffer CB : register(b3, space2) { + float a; +} + +StructuredBuffer<int> In : register(t0); +RWStructuredBuffer<int> Out : register(u0); + +RWBuffer<float> UAV : register(u3); + +RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); + +RWBuffer<float> UAV3 : register(space5); + +float f : register(c5); + +int4 intv : register(c2); + +double dar[5] : register(c3); + +struct S { + int a; +}; + +S s : register(c10); + +// Compute Shader for UAV testing +[numthreads(8, 8, 1)] +[RootSignature(ROOT_SIGNATURE)] +void CSMain(uint3 id : SV_DispatchThreadID) +{ + In[0] = id; + Out[0] = In[0]; +} diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index e076283b65193..5c763c24a210a 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -166,7 +166,7 @@ void DXContainerGlobals::addRootSignature(Module &M, const auto &RS = RSA.getDescForFunction(EntryFunction); const auto &RS = RSA.getDescForFunction(EntryFunction); - if (!RS ) + if (!RS) return; SmallString<256> Data; diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 398dcbb8d1737..daf53fefe5f17 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -7,11 +7,14 @@ //===----------------------------------------------------------------------===// #include "DXILPostOptimizationValidation.h" +#include "DXILRootSignature.h" #include "DXILShaderFlags.h" #include "DirectX.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/Analysis/DXILResource.h" +#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsDirectX.h" @@ -85,7 +88,9 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { } static void reportErrors(Module &M, DXILResourceMap &DRM, - DXILResourceBindingInfo &DRBI) { + DXILResourceBindingInfo &DRBI, + RootSignatureBindingInfo &RSBI, + dxil::ModuleMetadataInfo &MMI) { if (DRM.hasInvalidCounterDirection()) reportInvalidDirection(M, DRM); @@ -94,6 +99,30 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in " "DXILResourceImplicitBinding pass"); + // Assuming this is used to validate only the root signature assigned to the + // entry function. + std::optional<mcdxbc::RootSignatureDesc> RootSigDesc = + RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry); + if (!RootSigDesc) + return; + + for (const mcdxbc::RootParameterInfo &Info : + RootSigDesc->ParametersContainer) { + const auto &[Type, Loc] = + RootSigDesc->ParametersContainer.getTypeAndLocForParameter( + Info.Location); + switch (Type) { + case llvm::to_underlying(dxbc::RootParameterType::CBV): + dxbc::RTS0::v2::RootDescriptor Desc = + RootSigDesc->ParametersContainer.getRootDescriptor(Loc); + + llvm::dxil::ResourceInfo::ResourceBinding Binding; + Binding.LowerBound = Desc.ShaderRegister; + Binding.Space = Desc.RegisterSpace; + Binding.Size = 1; + break; + } + } } } // namespace @@ -101,7 +130,10 @@ PreservedAnalyses DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) { DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M); DXILResourceBindingInfo &DRBI = MAM.getResult<DXILResourceBindingAnalysis>(M); - reportErrors(M, DRM, DRBI); + RootSignatureBindingInfo &RSBI = MAM.getResult<RootSignatureAnalysis>(M); + ModuleMetadataInfo &MMI = MAM.getResult<DXILMetadataAnalysis>(M); + + reportErrors(M, DRM, DRBI, RSBI, MMI); return PreservedAnalyses::all(); } @@ -113,7 +145,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass { getAnalysis<DXILResourceWrapperPass>().getResourceMap(); DXILResourceBindingInfo &DRBI = getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo(); - reportErrors(M, DRM, DRBI); + + RootSignatureBindingInfo &RSBI = + getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); + dxil::ModuleMetadataInfo &MMI = + getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); + + reportErrors(M, DRM, DRBI, RSBI, MMI); return false; } StringRef getPassName() const override { @@ -125,10 +163,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass { void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { AU.addRequired<DXILResourceWrapperPass>(); AU.addRequired<DXILResourceBindingWrapperPass>(); + AU.addRequired<RootSignatureAnalysisWrapper>(); + AU.addRequired<DXILMetadataAnalysisWrapperPass>(); AU.addPreserved<DXILResourceWrapperPass>(); AU.addPreserved<DXILResourceBindingWrapperPass>(); AU.addPreserved<DXILMetadataAnalysisWrapperPass>(); AU.addPreserved<ShaderFlagsAnalysisWrapper>(); + AU.addPreserved<RootSignatureAnalysisWrapper>(); } }; char DXILPostOptimizationValidationLegacy::ID = 0; diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 24b1a8d3d2abe..ecfc577d1b97d 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -37,28 +37,30 @@ enum class RootSignatureElementKind { }; class RootSignatureBindingInfo { - private: - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; +private: + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; - public: +public: using iterator = - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; - RootSignatureBindingInfo () = default; - RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {}; + RootSignatureBindingInfo() = default; + RootSignatureBindingInfo( + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) + : FuncToRsMap(Map){}; iterator find(const Function *F) { return FuncToRsMap.find(F); } iterator end() { return FuncToRsMap.end(); } - std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) { + std::optional<mcdxbc::RootSignatureDesc> + getDescForFunction(const Function *F) { const auto FuncRs = find(F); if (FuncRs == end()) return std::nullopt; return FuncRs->second; } - }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { @@ -66,13 +68,11 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { static AnalysisKey Key; public: - -RootSignatureAnalysis() = default; + RootSignatureAnalysis() = default; using Result = RootSignatureBindingInfo; - - RootSignatureBindingInfo - run(Module &M, ModuleAnalysisManager &AM); + + RootSignatureBindingInfo run(Module &M, ModuleAnalysisManager &AM); }; /// Wrapper pass for the legacy pass manager. @@ -89,8 +89,8 @@ class RootSignatureAnalysisWrapper : public ModulePass { RootSignatureAnalysisWrapper() : ModulePass(ID) {} - RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;} - + RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; } + bool runOnModule(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; >From a04eb9ff37d20499f05c7b1cc0ab3187f729609b Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Wed, 2 Jul 2025 17:58:56 +0000 Subject: [PATCH 03/13] adding validation --- .../SemaHLSL/RootSignature-Validation.hlsl | 28 ++++--------- .../DXILPostOptimizationValidation.cpp | 42 +++++++++++++++---- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl index 8a4a97f87cb65..62ba704b95c7d 100644 --- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl +++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl @@ -1,42 +1,30 @@ -// RUN: %clang_dxc -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify #define ROOT_SIGNATURE \ "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ - "CBV(b0, visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(SRV(t0, numDescriptors=3), visibility=SHADER_VISIBILITY_PIXEL), " \ - "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL), " \ - "DescriptorTable(UAV(u0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)" + "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)" cbuffer CB : register(b3, space2) { float a; } -StructuredBuffer<int> In : register(t0); +StructuredBuffer<int> In : register(t0, space0); RWStructuredBuffer<int> Out : register(u0); RWBuffer<float> UAV : register(u3); RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); -RWBuffer<float> UAV3 : register(space5); +RWBuffer<float> UAV3 : register(space0); -float f : register(c5); -int4 intv : register(c2); - -double dar[5] : register(c3); - -struct S { - int a; -}; - -S s : register(c10); // Compute Shader for UAV testing [numthreads(8, 8, 1)] [RootSignature(ROOT_SIGNATURE)] -void CSMain(uint3 id : SV_DispatchThreadID) +void CSMain(uint id : SV_GroupID) { - In[0] = id; - Out[0] = In[0]; + Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0]; } diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index daf53fefe5f17..3e542e502c2d5 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -10,6 +10,7 @@ #include "DXILRootSignature.h" #include "DXILShaderFlags.h" #include "DirectX.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" @@ -86,7 +87,9 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { } } } - + uint64_t combine_uint32_to_uint64(uint32_t high, uint32_t low) { + return (static_cast<uint64_t>(high) << 32) | low; + } static void reportErrors(Module &M, DXILResourceMap &DRM, DXILResourceBindingInfo &DRBI, RootSignatureBindingInfo &RSBI, @@ -101,18 +104,24 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, "DXILResourceImplicitBinding pass"); // Assuming this is used to validate only the root signature assigned to the // entry function. + //Start test stuff + if(MMI.EntryPropertyVec.size() == 0) + return; + std::optional<mcdxbc::RootSignatureDesc> RootSigDesc = RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry); if (!RootSigDesc) return; - for (const mcdxbc::RootParameterInfo &Info : - RootSigDesc->ParametersContainer) { + using MapT = llvm::IntervalMap<uint64_t, llvm::dxil::ResourceInfo::ResourceBinding, sizeof(llvm::dxil::ResourceInfo::ResourceBinding), llvm::IntervalMapInfo<uint64_t>>; + MapT::Allocator Allocator; + MapT BindingsMap(Allocator); + auto RSD = *RootSigDesc; + for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) { const auto &[Type, Loc] = - RootSigDesc->ParametersContainer.getTypeAndLocForParameter( - Info.Location); + RootSigDesc->ParametersContainer.getTypeAndLocForParameter(I); switch (Type) { - case llvm::to_underlying(dxbc::RootParameterType::CBV): + case llvm::to_underlying(dxbc::RootParameterType::CBV):{ dxbc::RTS0::v2::RootDescriptor Desc = RootSigDesc->ParametersContainer.getRootDescriptor(Loc); @@ -120,8 +129,27 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, Binding.LowerBound = Desc.ShaderRegister; Binding.Space = Desc.RegisterSpace; Binding.Size = 1; + + BindingsMap.insert(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1), Binding); break; } + // case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{ + // mcdxbc::DescriptorTable Table = + // RootSigDesc->ParametersContainer.getDescriptorTable(Loc); + // for (const dxbc::RTS0::v2::DescriptorRange &Range : Table){ + // Range. + // } + + // break; + // } + } + + } + + for(const auto &CBuf : DRM.cbuffers()) { + auto Binding = CBuf.getBinding(); + if(!BindingsMap.overlaps(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1))) + auto X = 1; } } } // namespace @@ -146,7 +174,7 @@ class DXILPostOptimizationValidationLegacy : public ModulePass { DXILResourceBindingInfo &DRBI = getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo(); - RootSignatureBindingInfo &RSBI = + RootSignatureBindingInfo& RSBI = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); dxil::ModuleMetadataInfo &MMI = getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); >From 5994b8f8f4ea24115a66c0046c8fc344905b41d4 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Wed, 2 Jul 2025 21:19:37 +0000 Subject: [PATCH 04/13] clean --- .../DXILPostOptimizationValidation.cpp | 6 +---- .../DirectX/DXILPostOptimizationValidation.h | 3 +++ llvm/lib/Target/DirectX/DXILRootSignature.h | 24 +++++++++---------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 3e542e502c2d5..4c29b56304391 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -10,12 +10,9 @@ #include "DXILRootSignature.h" #include "DXILShaderFlags.h" #include "DirectX.h" -#include "llvm/ADT/IntervalMap.h" -#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/Analysis/DXILResource.h" -#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsDirectX.h" @@ -173,8 +170,7 @@ class DXILPostOptimizationValidationLegacy : public ModulePass { getAnalysis<DXILResourceWrapperPass>().getResourceMap(); DXILResourceBindingInfo &DRBI = getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo(); - - RootSignatureBindingInfo& RSBI = + RootSignatureBindingInfo &RSBI = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); dxil::ModuleMetadataInfo &MMI = getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h index cb5e624514272..151843daf068d 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h @@ -14,6 +14,9 @@ #ifndef LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H #define LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H +#include "DXILRootSignature.h" +#include "llvm/ADT/IntervalMap.h" +#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/PassManager.h" namespace llvm { diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index ecfc577d1b97d..d0d5c7785bda3 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -37,30 +37,28 @@ enum class RootSignatureElementKind { }; class RootSignatureBindingInfo { -private: - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; + private: + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; -public: + public: using iterator = - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; - RootSignatureBindingInfo() = default; - RootSignatureBindingInfo( - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) - : FuncToRsMap(Map){}; +RootSignatureBindingInfo () = default; + RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {}; iterator find(const Function *F) { return FuncToRsMap.find(F); } iterator end() { return FuncToRsMap.end(); } - std::optional<mcdxbc::RootSignatureDesc> - getDescForFunction(const Function *F) { + std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function *F) { const auto FuncRs = find(F); if (FuncRs == end()) return std::nullopt; return FuncRs->second; } + }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { @@ -68,7 +66,7 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { static AnalysisKey Key; public: - RootSignatureAnalysis() = default; +RootSignatureAnalysis() = default; using Result = RootSignatureBindingInfo; @@ -88,8 +86,8 @@ class RootSignatureAnalysisWrapper : public ModulePass { using Result = RootSignatureBindingInfo; RootSignatureAnalysisWrapper() : ModulePass(ID) {} - - RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; } + + RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;} bool runOnModule(Module &M) override; >From e8b14bf32e47cf8c059d2f492e57a602375ceeaa Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Fri, 4 Jul 2025 02:03:26 +0000 Subject: [PATCH 05/13] implementing --- .../RootSignature-Validation-Fail.hlsl | 35 ++++ .../SemaHLSL/RootSignature-Validation.hlsl | 11 +- .../DXILPostOptimizationValidation.cpp | 166 +++++++++++++----- .../DirectX/DXILPostOptimizationValidation.h | 88 ++++++++++ llvm/lib/Target/DirectX/DXILRootSignature.h | 24 +-- .../RootSignature-DescriptorTable.ll | 4 +- 6 files changed, 271 insertions(+), 57 deletions(-) create mode 100644 clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl diff --git a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl new file mode 100644 index 0000000000000..b590ed67e7085 --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl @@ -0,0 +1,35 @@ +// RUN: not %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 | FileCheck %s + +// CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature +// CHECK: error: register srv (space=0, register=0) is not defined in Root Signature +// CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature + + +#define ROOT_SIGNATURE \ + "CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX), " \ + "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)" + +cbuffer CB : register(b3, space665) { + float a; +} + +StructuredBuffer<int> In : register(t0, space0); +RWStructuredBuffer<int> Out : register(u0); + +RWBuffer<float> UAV : register(u4294967295); + +RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); + +RWBuffer<float> UAV3 : register(space0); + + + +// Compute Shader for UAV testing +[numthreads(8, 8, 1)] +[RootSignature(ROOT_SIGNATURE)] +void CSMain(uint id : SV_GroupID) +{ + Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0]; +} diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl index 62ba704b95c7d..5a7f5baf00619 100644 --- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl +++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl @@ -1,19 +1,22 @@ +// RUN: %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 + +// expected-no-diagnostics + #define ROOT_SIGNATURE \ - "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \ "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \ + "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX), " \ "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)" -cbuffer CB : register(b3, space2) { +cbuffer CB : register(b3, space1) { float a; } StructuredBuffer<int> In : register(t0, space0); RWStructuredBuffer<int> Out : register(u0); -RWBuffer<float> UAV : register(u3); +RWBuffer<float> UAV : register(u4294967294); RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 4c29b56304391..23bb5d1a7f651 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -84,9 +84,57 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { } } } - uint64_t combine_uint32_to_uint64(uint32_t high, uint32_t low) { - return (static_cast<uint64_t>(high) << 32) | low; + +static void reportRegNotBound(Module &M, Twine Type, + ResourceInfo::ResourceBinding Binding) { + SmallString<128> Message; + raw_svector_ostream OS(Message); + OS << "register " << Type << " (space=" << Binding.Space + << ", register=" << Binding.LowerBound << ")" + << " is not defined in Root Signature"; + M.getContext().diagnose(DiagnosticInfoGeneric(Message)); +} + +static dxbc::ShaderVisibility +tripleToVisibility(llvm::Triple::EnvironmentType ET) { + assert((ET == Triple::Pixel || ET == Triple::Vertex || + ET == Triple::Geometry || ET == Triple::Hull || + ET == Triple::Domain || ET == Triple::Mesh || + ET == Triple::Compute) && + "Invalid Triple to shader stage conversion"); + + switch (ET) { + case Triple::Pixel: + return dxbc::ShaderVisibility::Pixel; + case Triple::Vertex: + return dxbc::ShaderVisibility::Vertex; + case Triple::Geometry: + return dxbc::ShaderVisibility::Geometry; + case Triple::Hull: + return dxbc::ShaderVisibility::Hull; + case Triple::Domain: + return dxbc::ShaderVisibility::Domain; + case Triple::Mesh: + return dxbc::ShaderVisibility::Mesh; + case Triple::Compute: + return dxbc::ShaderVisibility::All; + default: + llvm_unreachable("Invalid triple to shader stage conversion"); } +} + +std::optional<mcdxbc::RootSignatureDesc> +getRootSignature(RootSignatureBindingInfo &RSBI, + dxil::ModuleMetadataInfo &MMI) { + if (MMI.EntryPropertyVec.size() == 0) + return std::nullopt; + std::optional<mcdxbc::RootSignatureDesc> RootSigDesc = + RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry); + if (!RootSigDesc) + return std::nullopt; + return RootSigDesc; +} + static void reportErrors(Module &M, DXILResourceMap &DRM, DXILResourceBindingInfo &DRBI, RootSignatureBindingInfo &RSBI, @@ -99,57 +147,95 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in " "DXILResourceImplicitBinding pass"); - // Assuming this is used to validate only the root signature assigned to the - // entry function. - //Start test stuff - if(MMI.EntryPropertyVec.size() == 0) - return; - std::optional<mcdxbc::RootSignatureDesc> RootSigDesc = - RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry); - if (!RootSigDesc) - return; + if (auto RSD = getRootSignature(RSBI, MMI)) { + + RootSignatureBindingValidation Validation; + Validation.addRsBindingInfo(*RSD, tripleToVisibility(MMI.ShaderProfile)); + + for (const auto &CBuf : DRM.cbuffers()) { + ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + if (!Validation.checkCregBinding(Binding)) + reportRegNotBound(M, "cbuffer", Binding); + } + + for (const auto &CBuf : DRM.srvs()) { + ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + if (!Validation.checkTRegBinding(Binding)) + reportRegNotBound(M, "srv", Binding); + } - using MapT = llvm::IntervalMap<uint64_t, llvm::dxil::ResourceInfo::ResourceBinding, sizeof(llvm::dxil::ResourceInfo::ResourceBinding), llvm::IntervalMapInfo<uint64_t>>; - MapT::Allocator Allocator; - MapT BindingsMap(Allocator); - auto RSD = *RootSigDesc; - for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) { + for (const auto &CBuf : DRM.uavs()) { + ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + if (!Validation.checkURegBinding(Binding)) + reportRegNotBound(M, "uav", Binding); + } + } +} +} // namespace + +void RootSignatureBindingValidation::addRsBindingInfo( + mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) { + for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) { const auto &[Type, Loc] = - RootSigDesc->ParametersContainer.getTypeAndLocForParameter(I); + RSD.ParametersContainer.getTypeAndLocForParameter(I); + + const auto &Header = RSD.ParametersContainer.getHeader(I); switch (Type) { - case llvm::to_underlying(dxbc::RootParameterType::CBV):{ + case llvm::to_underlying(dxbc::RootParameterType::SRV): + case llvm::to_underlying(dxbc::RootParameterType::UAV): + case llvm::to_underlying(dxbc::RootParameterType::CBV): { dxbc::RTS0::v2::RootDescriptor Desc = - RootSigDesc->ParametersContainer.getRootDescriptor(Loc); + RSD.ParametersContainer.getRootDescriptor(Loc); - llvm::dxil::ResourceInfo::ResourceBinding Binding; - Binding.LowerBound = Desc.ShaderRegister; - Binding.Space = Desc.RegisterSpace; - Binding.Size = 1; + if (Header.ShaderVisibility == + llvm::to_underlying(dxbc::ShaderVisibility::All) || + Header.ShaderVisibility == llvm::to_underlying(Visibility)) + addRange(Desc, Type); + break; + } + case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): { + const mcdxbc::DescriptorTable &Table = + RSD.ParametersContainer.getDescriptorTable(Loc); - BindingsMap.insert(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1), Binding); + for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) { + if (Range.RangeType == + llvm::to_underlying(dxbc::DescriptorRangeType::Sampler)) + continue; + + if (Header.ShaderVisibility == + llvm::to_underlying(dxbc::ShaderVisibility::All) || + Header.ShaderVisibility == llvm::to_underlying(Visibility)) + addRange(Range); + } break; } - // case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{ - // mcdxbc::DescriptorTable Table = - // RootSigDesc->ParametersContainer.getDescriptorTable(Loc); - // for (const dxbc::RTS0::v2::DescriptorRange &Range : Table){ - // Range. - // } - - // break; - // } } - } +} - for(const auto &CBuf : DRM.cbuffers()) { - auto Binding = CBuf.getBinding(); - if(!BindingsMap.overlaps(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1))) - auto X = 1; - } +bool RootSignatureBindingValidation::checkCregBinding( + ResourceInfo::ResourceBinding Binding) { + return CRegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); +} + +bool RootSignatureBindingValidation::checkTRegBinding( + ResourceInfo::ResourceBinding Binding) { + return TRegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, Binding.LowerBound + Binding.Size)); +} + +bool RootSignatureBindingValidation::checkURegBinding( + ResourceInfo::ResourceBinding Binding) { + return URegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); } -} // namespace PreservedAnalyses DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) { diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h index 151843daf068d..58113bf9f93c7 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h @@ -21,6 +21,94 @@ namespace llvm { +static uint64_t combineUint32ToUint64(uint32_t High, uint32_t Low) { + return (static_cast<uint64_t>(High) << 32) | Low; +} + +class RootSignatureBindingValidation { + using MapT = + llvm::IntervalMap<uint64_t, dxil::ResourceInfo::ResourceBinding, + sizeof(llvm::dxil::ResourceInfo::ResourceBinding), + llvm::IntervalMapInfo<uint64_t>>; + +private: + MapT::Allocator Allocator; + MapT CRegBindingsMap; + MapT TRegBindingsMap; + MapT URegBindingsMap; + + void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) { + assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) || + Type == llvm::to_underlying(dxbc::RootParameterType::SRV) || + Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) && + "Invalid Type"); + + llvm::dxil::ResourceInfo::ResourceBinding Binding; + Binding.LowerBound = Desc.ShaderRegister; + Binding.Space = Desc.RegisterSpace; + Binding.Size = 1; + + uint64_t LowRange = + combineUint32ToUint64(Binding.Space, Binding.LowerBound); + uint64_t HighRange = combineUint32ToUint64( + Binding.Space, Binding.LowerBound + Binding.Size - 1); + + switch (Type) { + + case llvm::to_underlying(dxbc::RootParameterType::CBV): + CRegBindingsMap.insert(LowRange, HighRange, Binding); + return; + case llvm::to_underlying(dxbc::RootParameterType::SRV): + TRegBindingsMap.insert(LowRange, HighRange, Binding); + return; + case llvm::to_underlying(dxbc::RootParameterType::UAV): + URegBindingsMap.insert(LowRange, HighRange, Binding); + return; + } + llvm_unreachable("Invalid Type in add Range Method"); + } + + void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) { + + llvm::dxil::ResourceInfo::ResourceBinding Binding; + Binding.LowerBound = Range.BaseShaderRegister; + Binding.Space = Range.RegisterSpace; + Binding.Size = Range.NumDescriptors; + + uint64_t LowRange = + combineUint32ToUint64(Binding.Space, Binding.LowerBound); + uint64_t HighRange = combineUint32ToUint64( + Binding.Space, Binding.LowerBound + Binding.Size - 1); + + switch (Range.RangeType) { + case llvm::to_underlying(dxbc::DescriptorRangeType::CBV): + CRegBindingsMap.insert(LowRange, HighRange, Binding); + return; + case llvm::to_underlying(dxbc::DescriptorRangeType::SRV): + TRegBindingsMap.insert(LowRange, HighRange, Binding); + return; + case llvm::to_underlying(dxbc::DescriptorRangeType::UAV): + URegBindingsMap.insert(LowRange, HighRange, Binding); + return; + } + llvm_unreachable("Invalid Type in add Range Method"); + } + +public: + RootSignatureBindingValidation() + : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator), + URegBindingsMap(Allocator) {} + + void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD, + dxbc::ShaderVisibility Visibility); + + bool checkCregBinding(dxil::ResourceInfo::ResourceBinding Binding); + + bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding); + + bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding); +}; + class DXILPostOptimizationValidation : public PassInfoMixin<DXILPostOptimizationValidation> { public: diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index d0d5c7785bda3..ecfc577d1b97d 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -37,28 +37,30 @@ enum class RootSignatureElementKind { }; class RootSignatureBindingInfo { - private: - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; +private: + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap; - public: +public: using iterator = - SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator; -RootSignatureBindingInfo () = default; - RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {}; + RootSignatureBindingInfo() = default; + RootSignatureBindingInfo( + SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) + : FuncToRsMap(Map){}; iterator find(const Function *F) { return FuncToRsMap.find(F); } iterator end() { return FuncToRsMap.end(); } - std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function *F) { + std::optional<mcdxbc::RootSignatureDesc> + getDescForFunction(const Function *F) { const auto FuncRs = find(F); if (FuncRs == end()) return std::nullopt; return FuncRs->second; } - }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { @@ -66,7 +68,7 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { static AnalysisKey Key; public: -RootSignatureAnalysis() = default; + RootSignatureAnalysis() = default; using Result = RootSignatureBindingInfo; @@ -86,8 +88,8 @@ class RootSignatureAnalysisWrapper : public ModulePass { using Result = RootSignatureBindingInfo; RootSignatureAnalysisWrapper() : ModulePass(ID) {} - - RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;} + + RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; } bool runOnModule(Module &M) override; diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll index b516d66180247..8e9b4b43b11a6 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll @@ -16,7 +16,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements !5 = !{ !"DescriptorTable", i32 0, !6, !7 } -!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 } +!6 = !{ !"SRV", i32 1, i32 1, i32 0, i32 -1, i32 4 } !7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 } ; DXC: - Name: RTS0 @@ -35,7 +35,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } ; DXC-NEXT: RangesOffset: 44 ; DXC-NEXT: Ranges: ; DXC-NEXT: - RangeType: 0 -; DXC-NEXT: NumDescriptors: 0 +; DXC-NEXT: NumDescriptors: 1 ; DXC-NEXT: BaseShaderRegister: 1 ; DXC-NEXT: RegisterSpace: 0 ; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295 >From 8f40e83ab0db147e90070f15708d0a0f4e1a9d1f Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Fri, 4 Jul 2025 19:24:25 +0000 Subject: [PATCH 06/13] finish implementing && fix tests --- .../DXILPostOptimizationValidation.cpp | 45 +++++----------- .../DirectX/DXILPostOptimizationValidation.h | 54 ++++++++++++++----- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 5 +- ...criptorTable-AllValidFlagCombinationsV1.ll | 4 +- llvm/test/CodeGen/DirectX/llc-pipeline.ll | 1 + 5 files changed, 59 insertions(+), 50 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 23bb5d1a7f651..a52a04323514c 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -153,23 +153,29 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, RootSignatureBindingValidation Validation; Validation.addRsBindingInfo(*RSD, tripleToVisibility(MMI.ShaderProfile)); - for (const auto &CBuf : DRM.cbuffers()) { + for (const ResourceInfo &CBuf : DRM.cbuffers()) { ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); - if (!Validation.checkCregBinding(Binding)) + if (!Validation.checkCRegBinding(Binding)) reportRegNotBound(M, "cbuffer", Binding); } - for (const auto &CBuf : DRM.srvs()) { - ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + for (const ResourceInfo &SRV : DRM.srvs()) { + ResourceInfo::ResourceBinding Binding = SRV.getBinding(); if (!Validation.checkTRegBinding(Binding)) reportRegNotBound(M, "srv", Binding); } - for (const auto &CBuf : DRM.uavs()) { - ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + for (const ResourceInfo &UAV : DRM.uavs()) { + ResourceInfo::ResourceBinding Binding = UAV.getBinding(); if (!Validation.checkURegBinding(Binding)) reportRegNotBound(M, "uav", Binding); } + + for (const ResourceInfo &Sampler : DRM.samplers()) { + ResourceInfo::ResourceBinding Binding = Sampler.getBinding(); + if (!Validation.checkSamplerBinding(Binding)) + reportRegNotBound(M, "sampler", Binding); + } } } } // namespace @@ -199,10 +205,6 @@ void RootSignatureBindingValidation::addRsBindingInfo( RSD.ParametersContainer.getDescriptorTable(Loc); for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) { - if (Range.RangeType == - llvm::to_underlying(dxbc::DescriptorRangeType::Sampler)) - continue; - if (Header.ShaderVisibility == llvm::to_underlying(dxbc::ShaderVisibility::All) || Header.ShaderVisibility == llvm::to_underlying(Visibility)) @@ -214,29 +216,6 @@ void RootSignatureBindingValidation::addRsBindingInfo( } } -bool RootSignatureBindingValidation::checkCregBinding( - ResourceInfo::ResourceBinding Binding) { - return CRegBindingsMap.overlaps( - combineUint32ToUint64(Binding.Space, Binding.LowerBound), - combineUint32ToUint64(Binding.Space, - Binding.LowerBound + Binding.Size - 1)); -} - -bool RootSignatureBindingValidation::checkTRegBinding( - ResourceInfo::ResourceBinding Binding) { - return TRegBindingsMap.overlaps( - combineUint32ToUint64(Binding.Space, Binding.LowerBound), - combineUint32ToUint64(Binding.Space, Binding.LowerBound + Binding.Size)); -} - -bool RootSignatureBindingValidation::checkURegBinding( - ResourceInfo::ResourceBinding Binding) { - return URegBindingsMap.overlaps( - combineUint32ToUint64(Binding.Space, Binding.LowerBound), - combineUint32ToUint64(Binding.Space, - Binding.LowerBound + Binding.Size - 1)); -} - PreservedAnalyses DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) { DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M); diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h index 58113bf9f93c7..0fa0285425d7e 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h @@ -36,12 +36,13 @@ class RootSignatureBindingValidation { MapT CRegBindingsMap; MapT TRegBindingsMap; MapT URegBindingsMap; + MapT SamplersBindingsMap; void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) { assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) || Type == llvm::to_underlying(dxbc::RootParameterType::SRV) || Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) && - "Invalid Type"); + "Invalid Type in add Range Method"); llvm::dxil::ResourceInfo::ResourceBinding Binding; Binding.LowerBound = Desc.ShaderRegister; @@ -53,19 +54,20 @@ class RootSignatureBindingValidation { uint64_t HighRange = combineUint32ToUint64( Binding.Space, Binding.LowerBound + Binding.Size - 1); + assert(LowRange <= HighRange && "Invalid range configuration"); + switch (Type) { case llvm::to_underlying(dxbc::RootParameterType::CBV): CRegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; case llvm::to_underlying(dxbc::RootParameterType::SRV): TRegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; case llvm::to_underlying(dxbc::RootParameterType::UAV): URegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; } - llvm_unreachable("Invalid Type in add Range Method"); } void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) { @@ -80,33 +82,59 @@ class RootSignatureBindingValidation { uint64_t HighRange = combineUint32ToUint64( Binding.Space, Binding.LowerBound + Binding.Size - 1); + assert(LowRange <= HighRange && "Invalid range configuration"); + switch (Range.RangeType) { case llvm::to_underlying(dxbc::DescriptorRangeType::CBV): CRegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; case llvm::to_underlying(dxbc::DescriptorRangeType::SRV): TRegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; case llvm::to_underlying(dxbc::DescriptorRangeType::UAV): URegBindingsMap.insert(LowRange, HighRange, Binding); - return; + break; + case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler): + SamplersBindingsMap.insert(LowRange, HighRange, Binding); + break; } - llvm_unreachable("Invalid Type in add Range Method"); } public: RootSignatureBindingValidation() : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator), - URegBindingsMap(Allocator) {} + URegBindingsMap(Allocator), SamplersBindingsMap(Allocator) {} void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility); - bool checkCregBinding(dxil::ResourceInfo::ResourceBinding Binding); + bool checkCRegBinding(dxil::ResourceInfo::ResourceBinding Binding) { + return CRegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); + } - bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding); + bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding) { + return TRegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); + } - bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding); + bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding) { + return URegBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); + } + + bool checkSamplerBinding(dxil::ResourceInfo::ResourceBinding Binding) { + return SamplersBindingsMap.overlaps( + combineUint32ToUint64(Binding.Space, Binding.LowerBound), + combineUint32ToUint64(Binding.Space, + Binding.LowerBound + Binding.Size - 1)); + } }; class DXILPostOptimizationValidation diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 4094df160ef6f..2a68a4c324a09 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -635,8 +635,9 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M, //===----------------------------------------------------------------------===// bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { - FuncToRsMap = std::make_unique<RootSignatureBindingInfo>( - RootSignatureBindingInfo(analyzeModule(M))); + if (!FuncToRsMap) + FuncToRsMap = std::make_unique<RootSignatureBindingInfo>( + RootSignatureBindingInfo(analyzeModule(M))); return false; } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll index 9d89dbdd9107b..053721de1eb1f 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll @@ -13,7 +13,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !2 = !{ ptr @main, !3, i32 1 } ; function, root signature !3 = !{ !5 } ; list of root signature elements !5 = !{ !"DescriptorTable", i32 0, !6, !7 } -!6 = !{ !"Sampler", i32 0, i32 1, i32 0, i32 -1, i32 1 } +!6 = !{ !"Sampler", i32 1, i32 1, i32 0, i32 -1, i32 1 } !7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 3 } @@ -33,7 +33,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } ; DXC-NEXT: RangesOffset: 44 ; DXC-NEXT: Ranges: ; DXC-NEXT: - RangeType: 3 -; DXC-NEXT: NumDescriptors: 0 +; DXC-NEXT: NumDescriptors: 1 ; DXC-NEXT: BaseShaderRegister: 1 ; DXC-NEXT: RegisterSpace: 0 ; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295 diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index 2b29fd30a7a56..8d75249dc6ecb 100644 --- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll +++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll @@ -31,6 +31,7 @@ ; CHECK-NEXT: DXIL Module Metadata analysis ; CHECK-NEXT: DXIL Shader Flag Analysis ; CHECK-NEXT: DXIL Translate Metadata +; CHECK-NEXT: DXIL Root Signature Analysis ; CHECK-NEXT: DXIL Post Optimization Validation ; CHECK-NEXT: DXIL Op Lowering ; CHECK-NEXT: DXIL Prepare Module >From 28350b2dfe2a896b2199260953c1d061550badba Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Sat, 5 Jul 2025 00:35:07 +0000 Subject: [PATCH 07/13] fix issue --- llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 5c763c24a210a..6c8ae8eaaea77 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -160,11 +160,9 @@ void DXContainerGlobals::addRootSignature(Module &M, assert(MMI.EntryPropertyVec.size() == 1); - auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; const auto &RS = RSA.getDescForFunction(EntryFunction); - const auto &RS = RSA.getDescForFunction(EntryFunction); if (!RS) return; >From 4fd2e0bfdda5f87a3204982aa01d8b158945eadf Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Sat, 5 Jul 2025 00:37:12 +0000 Subject: [PATCH 08/13] sync parent --- llvm/lib/Target/DirectX/DXILRootSignature.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index ecfc577d1b97d..3832182277050 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -47,7 +47,7 @@ class RootSignatureBindingInfo { RootSignatureBindingInfo() = default; RootSignatureBindingInfo( SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) - : FuncToRsMap(Map){}; + : FuncToRsMap(Map) {}; iterator find(const Function *F) { return FuncToRsMap.find(F); } @@ -72,7 +72,10 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { using Result = RootSignatureBindingInfo; - RootSignatureBindingInfo run(Module &M, ModuleAnalysisManager &AM); + Result run(Module &M, ModuleAnalysisManager &AM); + +private: + std::unique_ptr<RootSignatureBindingInfo> AnalysisResult; }; /// Wrapper pass for the legacy pass manager. >From e25ee87104bbb7013da38761df2beee7c98f4a9a Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Sat, 5 Jul 2025 00:39:18 +0000 Subject: [PATCH 09/13] sync parent --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 2a68a4c324a09..5a53ea8a3631b 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -554,9 +554,12 @@ analyzeModule(Module &M) { AnalysisKey RootSignatureAnalysis::Key; -RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M, - ModuleAnalysisManager &AM) { - return RootSignatureBindingInfo(analyzeModule(M)); +RootSignatureAnalysis::Result +RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) { + if (!AnalysisResult) + AnalysisResult = std::make_unique<RootSignatureBindingInfo>( + RootSignatureBindingInfo(analyzeModule(M))); + return *AnalysisResult; } //===----------------------------------------------------------------------===// >From c16f15b4cd469a3f6efc2e4b0e098190d7fd0787 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 17:00:28 +0000 Subject: [PATCH 10/13] fix test --- clang/test/SemaHLSL/RootSignature-Validation.hlsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl index 5a7f5baf00619..c4ea897c6f490 100644 --- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl +++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl @@ -16,11 +16,11 @@ cbuffer CB : register(b3, space1) { StructuredBuffer<int> In : register(t0, space0); RWStructuredBuffer<int> Out : register(u0); -RWBuffer<float> UAV : register(u4294967294); +RWStructuredBuffer<float> UAV : register(u4294967294); -RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); +RWStructuredBuffer<float> UAV1 : register(u2), UAV2 : register(u4); -RWBuffer<float> UAV3 : register(space0); +RWStructuredBuffer<float> UAV3 : register(space0); >From 571a0ef25df4ffffe56cdc7d7274ebe9d23996be Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 20:31:43 +0000 Subject: [PATCH 11/13] fix tests --- .../RootSignature-Validation-Fail.hlsl | 35 ---- .../SemaHLSL/RootSignature-Validation.hlsl | 33 ---- .../DirectX/rootsignature-validation-fail.ll | 160 ++++++++++++++++++ .../DirectX/rootsignature-validation.ll | 149 ++++++++++++++++ 4 files changed, 309 insertions(+), 68 deletions(-) delete mode 100644 clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl delete mode 100644 clang/test/SemaHLSL/RootSignature-Validation.hlsl create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation.ll diff --git a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl deleted file mode 100644 index b590ed67e7085..0000000000000 --- a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: not %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 | FileCheck %s - -// CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature -// CHECK: error: register srv (space=0, register=0) is not defined in Root Signature -// CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature - - -#define ROOT_SIGNATURE \ - "CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX), " \ - "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)" - -cbuffer CB : register(b3, space665) { - float a; -} - -StructuredBuffer<int> In : register(t0, space0); -RWStructuredBuffer<int> Out : register(u0); - -RWBuffer<float> UAV : register(u4294967295); - -RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); - -RWBuffer<float> UAV3 : register(space0); - - - -// Compute Shader for UAV testing -[numthreads(8, 8, 1)] -[RootSignature(ROOT_SIGNATURE)] -void CSMain(uint id : SV_GroupID) -{ - Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0]; -} diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl deleted file mode 100644 index c4ea897c6f490..0000000000000 --- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 - -// expected-no-diagnostics - - -#define ROOT_SIGNATURE \ - "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \ - "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX), " \ - "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)" - -cbuffer CB : register(b3, space1) { - float a; -} - -StructuredBuffer<int> In : register(t0, space0); -RWStructuredBuffer<int> Out : register(u0); - -RWStructuredBuffer<float> UAV : register(u4294967294); - -RWStructuredBuffer<float> UAV1 : register(u2), UAV2 : register(u4); - -RWStructuredBuffer<float> UAV3 : register(space0); - - - -// Compute Shader for UAV testing -[numthreads(8, 8, 1)] -[RootSignature(ROOT_SIGNATURE)] -void CSMain(uint id : SV_GroupID) -{ - Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0]; -} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll new file mode 100644 index 0000000000000..54802c9e7ed22 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll @@ -0,0 +1,160 @@ +; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 + +; CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature +; CHECK: error: register srv (space=0, register=0) is not defined in Root Signature +; CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature + +; +; Resource Bindings: +; +; Name Type Format Dim ID HLSL Bind Count +; ------------------------------ ---------- ------- ----------- ------- -------------- --------- +; In texture struct r/o T0 t0 1 +; Out UAV struct r/w U0 u0 1 +; UAV3 UAV f32 buf U1 u1 1 +; UAV1 UAV f32 buf U2 u2 1 +; UAV UAV f32 buf U3 u4294967295 1 +; CB cbuffer NA NA CB0 cb3,space665 1 +; +; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl' +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxilv1.5-unknown-shadermodel6.5-compute" + +%__cblayout_CB = type <{ float }> +%"StructuredBuffer<int32_t>" = type { i32 } +%"RWStructuredBuffer<int32_t>" = type { i32 } +%"RWBuffer<float>" = type { float } +%CBuffer.CB = type { float } + +@CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison +@CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 +@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1 +@.str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1 +@.str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1 +@.str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1 +@.str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1 +@In = external constant %"StructuredBuffer<int32_t>" +@Out = external constant %"RWStructuredBuffer<int32_t>" +@UAV3 = external constant %"RWBuffer<float>" +@UAV1 = external constant %"RWBuffer<float>" +@UAV = external constant %"RWBuffer<float>" +@CB = external constant %CBuffer.CB + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) +define void @CSMain() local_unnamed_addr #1 { +entry: + %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str) + store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4 + %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str) + %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2) + %2 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr nonnull @.str.4) + %3 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6) + %4 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10) + %5 = tail call i32 @llvm.dx.group.id(i32 0) + %6 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0) + %7 = extractvalue { float, float, float, float } %6, 0 + %conv.i = uitofp i32 %5 to float + %add.i = fadd reassoc nnan ninf nsz arcp afn float %7, %conv.i + %8 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0) + %9 = extractvalue { i32, i1 } %8, 0 + %conv1.i = sitofp i32 %9 to float + %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %conv1.i + %10 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %2, i32 0) + %11 = extractvalue { float, i1 } %10, 0 + %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %11 + %12 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %3, i32 0) + %13 = extractvalue { float, i1 } %12, 0 + %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %13 + %14 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %4, i32 0) + %15 = extractvalue { float, i1 } %14, 0 + %add8.i = fadd reassoc nnan ninf nsz arcp afn float %add6.i, %15 + %conv9.i = fptosi float %add8.i to i32 + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv9.i) + ret void +} + +; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) +declare i32 @llvm.dx.group.id(i32) #2 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #0 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #3 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #3 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write) +declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #4 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #3 + +; uselistorder directives +uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 } +uselistorder ptr @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 } + +attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) } +attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { mustprogress nofree nosync nounwind willreturn memory(none) } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(read) } +attributes #4 = { nocallback nofree nosync nounwind willreturn memory(write) } + +!dx.rootsignatures = !{!0} +!llvm.module.flags = !{!9, !10} +!dx.valver = !{!11} +!llvm.ident = !{!12} +!dx.shaderModel = !{!13} +!dx.version = !{!14} +!dx.resources = !{!15} +!dx.entryPoints = !{!27} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!2, !3, !5, !7} +!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4} +!3 = !{!"DescriptorTable", i32 1, !4} +!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4} +!5 = !{!"DescriptorTable", i32 0, !6} +!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0} +!7 = !{!"DescriptorTable", i32 0, !8} +!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"frame-pointer", i32 2} +!11 = !{i32 1, i32 8} +!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"} +!13 = !{!"cs", i32 6, i32 5} +!14 = !{i32 1, i32 5} +!15 = !{!16, !19, !25, null} +!16 = !{!17} +!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18} +!18 = !{i32 1, i32 4} +!19 = !{!20, !21, !23, !24} +!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18} +!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 10, i1 false, i1 false, i1 false, !22} +!22 = !{i32 0, i32 9} +!23 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 10, i1 false, i1 false, i1 false, !22} +!24 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -1, i32 1, i32 10, i1 false, i1 false, i1 false, !22} +!25 = !{!26} +!26 = !{i32 0, ptr @CB, !"CB", i32 665, i32 3, i32 1, i32 4, null} +!27 = !{ptr @CSMain, !"CSMain", null, !15, !28} +!28 = !{i32 0, i64 16, i32 4, !29} +!29 = !{i32 8, i32 8, i32 1} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll new file mode 100644 index 0000000000000..eaf8512c284a7 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll @@ -0,0 +1,149 @@ +; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 +; expected-no-diagnostics + +; +; Resource Bindings: +; +; Name Type Format Dim ID HLSL Bind Count +; ------------------------------ ---------- ------- ----------- ------- -------------- --------- +; In texture struct r/o T0 t0 1 +; Out UAV struct r/w U0 u0 1 +; UAV3 UAV struct r/w U1 u1 1 +; UAV1 UAV struct r/w U2 u2 1 +; UAV UAV struct r/w U3 u4294967294 1 +; CB cbuffer NA NA CB0 cb3,space1 1 +; +; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation.hlsl' +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxilv1.5-unknown-shadermodel6.5-compute" + +%__cblayout_CB = type <{ float }> +%"StructuredBuffer<int32_t>" = type { i32 } +%"RWStructuredBuffer<int32_t>" = type { i32 } +%"RWStructuredBuffer<float>" = type { float } +%CBuffer.CB = type { float } + +@CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison +@CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 +@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1 +@.str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1 +@.str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1 +@.str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1 +@.str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1 +@In = external constant %"StructuredBuffer<int32_t>" +@Out = external constant %"RWStructuredBuffer<int32_t>" +@UAV3 = external constant %"RWStructuredBuffer<float>" +@UAV1 = external constant %"RWStructuredBuffer<float>" +@UAV = external constant %"RWStructuredBuffer<float>" +@CB = external constant %CBuffer.CB + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) +define void @CSMain() local_unnamed_addr #1 { +entry: + %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str) + store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4 + %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str) + %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2) + %2 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 -2, i32 1, i32 0, i1 false, ptr nonnull @.str.4) + %3 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6) + %4 = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10) + %5 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0) + %6 = extractvalue { float, float, float, float } %5, 0 + %7 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0) + %8 = extractvalue { i32, i1 } %7, 0 + %conv.i = sitofp i32 %8 to float + %add.i = fadd reassoc nnan ninf nsz arcp afn float %6, %conv.i + %9 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %2, i32 0, i32 0) + %10 = extractvalue { float, i1 } %9, 0 + %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %10 + %11 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %3, i32 0, i32 0) + %12 = extractvalue { float, i1 } %11, 0 + %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %12 + %13 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %4, i32 0, i32 0) + %14 = extractvalue { float, i1 } %13, 0 + %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %14 + %conv7.i = fptosi float %add6.i to i32 + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv7.i) + ret void +} + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32, i32, i32, i32, i1, ptr) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) #0 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #2 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32, i32) #2 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write) +declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #3 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #2 + +; uselistorder directives +uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 } +uselistorder ptr @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 } + +attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) } +attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) } + +!dx.rootsignatures = !{!0} +!llvm.module.flags = !{!9, !10} +!dx.valver = !{!11} +!llvm.ident = !{!12} +!dx.shaderModel = !{!13} +!dx.version = !{!14} +!dx.resources = !{!15} +!dx.entryPoints = !{!26} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!2, !3, !5, !7} +!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4} +!3 = !{!"DescriptorTable", i32 0, !4} +!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4} +!5 = !{!"DescriptorTable", i32 1, !6} +!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0} +!7 = !{!"DescriptorTable", i32 0, !8} +!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"frame-pointer", i32 2} +!11 = !{i32 1, i32 8} +!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"} +!13 = !{!"cs", i32 6, i32 5} +!14 = !{i32 1, i32 5} +!15 = !{!16, !19, !24, null} +!16 = !{!17} +!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18} +!18 = !{i32 1, i32 4} +!19 = !{!20, !21, !22, !23} +!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18} +!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !18} +!22 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 12, i1 false, i1 false, i1 false, !18} +!23 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -2, i32 1, i32 12, i1 false, i1 false, i1 false, !18} +!24 = !{!25} +!25 = !{i32 0, ptr @CB, !"CB", i32 1, i32 3, i32 1, i32 4, null} +!26 = !{ptr @CSMain, !"CSMain", null, !15, !27} +!27 = !{i32 0, i64 16, i32 4, !28} +!28 = !{i32 8, i32 8, i32 1} >From e0bc8623dba624c1d3b01bd73102b258df5cc006 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 21:18:45 +0000 Subject: [PATCH 12/13] add preserved --- llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 +- llvm/test/CodeGen/DirectX/llc-pipeline.ll | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index b6e8ce7d78b23..a6dfc11c9c44c 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -62,10 +62,10 @@ class DXContainerGlobals : public llvm::ModulePass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); AU.addRequired<ShaderFlagsAnalysisWrapper>(); - AU.addRequired<RootSignatureAnalysisWrapper>(); AU.addRequired<DXILMetadataAnalysisWrapperPass>(); AU.addRequired<DXILResourceTypeWrapperPass>(); AU.addRequired<DXILResourceWrapperPass>(); + AU.addPreserved<RootSignatureAnalysisWrapper>(); } }; diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index 8d75249dc6ecb..e8612f4213539 100644 --- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll +++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll @@ -40,7 +40,6 @@ ; CHECK-ASM-NEXT: Print Module IR ; CHECK-OBJ-NEXT: DXIL Embedder -; CHECK-OBJ-NEXT: DXIL Root Signature Analysis ; CHECK-OBJ-NEXT: DXContainer Global Emitter ; CHECK-OBJ-NEXT: FunctionPass Manager ; CHECK-OBJ-NEXT: Lazy Machine Block Frequency Analysis >From b5a0b32a43b04f9f20efb879a7b8644e937cfaf7 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 10 Jul 2025 17:46:07 +0000 Subject: [PATCH 13/13] addressing comments --- llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 07dbd51bed391..ccffa3fd0a3e2 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -106,4 +106,4 @@ class RootSignatureAnalysisPrinter } // namespace dxil } // namespace llvm -#endif +#endif // LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits