https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/123147
>From aabdfe7d6c6b6e27e9c2150c10199baa6638b6df Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Wed, 15 Jan 2025 17:30:00 +0000 Subject: [PATCH 01/18] adding metadata extraction --- .../llvm/Analysis/DXILMetadataAnalysis.h | 3 + llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 89 +++++++++++++++++++ .../lib/Target/DirectX/DXContainerGlobals.cpp | 24 +++++ 3 files changed, 116 insertions(+) diff --git a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h index cb535ac14f1c613..f420244ba111a45 100644 --- a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h +++ b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h @@ -11,9 +11,11 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/PassManager.h" +#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Pass.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/Triple.h" +#include <optional> namespace llvm { @@ -37,6 +39,7 @@ struct ModuleMetadataInfo { Triple::EnvironmentType ShaderProfile{Triple::UnknownEnvironment}; VersionTuple ValidatorVersion{}; SmallVector<EntryProperties> EntryPropertyVec{}; + std::optional<mcdxbc::RootSignatureDesc> RootSignatureDesc; void print(raw_ostream &OS) const; }; diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index a7f666a3f8b48f2..388e3853008eaec 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -15,12 +15,91 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" +#include "llvm/MC/DXContainerRootSignature.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include <memory> #define DEBUG_TYPE "dxil-metadata-analysis" using namespace llvm; using namespace dxil; +using namespace llvm::mcdxbc; + +static bool parseRootFlags(MDNode *RootFlagNode, RootSignatureDesc *Desc) { + + assert(RootFlagNode->getNumOperands() == 2 && + "Invalid format for RootFlag Element"); + auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); + auto Value = (RootSignatureFlags)Flag->getZExtValue(); + + if ((Value & ~RootSignatureFlags::ValidFlags) != RootSignatureFlags::None) + return true; + + Desc->Flags = Value; + return false; +} + +static bool parseRootSignatureElement(MDNode *Element, + RootSignatureDesc *Desc) { + MDString *ElementText = cast<MDString>(Element->getOperand(0)); + + assert(ElementText != nullptr && "First preoperty of element is not "); + + RootSignatureElementKind ElementKind = + StringSwitch<RootSignatureElementKind>(ElementText->getString()) + .Case("RootFlags", RootSignatureElementKind::RootFlags) + .Case("RootConstants", RootSignatureElementKind::RootConstants) + .Case("RootCBV", RootSignatureElementKind::RootDescriptor) + .Case("RootSRV", RootSignatureElementKind::RootDescriptor) + .Case("RootUAV", RootSignatureElementKind::RootDescriptor) + .Case("Sampler", RootSignatureElementKind::RootDescriptor) + .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable) + .Case("StaticSampler", RootSignatureElementKind::StaticSampler) + .Default(RootSignatureElementKind::None); + + switch (ElementKind) { + + case RootSignatureElementKind::RootFlags: { + return parseRootFlags(Element, Desc); + break; + } + + case RootSignatureElementKind::RootConstants: + case RootSignatureElementKind::RootDescriptor: + case RootSignatureElementKind::DescriptorTable: + case RootSignatureElementKind::StaticSampler: + case RootSignatureElementKind::None: + llvm_unreachable("Not Implemented yet"); + break; + } + + return true; +} + +bool parseRootSignature(RootSignatureDesc *Desc, int32_t Version, + NamedMDNode *Root) { + Desc->Version = Version; + bool HasError = false; + + for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { + // This should be an if, for error handling + MDNode *Node = cast<MDNode>(Root->getOperand(Sid)); + + // Not sure what use this for... + Metadata *Func = Node->getOperand(0).get(); + + // This should be an if, for error handling + MDNode *Elements = cast<MDNode>(Node->getOperand(1).get()); + + for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) { + MDNode *Element = cast<MDNode>(Elements->getOperand(Eid)); + + HasError = HasError || parseRootSignatureElement(Element, Desc); + } + } + return HasError; +} static ModuleMetadataInfo collectMetadataInfo(Module &M) { ModuleMetadataInfo MMDAI; @@ -28,6 +107,7 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { MMDAI.DXILVersion = TT.getDXILVersion(); MMDAI.ShaderModelVersion = TT.getOSVersion(); MMDAI.ShaderProfile = TT.getEnvironment(); + NamedMDNode *ValidatorVerNode = M.getNamedMetadata("dx.valver"); if (ValidatorVerNode) { auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand(0)); @@ -37,6 +117,15 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue()); } + NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); + if (RootSignatureNode) { + mcdxbc::RootSignatureDesc Desc; + + parseRootSignature(&Desc, 1, RootSignatureNode); + + MMDAI.RootSignatureDesc = Desc; + } + // For all HLSL Shader functions for (auto &F : M.functions()) { if (!F.hasFnAttribute("hlsl.shader")) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 7a0bd6a7c886923..7ab11ce757e436c 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -23,9 +23,11 @@ #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/MC/DXContainerPSVInfo.h" +#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Pass.h" #include "llvm/Support/MD5.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include <optional> using namespace llvm; using namespace llvm::dxil; @@ -41,6 +43,7 @@ class DXContainerGlobals : public llvm::ModulePass { GlobalVariable *buildSignature(Module &M, Signature &Sig, StringRef Name, StringRef SectionName); void addSignature(Module &M, SmallVector<GlobalValue *> &Globals); + void addRootSignature(Module &M, SmallVector<GlobalValue *> &Globals); void addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV); void addPipelineStateValidationInfo(Module &M, SmallVector<GlobalValue *> &Globals); @@ -73,6 +76,7 @@ bool DXContainerGlobals::runOnModule(Module &M) { Globals.push_back(getFeatureFlags(M)); Globals.push_back(computeShaderHash(M)); addSignature(M, Globals); + addRootSignature(M, Globals); addPipelineStateValidationInfo(M, Globals); appendToCompilerUsed(M, Globals); return true; @@ -144,6 +148,26 @@ void DXContainerGlobals::addSignature(Module &M, Globals.emplace_back(buildSignature(M, OutputSig, "dx.osg1", "OSG1")); } +void DXContainerGlobals::addRootSignature(Module &M, + SmallVector<GlobalValue *> &Globals) { + + std::optional<RootSignatureDesc> Desc = + getAnalysis<DXILMetadataAnalysisWrapperPass>() + .getModuleMetadata() + .RootSignatureDesc; + if (!Desc.has_value()) + return; + + SmallString<256> Data; + raw_svector_ostream OS(Data); + RootSignatureDescWriter writer(&Desc.value()); + writer.write(OS); + + Constant *Constant = + ConstantDataArray::getString(M.getContext(), Data, /*AddNull*/ false); + Globals.emplace_back(buildContainerGlobal(M, Constant, "dx.rts0", "RTS0")); +} + void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) { const DXILBindingMap &DBM = getAnalysis<DXILResourceBindingWrapperPass>().getBindingMap(); >From 4f6f941e3410e6aab982a73572d5ab2fa2cc1520 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 00:36:11 +0000 Subject: [PATCH 02/18] moving root signature to it's own pass --- .../llvm/Analysis/DXILMetadataAnalysis.h | 2 - llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 84 ---------- llvm/lib/MC/CMakeLists.txt | 1 - llvm/lib/Target/DirectX/CMakeLists.txt | 2 +- .../lib/Target/DirectX/DXContainerGlobals.cpp | 15 +- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 146 ++++++++++++++++++ llvm/lib/Target/DirectX/DXILRootSignature.h | 75 +++++++++ llvm/lib/Target/DirectX/DirectX.h | 3 + .../Target/DirectX/DirectXTargetMachine.cpp | 1 + .../ContainerData/RootSignature-Flags.ll | 38 +++++ 10 files changed, 271 insertions(+), 96 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILRootSignature.cpp create mode 100644 llvm/lib/Target/DirectX/DXILRootSignature.h create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll diff --git a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h index f420244ba111a45..dcc3237f57802f9 100644 --- a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h +++ b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h @@ -11,7 +11,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/PassManager.h" -#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Pass.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/Triple.h" @@ -39,7 +38,6 @@ struct ModuleMetadataInfo { Triple::EnvironmentType ShaderProfile{Triple::UnknownEnvironment}; VersionTuple ValidatorVersion{}; SmallVector<EntryProperties> EntryPropertyVec{}; - std::optional<mcdxbc::RootSignatureDesc> RootSignatureDesc; void print(raw_ostream &OS) const; }; diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index 388e3853008eaec..15e72bf17515b15 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -15,7 +15,6 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" -#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <memory> @@ -24,82 +23,8 @@ using namespace llvm; using namespace dxil; -using namespace llvm::mcdxbc; -static bool parseRootFlags(MDNode *RootFlagNode, RootSignatureDesc *Desc) { - assert(RootFlagNode->getNumOperands() == 2 && - "Invalid format for RootFlag Element"); - auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); - auto Value = (RootSignatureFlags)Flag->getZExtValue(); - - if ((Value & ~RootSignatureFlags::ValidFlags) != RootSignatureFlags::None) - return true; - - Desc->Flags = Value; - return false; -} - -static bool parseRootSignatureElement(MDNode *Element, - RootSignatureDesc *Desc) { - MDString *ElementText = cast<MDString>(Element->getOperand(0)); - - assert(ElementText != nullptr && "First preoperty of element is not "); - - RootSignatureElementKind ElementKind = - StringSwitch<RootSignatureElementKind>(ElementText->getString()) - .Case("RootFlags", RootSignatureElementKind::RootFlags) - .Case("RootConstants", RootSignatureElementKind::RootConstants) - .Case("RootCBV", RootSignatureElementKind::RootDescriptor) - .Case("RootSRV", RootSignatureElementKind::RootDescriptor) - .Case("RootUAV", RootSignatureElementKind::RootDescriptor) - .Case("Sampler", RootSignatureElementKind::RootDescriptor) - .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable) - .Case("StaticSampler", RootSignatureElementKind::StaticSampler) - .Default(RootSignatureElementKind::None); - - switch (ElementKind) { - - case RootSignatureElementKind::RootFlags: { - return parseRootFlags(Element, Desc); - break; - } - - case RootSignatureElementKind::RootConstants: - case RootSignatureElementKind::RootDescriptor: - case RootSignatureElementKind::DescriptorTable: - case RootSignatureElementKind::StaticSampler: - case RootSignatureElementKind::None: - llvm_unreachable("Not Implemented yet"); - break; - } - - return true; -} - -bool parseRootSignature(RootSignatureDesc *Desc, int32_t Version, - NamedMDNode *Root) { - Desc->Version = Version; - bool HasError = false; - - for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { - // This should be an if, for error handling - MDNode *Node = cast<MDNode>(Root->getOperand(Sid)); - - // Not sure what use this for... - Metadata *Func = Node->getOperand(0).get(); - - // This should be an if, for error handling - MDNode *Elements = cast<MDNode>(Node->getOperand(1).get()); - - for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) { - MDNode *Element = cast<MDNode>(Elements->getOperand(Eid)); - - HasError = HasError || parseRootSignatureElement(Element, Desc); - } - } - return HasError; -} static ModuleMetadataInfo collectMetadataInfo(Module &M) { ModuleMetadataInfo MMDAI; @@ -117,15 +42,6 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue()); } - NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); - if (RootSignatureNode) { - mcdxbc::RootSignatureDesc Desc; - - parseRootSignature(&Desc, 1, RootSignatureNode); - - MMDAI.RootSignatureDesc = Desc; - } - // For all HLSL Shader functions for (auto &F : M.functions()) { if (!F.hasFnAttribute("hlsl.shader")) diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index f49f14c848b9023..e1d19196c8766a7 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -1,7 +1,6 @@ add_llvm_component_library(LLVMMC ConstantPools.cpp DXContainerPSVInfo.cpp - DXContainerRootSignature.cpp ELFObjectWriter.cpp GOFFObjectWriter.cpp MCAsmBackend.cpp diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt index 26315db891b577a..89fe494dea71ccd 100644 --- a/llvm/lib/Target/DirectX/CMakeLists.txt +++ b/llvm/lib/Target/DirectX/CMakeLists.txt @@ -33,7 +33,7 @@ add_llvm_target(DirectXCodeGen DXILResourceAccess.cpp DXILShaderFlags.cpp DXILTranslateMetadata.cpp - + DXILRootSignature.cpp LINK_COMPONENTS Analysis AsmPrinter diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 7ab11ce757e436c..833a22a9b3e81ee 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "DXILShaderFlags.h" +#include "DXILRootSignature.h" #include "DirectX.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -23,7 +24,6 @@ #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/MC/DXContainerPSVInfo.h" -#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Pass.h" #include "llvm/Support/MD5.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -63,6 +63,7 @@ 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<DXILResourceBindingWrapperPass>(); @@ -151,17 +152,15 @@ void DXContainerGlobals::addSignature(Module &M, void DXContainerGlobals::addRootSignature(Module &M, SmallVector<GlobalValue *> &Globals) { - std::optional<RootSignatureDesc> Desc = - getAnalysis<DXILMetadataAnalysisWrapperPass>() - .getModuleMetadata() - .RootSignatureDesc; - if (!Desc.has_value()) + std::optional<ModuleRootSignature> MRS = + getAnalysis<RootSignatureAnalysisWrapper>() + .getRootSignature(); + if (!MRS.has_value()) return; SmallString<256> Data; raw_svector_ostream OS(Data); - RootSignatureDescWriter writer(&Desc.value()); - writer.write(OS); + MRS->write(OS); Constant *Constant = ConstantDataArray::getString(M.getContext(), Data, /*AddNull*/ false); diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp new file mode 100644 index 000000000000000..4a51198d97ac347 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -0,0 +1,146 @@ +//===- DXILRootSignature.cpp - DXIL Root Signature helper objects ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file This file contains helper objects and APIs for working with DXIL +/// Root Signatures. +/// +//===----------------------------------------------------------------------===// +#include "DXILRootSignature.h" +#include "DirectX.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/BinaryFormat/DXContainer.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" + +using namespace llvm; +using namespace llvm::dxil; + +static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { + + assert(RootFlagNode->getNumOperands() == 2 && + "Invalid format for RootFlag Element"); + auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); + auto Value = Flag->getZExtValue(); + + // Root Element validation, as specified: https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation + if ((Value & ~0x80000fff) != 0) + return true; + + MRS->Flags = Value; + return false; +} + +static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) { + MDString *ElementText = cast<MDString>(Element->getOperand(0)); + + assert(ElementText != nullptr && "First preoperty of element is not "); + + RootSignatureElementKind ElementKind = + StringSwitch<RootSignatureElementKind>(ElementText->getString()) + .Case("RootFlags", RootSignatureElementKind::RootFlags) + .Case("RootConstants", RootSignatureElementKind::RootConstants) + .Case("RootCBV", RootSignatureElementKind::RootDescriptor) + .Case("RootSRV", RootSignatureElementKind::RootDescriptor) + .Case("RootUAV", RootSignatureElementKind::RootDescriptor) + .Case("Sampler", RootSignatureElementKind::RootDescriptor) + .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable) + .Case("StaticSampler", RootSignatureElementKind::StaticSampler) + .Default(RootSignatureElementKind::None); + + switch (ElementKind) { + + case RootSignatureElementKind::RootFlags: { + return parseRootFlags(MRS, Element); + break; + } + + case RootSignatureElementKind::RootConstants: + case RootSignatureElementKind::RootDescriptor: + case RootSignatureElementKind::DescriptorTable: + case RootSignatureElementKind::StaticSampler: + case RootSignatureElementKind::None: + llvm_unreachable("Not Implemented yet"); + break; + } + + return true; +} + +bool ModuleRootSignature::parse( int32_t Version, + NamedMDNode *Root) { + this->Version = Version; + bool HasError = false; + + for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { + // This should be an if, for error handling + MDNode *Node = cast<MDNode>(Root->getOperand(Sid)); + + // Not sure what use this for... + Metadata *Func = Node->getOperand(0).get(); + + // This should be an if, for error handling + MDNode *Elements = cast<MDNode>(Node->getOperand(1).get()); + + for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) { + MDNode *Element = cast<MDNode>(Elements->getOperand(Eid)); + + HasError = HasError || parseRootSignatureElement(this, Element); + } + } + return HasError; +} + +void ModuleRootSignature::write(raw_ostream &OS) { + dxbc::RootSignatureDesc Out{this->Version, this->Flags}; + + if (sys::IsBigEndianHost) { + Out.swapBytes(); + } + + OS.write(reinterpret_cast<const char *>(&Out), sizeof(dxbc::RootSignatureDesc)); +} + +AnalysisKey RootSignatureAnalysis::Key; + +ModuleRootSignature RootSignatureAnalysis::run(Module &M, + ModuleAnalysisManager &AM) { + ModuleRootSignature MRSI; + + NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); + if (RootSignatureNode) { + MRSI.parse(1, RootSignatureNode); + } + + return MRSI; + +} + + +//===----------------------------------------------------------------------===// +bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { + ModuleRootSignature MRS; + + NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); + if (RootSignatureNode) { + MRS.parse(1, RootSignatureNode); + this->MRS = MRS; + } + + + return false; +} + +void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); +} + +char RootSignatureAnalysisWrapper::ID = 0; + +INITIALIZE_PASS(RootSignatureAnalysisWrapper, "dx-root-signature-analysis", + "DXIL Root Signature Analysis", true, true) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h new file mode 100644 index 000000000000000..fdfd6c41c0af371 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -0,0 +1,75 @@ +//===- DXILRootSignature.h - DXIL Root Signature helper objects ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file This file contains helper objects and APIs for working with DXIL +/// Root Signatures. +/// +//===----------------------------------------------------------------------===// + + +#include "llvm/IR/Metadata.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include <optional> + +namespace llvm { +namespace dxil { + + + enum class RootSignatureElementKind { + None = 0, + RootFlags = 1, + RootConstants = 2, + RootDescriptor = 3, + DescriptorTable = 4, + StaticSampler = 5 + }; + + struct ModuleRootSignature { + uint32_t Version; + uint32_t Flags; + + ModuleRootSignature() = default; + + bool parse( int32_t Version, NamedMDNode *Root); + void write(raw_ostream &OS); + }; + + class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { + friend AnalysisInfoMixin<RootSignatureAnalysis>; + static AnalysisKey Key; + + public: + RootSignatureAnalysis() = default; + + using Result = ModuleRootSignature; + + ModuleRootSignature run(Module &M, ModuleAnalysisManager &AM); + }; + + /// Wrapper pass for the legacy pass manager. + /// + /// This is required because the passes that will depend on this are codegen + /// passes which run through the legacy pass manager. + class RootSignatureAnalysisWrapper : public ModulePass { + std::optional<ModuleRootSignature> MRS; + + public: + static char ID; + + RootSignatureAnalysisWrapper() : ModulePass(ID) {} + + const std::optional<ModuleRootSignature> &getRootSignature() { return MRS; } + + bool runOnModule(Module &M) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + }; + +} // namespace dxil +} // namespace llvm diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h index add23587de7d583..953ac3eb8209878 100644 --- a/llvm/lib/Target/DirectX/DirectX.h +++ b/llvm/lib/Target/DirectX/DirectX.h @@ -77,6 +77,9 @@ void initializeDXILPrettyPrinterLegacyPass(PassRegistry &); /// Initializer for dxil::ShaderFlagsAnalysisWrapper pass. void initializeShaderFlagsAnalysisWrapperPass(PassRegistry &); +/// Initializer for dxil::RootSignatureAnalysisWrapper pass. +void initializeRootSignatureAnalysisWrapperPass(PassRegistry &); + /// Initializer for DXContainerGlobals pass. void initializeDXContainerGlobalsPass(PassRegistry &); diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index ecb1bf775f85786..93745d7a5cb0d2b 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -61,6 +61,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { initializeDXILTranslateMetadataLegacyPass(*PR); initializeDXILResourceMDWrapperPass(*PR); initializeShaderFlagsAnalysisWrapperPass(*PR); + initializeRootSignatureAnalysisWrapperPass(*PR); initializeDXILFinalizeLinkageLegacyPass(*PR); } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll new file mode 100644 index 000000000000000..ffbf5e9ffd1d325 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -0,0 +1,38 @@ +; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s +; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: @dx.rts0 = private constant [8 x i8] c"{{.*}}", section "RTS0", align 4 + + +define void @main() #0 { +entry: + ret void +} + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3 } ; function, root signature +!3 = !{ !4 } ; list of root signature elements +!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout + + +; DXC: - Name: RTS0 +; DXC-NEXT: Size: 8 +; DXC-NEXT: RootSignature: +; DXC-NEXT: Version: 1 +; DXC-NEXT: AllowInputAssemblerInputLayout: true +; DXC-NEXT: DenyVertexShaderRootAccess: false +; DXC-NEXT: DenyHullShaderRootAccess: false +; DXC-NEXT: DenyDomainShaderRootAccess: false +; DXC-NEXT: DenyGeometryShaderRootAccess: false +; DXC-NEXT: DenyPixelShaderRootAccess: false +; DXC-NEXT: AllowStreamOutput: false +; DXC-NEXT: LocalRootSignature: false +; DXC-NEXT: DenyAmplificationShaderRootAccess: false +; DXC-NEXT: DenyMeshShaderRootAccess: false +; DXC-NEXT: CBVSRVUAVHeapDirectlyIndexed: false +; DXC-NEXT: SamplerHeapDirectlyIndexed: false >From a7f778412de28258703b51aed85699e413491e29 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 00:37:14 +0000 Subject: [PATCH 03/18] formating --- llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 2 - .../lib/Target/DirectX/DXContainerGlobals.cpp | 5 +- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 48 ++++++------ llvm/lib/Target/DirectX/DXILRootSignature.h | 77 +++++++++---------- 4 files changed, 64 insertions(+), 68 deletions(-) diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index 15e72bf17515b15..197b7e422092c6b 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -24,8 +24,6 @@ using namespace llvm; using namespace dxil; - - static ModuleMetadataInfo collectMetadataInfo(Module &M) { ModuleMetadataInfo MMDAI; Triple TT(Triple(M.getTargetTriple())); diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 833a22a9b3e81ee..ac70bd3771dadf2 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "DXILShaderFlags.h" #include "DXILRootSignature.h" +#include "DXILShaderFlags.h" #include "DirectX.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -153,8 +153,7 @@ void DXContainerGlobals::addRootSignature(Module &M, SmallVector<GlobalValue *> &Globals) { std::optional<ModuleRootSignature> MRS = - getAnalysis<RootSignatureAnalysisWrapper>() - .getRootSignature(); + getAnalysis<RootSignatureAnalysisWrapper>().getRootSignature(); if (!MRS.has_value()) return; diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 4a51198d97ac347..89621868a93368f 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -1,4 +1,5 @@ -//===- DXILRootSignature.cpp - DXIL Root Signature helper objects ---------------===// +//===- DXILRootSignature.cpp - DXIL Root Signature helper objects +//---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,7 +29,8 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); auto Value = Flag->getZExtValue(); - // Root Element validation, as specified: https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation + // Root Element validation, as specified: + // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation if ((Value & ~0x80000fff) != 0) return true; @@ -36,7 +38,8 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { return false; } -static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) { +static bool parseRootSignatureElement(ModuleRootSignature *MRS, + MDNode *Element) { MDString *ElementText = cast<MDString>(Element->getOperand(0)); assert(ElementText != nullptr && "First preoperty of element is not "); @@ -72,8 +75,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) return true; } -bool ModuleRootSignature::parse( int32_t Version, - NamedMDNode *Root) { +bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { this->Version = Version; bool HasError = false; @@ -103,37 +105,35 @@ void ModuleRootSignature::write(raw_ostream &OS) { Out.swapBytes(); } - OS.write(reinterpret_cast<const char *>(&Out), sizeof(dxbc::RootSignatureDesc)); + OS.write(reinterpret_cast<const char *>(&Out), + sizeof(dxbc::RootSignatureDesc)); } AnalysisKey RootSignatureAnalysis::Key; ModuleRootSignature RootSignatureAnalysis::run(Module &M, - ModuleAnalysisManager &AM) { - ModuleRootSignature MRSI; + ModuleAnalysisManager &AM) { + ModuleRootSignature MRSI; - NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); - if (RootSignatureNode) { - MRSI.parse(1, RootSignatureNode); - } - - return MRSI; + NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); + if (RootSignatureNode) { + MRSI.parse(1, RootSignatureNode); + } + return MRSI; } - //===----------------------------------------------------------------------===// bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { ModuleRootSignature MRS; - NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); - if (RootSignatureNode) { - MRS.parse(1, RootSignatureNode); - this->MRS = MRS; - } - + NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); + if (RootSignatureNode) { + MRS.parse(1, RootSignatureNode); + this->MRS = MRS; + } - return false; + return false; } void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { @@ -142,5 +142,5 @@ void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { char RootSignatureAnalysisWrapper::ID = 0; -INITIALIZE_PASS(RootSignatureAnalysisWrapper, "dx-root-signature-analysis", - "DXIL Root Signature Analysis", true, true) +INITIALIZE_PASS(RootSignatureAnalysisWrapper, "dx-root-signature-analysis", + "DXIL Root Signature Analysis", true, true) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index fdfd6c41c0af371..de82afcdc8c4677 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -1,4 +1,5 @@ -//===- DXILRootSignature.h - DXIL Root Signature helper objects ---------------===// +//===- DXILRootSignature.h - DXIL Root Signature helper objects +//---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +12,6 @@ /// //===----------------------------------------------------------------------===// - #include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" @@ -20,56 +20,55 @@ namespace llvm { namespace dxil { +enum class RootSignatureElementKind { + None = 0, + RootFlags = 1, + RootConstants = 2, + RootDescriptor = 3, + DescriptorTable = 4, + StaticSampler = 5 +}; - enum class RootSignatureElementKind { - None = 0, - RootFlags = 1, - RootConstants = 2, - RootDescriptor = 3, - DescriptorTable = 4, - StaticSampler = 5 - }; - - struct ModuleRootSignature { - uint32_t Version; - uint32_t Flags; +struct ModuleRootSignature { + uint32_t Version; + uint32_t Flags; - ModuleRootSignature() = default; + ModuleRootSignature() = default; - bool parse( int32_t Version, NamedMDNode *Root); - void write(raw_ostream &OS); - }; + bool parse(int32_t Version, NamedMDNode *Root); + void write(raw_ostream &OS); +}; - class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { - friend AnalysisInfoMixin<RootSignatureAnalysis>; - static AnalysisKey Key; +class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { + friend AnalysisInfoMixin<RootSignatureAnalysis>; + static AnalysisKey Key; - public: - RootSignatureAnalysis() = default; +public: + RootSignatureAnalysis() = default; - using Result = ModuleRootSignature; + using Result = ModuleRootSignature; - ModuleRootSignature run(Module &M, ModuleAnalysisManager &AM); - }; + ModuleRootSignature run(Module &M, ModuleAnalysisManager &AM); +}; - /// Wrapper pass for the legacy pass manager. - /// - /// This is required because the passes that will depend on this are codegen - /// passes which run through the legacy pass manager. - class RootSignatureAnalysisWrapper : public ModulePass { - std::optional<ModuleRootSignature> MRS; +/// Wrapper pass for the legacy pass manager. +/// +/// This is required because the passes that will depend on this are codegen +/// passes which run through the legacy pass manager. +class RootSignatureAnalysisWrapper : public ModulePass { + std::optional<ModuleRootSignature> MRS; - public: - static char ID; +public: + static char ID; - RootSignatureAnalysisWrapper() : ModulePass(ID) {} + RootSignatureAnalysisWrapper() : ModulePass(ID) {} - const std::optional<ModuleRootSignature> &getRootSignature() { return MRS; } + const std::optional<ModuleRootSignature> &getRootSignature() { return MRS; } - bool runOnModule(Module &M) override; + bool runOnModule(Module &M) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - }; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; } // namespace dxil } // namespace llvm >From bf3b2e0ed560e5776391db1511997b7278b9a122 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 00:42:54 +0000 Subject: [PATCH 04/18] removing useless imports --- llvm/include/llvm/Analysis/DXILMetadataAnalysis.h | 1 - llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 3 --- 2 files changed, 4 deletions(-) diff --git a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h index dcc3237f57802f9..cb535ac14f1c613 100644 --- a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h +++ b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h @@ -14,7 +14,6 @@ #include "llvm/Pass.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/Triple.h" -#include <optional> namespace llvm { diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index 197b7e422092c6b..a7f666a3f8b48f2 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -15,9 +15,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" -#include <memory> #define DEBUG_TYPE "dxil-metadata-analysis" @@ -30,7 +28,6 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { MMDAI.DXILVersion = TT.getDXILVersion(); MMDAI.ShaderModelVersion = TT.getOSVersion(); MMDAI.ShaderProfile = TT.getEnvironment(); - NamedMDNode *ValidatorVerNode = M.getNamedMetadata("dx.valver"); if (ValidatorVerNode) { auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand(0)); >From 16b4d03d316c40f1f97cb766d9ae979185132807 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 19:22:31 +0000 Subject: [PATCH 05/18] fixing pr changes --- llvm/lib/ObjectYAML/DXContainerYAML.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp index 0869fd4fa978587..afcc093cf045687 100644 --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Support/ScopedPrinter.h" +#include <cstdint> namespace llvm { >From e0433700ff8ddc13d88876075deea7116715e8c8 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 20:06:13 +0000 Subject: [PATCH 06/18] adding some asserts --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 89621868a93368f..024743b9f81a6cc 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include <cassert> using namespace llvm; using namespace llvm::dxil; @@ -31,8 +32,7 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { // Root Element validation, as specified: // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation - if ((Value & ~0x80000fff) != 0) - return true; + assert((Value & ~0x80000fff) != 0 && "Invalid flag for RootFlag Element"); MRS->Flags = Value; return false; @@ -41,8 +41,7 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) { MDString *ElementText = cast<MDString>(Element->getOperand(0)); - - assert(ElementText != nullptr && "First preoperty of element is not "); + assert(ElementText != nullptr && "First preoperty of element is not a string"); RootSignatureElementKind ElementKind = StringSwitch<RootSignatureElementKind>(ElementText->getString()) @@ -84,13 +83,14 @@ bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { MDNode *Node = cast<MDNode>(Root->getOperand(Sid)); // Not sure what use this for... - Metadata *Func = Node->getOperand(0).get(); + // Metadata *Func = Node->getOperand(0).get(); - // This should be an if, for error handling MDNode *Elements = cast<MDNode>(Node->getOperand(1).get()); + assert(Elements && "Invalid Metadata type on root signature"); for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) { MDNode *Element = cast<MDNode>(Elements->getOperand(Eid)); + assert(Element && "Invalid Metadata type on root element"); HasError = HasError || parseRootSignatureElement(this, Element); } >From 57bf935dccd2f4aaaa211984a77b94a28ef267bc Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 16 Jan 2025 20:11:36 +0000 Subject: [PATCH 07/18] format --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 024743b9f81a6cc..cabaec3671078e4 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -41,7 +41,8 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) { MDString *ElementText = cast<MDString>(Element->getOperand(0)); - assert(ElementText != nullptr && "First preoperty of element is not a string"); + assert(ElementText != nullptr && + "First preoperty of element is not a string"); RootSignatureElementKind ElementKind = StringSwitch<RootSignatureElementKind>(ElementText->getString()) >From 1f8c0a5c34d1f3f5350c8282c7d65ea9753d5de9 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Sat, 18 Jan 2025 00:24:53 +0000 Subject: [PATCH 08/18] fixing assert --- llvm/lib/MC/CMakeLists.txt | 1 + llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 7 ++++++- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 13 +------------ llvm/lib/Target/DirectX/DXILRootSignature.h | 1 - .../DirectX/ContainerData/RootSignature-Flags.ll | 16 +++------------- 5 files changed, 11 insertions(+), 27 deletions(-) diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index e1d19196c8766a7..f49f14c848b9023 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_component_library(LLVMMC ConstantPools.cpp DXContainerPSVInfo.cpp + DXContainerRootSignature.cpp ELFObjectWriter.cpp GOFFObjectWriter.cpp MCAsmBackend.cpp diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index ac70bd3771dadf2..c090d1074250a03 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/MC/DXContainerPSVInfo.h" +#include "llvm/MC/DXContainerRootSignature.h" #include "llvm/Pass.h" #include "llvm/Support/MD5.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -159,7 +160,11 @@ void DXContainerGlobals::addRootSignature(Module &M, SmallString<256> Data; raw_svector_ostream OS(Data); - MRS->write(OS); + + RootSignatureHeader RSH; + RSH.Flags = MRS->Flags; + RSH.Version = MRS->Version; + RSH.write(OS); Constant *Constant = ConstantDataArray::getString(M.getContext(), Data, /*AddNull*/ false); diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index cabaec3671078e4..5ee9eea68b9e600 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -32,7 +32,7 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { // Root Element validation, as specified: // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation - assert((Value & ~0x80000fff) != 0 && "Invalid flag for RootFlag Element"); + assert((Value & ~0x80000fff) == 0 && "Invalid flag for RootFlag Element"); MRS->Flags = Value; return false; @@ -99,17 +99,6 @@ bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { return HasError; } -void ModuleRootSignature::write(raw_ostream &OS) { - dxbc::RootSignatureDesc Out{this->Version, this->Flags}; - - if (sys::IsBigEndianHost) { - Out.swapBytes(); - } - - OS.write(reinterpret_cast<const char *>(&Out), - sizeof(dxbc::RootSignatureDesc)); -} - AnalysisKey RootSignatureAnalysis::Key; ModuleRootSignature RootSignatureAnalysis::run(Module &M, diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index de82afcdc8c4677..3bbbaa12b079842 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -36,7 +36,6 @@ struct ModuleRootSignature { ModuleRootSignature() = default; bool parse(int32_t Version, NamedMDNode *Root); - void write(raw_ostream &OS); }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll index ffbf5e9ffd1d325..20253efbb8e5c51 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -3,7 +3,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: @dx.rts0 = private constant [8 x i8] c"{{.*}}", section "RTS0", align 4 +; CHECK: @dx.rts0 = private constant [12 x i8] c"{{.*}}", section "RTS0", align 4 define void @main() #0 { @@ -21,18 +21,8 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } ; DXC: - Name: RTS0 -; DXC-NEXT: Size: 8 +; DXC-NEXT: Size: 12 ; DXC-NEXT: RootSignature: +; DXC-NEXT: Size: 8 ; DXC-NEXT: Version: 1 ; DXC-NEXT: AllowInputAssemblerInputLayout: true -; DXC-NEXT: DenyVertexShaderRootAccess: false -; DXC-NEXT: DenyHullShaderRootAccess: false -; DXC-NEXT: DenyDomainShaderRootAccess: false -; DXC-NEXT: DenyGeometryShaderRootAccess: false -; DXC-NEXT: DenyPixelShaderRootAccess: false -; DXC-NEXT: AllowStreamOutput: false -; DXC-NEXT: LocalRootSignature: false -; DXC-NEXT: DenyAmplificationShaderRootAccess: false -; DXC-NEXT: DenyMeshShaderRootAccess: false -; DXC-NEXT: CBVSRVUAVHeapDirectlyIndexed: false -; DXC-NEXT: SamplerHeapDirectlyIndexed: false >From 0905b8341c5baa6225b5f8fcd51455c80c160593 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 27 Jan 2025 23:45:45 +0000 Subject: [PATCH 09/18] cleaning --- llvm/lib/ObjectYAML/DXContainerYAML.cpp | 1 - llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp index afcc093cf045687..0869fd4fa978587 100644 --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Support/ScopedPrinter.h" -#include <cstdint> namespace llvm { diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index c090d1074250a03..36e7cedbdaee0cb 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -28,7 +28,6 @@ #include "llvm/Pass.h" #include "llvm/Support/MD5.h" #include "llvm/Transforms/Utils/ModuleUtils.h" -#include <optional> using namespace llvm; using namespace llvm::dxil; >From 77e85444c8ebd747046267d10d5ac221eb912b40 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Wed, 29 Jan 2025 18:36:55 +0000 Subject: [PATCH 10/18] clean up --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 2 -- llvm/test/CodeGen/DirectX/llc-pipeline.ll | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 5ee9eea68b9e600..71ca8a91bc3fe09 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -14,11 +14,9 @@ #include "DXILRootSignature.h" #include "DirectX.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include <cassert> using namespace llvm; using namespace llvm::dxil; diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index b07155724941467..fc0a7833ea2f073 100644 --- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll +++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll @@ -33,6 +33,7 @@ ; 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 1351fb06360ace76419d9d5991695d4b80c5eca2 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 30 Jan 2025 00:22:01 +0000 Subject: [PATCH 11/18] addressing comments --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 89 ++++++++++++------- llvm/lib/Target/DirectX/DXILRootSignature.h | 2 + .../ContainerData/RootSignature-Error.ll | 17 ++++ .../RootSignature-Flags-Error.ll | 19 ++++ .../RootSignature-Flags-Validation-Error.ll | 19 ++++ .../RootSignature-RootElement-Error.ll | 18 ++++ 6 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 71ca8a91bc3fe09..52c7ad8e249379e 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -1,5 +1,4 @@ -//===- DXILRootSignature.cpp - DXIL Root Signature helper objects -//---------------===// +//===- DXILRootSignature.cpp - DXIL Root Signature helper objects ----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,23 +13,31 @@ #include "DXILRootSignature.h" #include "DirectX.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include <cstdint> using namespace llvm; using namespace llvm::dxil; +static bool reportError(Twine Message) { + report_fatal_error(Message, false); + return true; +} + static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { - assert(RootFlagNode->getNumOperands() == 2 && - "Invalid format for RootFlag Element"); + if (RootFlagNode->getNumOperands() != 2) + return reportError("Invalid format for RootFlag Element"); + auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); - auto Value = Flag->getZExtValue(); + uint32_t Value = Flag->getZExtValue(); // Root Element validation, as specified: // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation - assert((Value & ~0x80000fff) == 0 && "Invalid flag for RootFlag Element"); + if ((Value & ~0x80000fff) != 0) + return reportError("Invalid flag value for RootFlag"); MRS->Flags = Value; return false; @@ -39,8 +46,8 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { static bool parseRootSignatureElement(ModuleRootSignature *MRS, MDNode *Element) { MDString *ElementText = cast<MDString>(Element->getOperand(0)); - assert(ElementText != nullptr && - "First preoperty of element is not a string"); + if (ElementText == nullptr) + return reportError("Invalid format for Root Element"); RootSignatureElementKind ElementKind = StringSwitch<RootSignatureElementKind>(ElementText->getString()) @@ -66,7 +73,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS, case RootSignatureElementKind::DescriptorTable: case RootSignatureElementKind::StaticSampler: case RootSignatureElementKind::None: - llvm_unreachable("Not Implemented yet"); + return reportError("Invalid Root Element: " + ElementText->getString()); break; } @@ -77,19 +84,37 @@ bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { this->Version = Version; bool HasError = false; + /** Root Signature are specified as following in the metadata: + + !dx.rootsignatures = !{!2} ; list of function/root signature pairs + !2 = !{ ptr @main, !3 } ; function, root signature + !3 = !{ !4, !5, !6, !7 } ; list of root signature elements + + So for each MDNode inside dx.rootsignatures NamedMDNode + (the Root parameter of this function), the parsing process needs + to loop through each of it's operand and process the pairs function + signature pair. + */ + for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { - // This should be an if, for error handling - MDNode *Node = cast<MDNode>(Root->getOperand(Sid)); + MDNode *Node = dyn_cast<MDNode>(Root->getOperand(Sid)); + + if (Node == nullptr || Node->getNumOperands() != 2) + return reportError("Invalid format for Root Signature Definition. Pairs " + "of function, root signature expected."); + + // Get the Root Signature Description from the function signature pair. + MDNode *RS = dyn_cast<MDNode>(Node->getOperand(1).get()); - // Not sure what use this for... - // Metadata *Func = Node->getOperand(0).get(); + if (RS == nullptr) + return reportError("Missing Root Signature Metadata node."); - MDNode *Elements = cast<MDNode>(Node->getOperand(1).get()); - assert(Elements && "Invalid Metadata type on root signature"); + // Loop through the Root Elements of the root signature. + for (unsigned int Eid = 0; Eid < RS->getNumOperands(); Eid++) { - for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) { - MDNode *Element = cast<MDNode>(Elements->getOperand(Eid)); - assert(Element && "Invalid Metadata type on root element"); + MDNode *Element = dyn_cast<MDNode>(RS->getOperand(Eid)); + if (Element == nullptr) + return reportError("Missing Root Element Metadata Node."); HasError = HasError || parseRootSignatureElement(this, Element); } @@ -97,29 +122,29 @@ bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { return HasError; } -AnalysisKey RootSignatureAnalysis::Key; - -ModuleRootSignature RootSignatureAnalysis::run(Module &M, - ModuleAnalysisManager &AM) { - ModuleRootSignature MRSI; +ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M) { + ModuleRootSignature MRS; NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); if (RootSignatureNode) { - MRSI.parse(1, RootSignatureNode); + if (MRS.parse(1, RootSignatureNode)) + llvm_unreachable("Invalid Root Signature Metadata."); } - return MRSI; + return MRS; +} + +AnalysisKey RootSignatureAnalysis::Key; + +ModuleRootSignature RootSignatureAnalysis::run(Module &M, + ModuleAnalysisManager &AM) { + return ModuleRootSignature::analyzeModule(M); } //===----------------------------------------------------------------------===// bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { - ModuleRootSignature MRS; - NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); - if (RootSignatureNode) { - MRS.parse(1, RootSignatureNode); - this->MRS = MRS; - } + this->MRS = MRS = ModuleRootSignature::analyzeModule(M); return false; } diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 3bbbaa12b079842..0439deea6451a67 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -36,6 +36,8 @@ struct ModuleRootSignature { ModuleRootSignature() = default; bool parse(int32_t Version, NamedMDNode *Root); + + static ModuleRootSignature analyzeModule(Module &M); }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll new file mode 100644 index 000000000000000..cbcd8e56c1c0463 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll @@ -0,0 +1,17 @@ +; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: LLVM ERROR: Invalid format for Root Signature Definition. Pairs of function, root signature expected. + + +define void @main() #0 { +entry: + ret void +} + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!1} ; list of function/root signature pairs +!1= !{ !"RootFlags" } ; function, root signature diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll new file mode 100644 index 000000000000000..9b4208011bba508 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll @@ -0,0 +1,19 @@ +; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: LLVM ERROR: Invalid Root Element: NOTRootFlags + + +define void @main() #0 { +entry: + ret void +} + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3 } ; function, root signature +!3 = !{ !4 } ; list of root signature elements +!4 = !{ !"NOTRootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll new file mode 100644 index 000000000000000..85e6f4d6748d5c4 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll @@ -0,0 +1,19 @@ +; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: LLVM ERROR: Invalid flag value for RootFlag + + +define void @main() #0 { +entry: + ret void +} + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3 } ; function, root signature +!3 = !{ !4 } ; list of root signature elements +!4 = !{ !"RootFlags", i32 2147487744 } ; 1 = allow_input_assembler_input_layout diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll new file mode 100644 index 000000000000000..501e3438943a3c9 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll @@ -0,0 +1,18 @@ +; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: LLVM ERROR: Missing Root Element Metadata Node. + + +define void @main() #0 { +entry: + ret void +} + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3 } ; function, root signature +!3 = !{ !"NOTRootElements" } ; list of root signature elements >From 09e645aec09371cd145cf42f54809d8ae0832ce5 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 30 Jan 2025 18:33:23 +0000 Subject: [PATCH 12/18] removing version --- llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 +- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 5 ++--- llvm/lib/Target/DirectX/DXILRootSignature.h | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 36e7cedbdaee0cb..37108f92718df81 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -162,7 +162,7 @@ void DXContainerGlobals::addRootSignature(Module &M, RootSignatureHeader RSH; RSH.Flags = MRS->Flags; - RSH.Version = MRS->Version; + RSH.write(OS); Constant *Constant = diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 52c7ad8e249379e..c86be5bd9eb676c 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -80,8 +80,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS, return true; } -bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { - this->Version = Version; +bool ModuleRootSignature::parse(NamedMDNode *Root) { bool HasError = false; /** Root Signature are specified as following in the metadata: @@ -127,7 +126,7 @@ ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M) { NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); if (RootSignatureNode) { - if (MRS.parse(1, RootSignatureNode)) + if (MRS.parse(RootSignatureNode)) llvm_unreachable("Invalid Root Signature Metadata."); } diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 0439deea6451a67..f89fb0f00b5a4d5 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -30,12 +30,11 @@ enum class RootSignatureElementKind { }; struct ModuleRootSignature { - uint32_t Version; uint32_t Flags; ModuleRootSignature() = default; - bool parse(int32_t Version, NamedMDNode *Root); + bool parse(NamedMDNode *Root); static ModuleRootSignature analyzeModule(Module &M); }; >From 5a44b6286fd8da48d46927d031f442a41eca2840 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 30 Jan 2025 22:29:30 +0000 Subject: [PATCH 13/18] fix test --- .../CodeGen/DirectX/ContainerData/RootSignature-Flags.ll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll index 20253efbb8e5c51..b44d31c5b385746 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -3,7 +3,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: @dx.rts0 = private constant [12 x i8] c"{{.*}}", section "RTS0", align 4 +; CHECK: @dx.rts0 = private constant [8 x i8] c"{{.*}}", section "RTS0", align 4 define void @main() #0 { @@ -11,6 +11,9 @@ entry: ret void } + + + attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } @@ -21,8 +24,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } ; DXC: - Name: RTS0 -; DXC-NEXT: Size: 12 +; DXC-NEXT: Size: 8 ; DXC-NEXT: RootSignature: ; DXC-NEXT: Size: 8 -; DXC-NEXT: Version: 1 ; DXC-NEXT: AllowInputAssemblerInputLayout: true >From d1a79b3678375e587460844419a65a74b2ba7412 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Fri, 31 Jan 2025 00:42:33 +0000 Subject: [PATCH 14/18] addressing PR Comments --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 5 ++--- llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index c86be5bd9eb676c..109069eb66dea52 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -95,10 +95,9 @@ bool ModuleRootSignature::parse(NamedMDNode *Root) { signature pair. */ - for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { - MDNode *Node = dyn_cast<MDNode>(Root->getOperand(Sid)); + for (const MDNode *Node : Root->operands()) { - if (Node == nullptr || Node->getNumOperands() != 2) + if (Node->getNumOperands() != 2) return reportError("Invalid format for Root Signature Definition. Pairs " "of function, root signature expected."); diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index f89fb0f00b5a4d5..5bbea29d22ae50a 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -30,7 +30,7 @@ enum class RootSignatureElementKind { }; struct ModuleRootSignature { - uint32_t Flags; + uint32_t Flags = 0; ModuleRootSignature() = default; >From 9f8e51255b6c2f23761bab88478094da282311db Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 3 Feb 2025 21:32:59 +0000 Subject: [PATCH 15/18] fix test --- .../DirectX/ContainerData/RootSignature-Flags.ll | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll index b44d31c5b385746..c3e38c44c619445 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -3,7 +3,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: @dx.rts0 = private constant [8 x i8] c"{{.*}}", section "RTS0", align 4 +; CHECK: @dx.rts0 = private constant [24 x i8] c"{{.*}}", section "RTS0", align 4 define void @main() #0 { @@ -23,8 +23,12 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout -; DXC: - Name: RTS0 -; DXC-NEXT: Size: 8 -; DXC-NEXT: RootSignature: -; DXC-NEXT: Size: 8 -; DXC-NEXT: AllowInputAssemblerInputLayout: true +; DXC: - Name: RTS0 +; DXC-NEXT: Size: 24 +; DXC-NEXT: RootSignature: +; DXC-NEXT: Version: 2 +; DXC-NEXT: NumParameters: 0 +; DXC-NEXT: RootParametersOffset: 0 +; DXC-NEXT: NumStaticSamplers: 0 +; DXC-NEXT: StaticSamplersOffset: 0 +; DXC-NEXT: AllowInputAssemblerInputLayout: true >From 5c7ed7e42803423cb9771fbf895ef1878b4ed803 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 4 Feb 2025 00:07:43 +0000 Subject: [PATCH 16/18] filtering root signatures not associated with entry function --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 57 ++++++++++++++++--- llvm/lib/Target/DirectX/DXILRootSignature.h | 4 +- .../ContainerData/RootSignature-Flags.ll | 1 - 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 109069eb66dea52..984505b3fb85b81 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -14,9 +14,12 @@ #include "DirectX.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Module.h" -#include <cstdint> +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" using namespace llvm; using namespace llvm::dxil; @@ -80,7 +83,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS, return true; } -bool ModuleRootSignature::parse(NamedMDNode *Root) { +bool ModuleRootSignature::parse(NamedMDNode *Root, const Function *EF) { bool HasError = false; /** Root Signature are specified as following in the metadata: @@ -96,11 +99,25 @@ bool ModuleRootSignature::parse(NamedMDNode *Root) { */ for (const MDNode *Node : Root->operands()) { - if (Node->getNumOperands() != 2) return reportError("Invalid format for Root Signature Definition. Pairs " "of function, root signature expected."); + Metadata *MD = Node->getOperand(0).get(); + if (auto *VAM = llvm::dyn_cast<llvm::ValueAsMetadata>(MD)) { + llvm::Value *V = VAM->getValue(); + if (Function *F = dyn_cast<Function>(V)) { + if (F != EF) + continue; + } else { + return reportError( + "Root Signature MD node, first element is not a function."); + } + } else { + return reportError( + "Root Signature MD node, first element is not a function."); + } + // Get the Root Signature Description from the function signature pair. MDNode *RS = dyn_cast<MDNode>(Node->getOperand(1).get()); @@ -120,12 +137,13 @@ bool ModuleRootSignature::parse(NamedMDNode *Root) { return HasError; } -ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M) { +ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M, + const Function *F) { ModuleRootSignature MRS; NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); if (RootSignatureNode) { - if (MRS.parse(RootSignatureNode)) + if (MRS.parse(RootSignatureNode, F)) llvm_unreachable("Invalid Root Signature Metadata."); } @@ -136,22 +154,43 @@ AnalysisKey RootSignatureAnalysis::Key; ModuleRootSignature RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) { - return ModuleRootSignature::analyzeModule(M); + auto MMI = AM.getResult<DXILMetadataAnalysis>(M); + + if (MMI.ShaderProfile == Triple::Library) + return ModuleRootSignature(); + + assert(MMI.EntryPropertyVec.size() == 1); + + const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; + return ModuleRootSignature::analyzeModule(M, EntryFunction); } //===----------------------------------------------------------------------===// bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { - this->MRS = MRS = ModuleRootSignature::analyzeModule(M); + dxil::ModuleMetadataInfo &MMI = + getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); + + if (MMI.ShaderProfile == Triple::Library) + return false; + assert(MMI.EntryPropertyVec.size() == 1); + + const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; + this->MRS = MRS = ModuleRootSignature::analyzeModule(M, EntryFunction); return false; } void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addRequired<DXILMetadataAnalysisWrapperPass>(); } char RootSignatureAnalysisWrapper::ID = 0; -INITIALIZE_PASS(RootSignatureAnalysisWrapper, "dx-root-signature-analysis", - "DXIL Root Signature Analysis", true, true) +INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper, + "dx-root-signature-analysis", + "DXIL Root Signature Analysis", true, true) +INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass) +INITIALIZE_PASS_END(RootSignatureAnalysisWrapper, "dx-root-signature-analysis", + "DXIL Root Signature Analysis", true, true) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 5bbea29d22ae50a..0650ffa7edf415d 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -34,9 +34,9 @@ struct ModuleRootSignature { ModuleRootSignature() = default; - bool parse(NamedMDNode *Root); + bool parse(NamedMDNode *Root, const Function *F); - static ModuleRootSignature analyzeModule(Module &M); + static ModuleRootSignature analyzeModule(Module &M, const Function *F); }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll index c3e38c44c619445..cf00609a7307eb3 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -5,7 +5,6 @@ target triple = "dxil-unknown-shadermodel6.0-compute" ; CHECK: @dx.rts0 = private constant [24 x i8] c"{{.*}}", section "RTS0", align 4 - define void @main() #0 { entry: ret void >From 93f7c4c87d2f60358371eabf07bc3512ac336587 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 4 Feb 2025 01:17:18 +0000 Subject: [PATCH 17/18] separating parsing and validation --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 37 ++++++++++++------- llvm/lib/Target/DirectX/DXILRootSignature.h | 7 +++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 984505b3fb85b81..c85291186f61807 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -29,25 +29,18 @@ static bool reportError(Twine Message) { return true; } -static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { +bool ModuleRootSignature::parseRootFlags(MDNode *RootFlagNode) { if (RootFlagNode->getNumOperands() != 2) return reportError("Invalid format for RootFlag Element"); auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); - uint32_t Value = Flag->getZExtValue(); + this->Flags = Flag->getZExtValue(); - // Root Element validation, as specified: - // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation - if ((Value & ~0x80000fff) != 0) - return reportError("Invalid flag value for RootFlag"); - - MRS->Flags = Value; return false; } -static bool parseRootSignatureElement(ModuleRootSignature *MRS, - MDNode *Element) { +bool ModuleRootSignature::parseRootSignatureElement(MDNode *Element) { MDString *ElementText = cast<MDString>(Element->getOperand(0)); if (ElementText == nullptr) return reportError("Invalid format for Root Element"); @@ -67,7 +60,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS, switch (ElementKind) { case RootSignatureElementKind::RootFlags: { - return parseRootFlags(MRS, Element); + return parseRootFlags(Element); break; } @@ -131,19 +124,35 @@ bool ModuleRootSignature::parse(NamedMDNode *Root, const Function *EF) { if (Element == nullptr) return reportError("Missing Root Element Metadata Node."); - HasError = HasError || parseRootSignatureElement(this, Element); + HasError = HasError || parseRootSignatureElement(Element); } } return HasError; } +bool ModuleRootSignature::validateRootFlag() { + // Root Element validation, as specified: + // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation + if ((Flags & ~0x80000fff) != 0) + return reportError("Invalid flag value for RootFlag"); + + return false; +} + +bool ModuleRootSignature::validate() { + if (validateRootFlag()) + return reportError("Invalid flag value for RootFlag"); + + return false; +} + ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M, const Function *F) { ModuleRootSignature MRS; NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); if (RootSignatureNode) { - if (MRS.parse(RootSignatureNode, F)) + if (MRS.parse(RootSignatureNode, F) || MRS.validate()) llvm_unreachable("Invalid Root Signature Metadata."); } @@ -176,7 +185,7 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { assert(MMI.EntryPropertyVec.size() == 1); const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; - this->MRS = MRS = ModuleRootSignature::analyzeModule(M, EntryFunction); + MRS = ModuleRootSignature::analyzeModule(M, EntryFunction); return false; } diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index 0650ffa7edf415d..f79597721c3501f 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -33,10 +33,15 @@ struct ModuleRootSignature { uint32_t Flags = 0; ModuleRootSignature() = default; + static ModuleRootSignature analyzeModule(Module &M, const Function *F); +private: bool parse(NamedMDNode *Root, const Function *F); + bool parseRootSignatureElement(MDNode *Element); + bool parseRootFlags(MDNode *RootFlagNode); - static ModuleRootSignature analyzeModule(Module &M, const Function *F); + bool validate(); + bool validateRootFlag(); }; class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { >From 5aac761b8a254dfa7a02c4e182091ce795cf8579 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Thu, 6 Feb 2025 01:32:09 +0000 Subject: [PATCH 18/18] improve error handling --- llvm/include/llvm/BinaryFormat/DXContainer.h | 12 ++---- llvm/lib/Object/DXContainer.cpp | 17 +++----- .../lib/Target/DirectX/DXContainerGlobals.cpp | 10 +++-- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 43 ++++++++----------- llvm/lib/Target/DirectX/DXILRootSignature.h | 27 ++++++++---- .../ContainerData/RootSignature-Error.ll | 2 +- .../RootSignature-Flags-Error.ll | 4 +- .../RootSignature-Flags-Validation-Error.ll | 6 +-- .../RootSignature-RootElement-Error.ll | 2 +- 9 files changed, 61 insertions(+), 62 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h index c219aa819795e83..7bcf6f2bc7db58f 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainer.h +++ b/llvm/include/llvm/BinaryFormat/DXContainer.h @@ -550,16 +550,12 @@ static_assert(sizeof(ProgramSignatureElement) == 32, struct RootSignatureValidations { - static Expected<uint32_t> validateRootFlag(uint32_t Flags) { - if ((Flags & ~0x80000fff) != 0) - return llvm::make_error<BinaryStreamError>("Invalid flag"); - return Flags; + static bool validateRootFlag(uint32_t Flags) { + return (Flags & ~0x80000fff) != 0; } - static Expected<uint32_t> validateVersion(uint32_t Version) { - if (Version < 1 || Version > 2) - return llvm::make_error<BinaryStreamError>("Invalid Version"); - return Version; + static bool validateVersion(uint32_t Version) { + return (Version < 1 || Version > 2); } }; diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp index 4a5f58180804512..460d4a10207b6b9 100644 --- a/llvm/lib/Object/DXContainer.cpp +++ b/llvm/lib/Object/DXContainer.cpp @@ -11,6 +11,7 @@ #include "llvm/Object/Error.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; @@ -254,11 +255,9 @@ Error DirectX::RootSignature::parse(StringRef Data) { support::endian::read<uint32_t, llvm::endianness::little>(Current); Current += sizeof(uint32_t); - Expected<uint32_t> MaybeVersion = - dxbc::RootSignatureValidations::validateVersion(VValue); - if (Error E = MaybeVersion.takeError()) - return E; - Version = MaybeVersion.get(); + if (dxbc::RootSignatureValidations::validateVersion(VValue)) + return make_error<GenericBinaryError>("Invalid Version"); + Version = VValue; NumParameters = support::endian::read<uint32_t, llvm::endianness::little>(Current); @@ -280,11 +279,9 @@ Error DirectX::RootSignature::parse(StringRef Data) { support::endian::read<uint32_t, llvm::endianness::little>(Current); Current += sizeof(uint32_t); - Expected<uint32_t> MaybeFlag = - dxbc::RootSignatureValidations::validateRootFlag(FValue); - if (Error E = MaybeFlag.takeError()) - return E; - Flags = MaybeFlag.get(); + if (dxbc::RootSignatureValidations::validateRootFlag(FValue)) + return make_error<GenericBinaryError>("Invalid flag"); + Flags = FValue; return Error::success(); } diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 37108f92718df81..b0f00c2735080a5 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -152,16 +152,18 @@ void DXContainerGlobals::addSignature(Module &M, void DXContainerGlobals::addRootSignature(Module &M, SmallVector<GlobalValue *> &Globals) { - std::optional<ModuleRootSignature> MRS = - getAnalysis<RootSignatureAnalysisWrapper>().getRootSignature(); - if (!MRS.has_value()) + auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>(); + + if (!RSA.hasRootSignature()) return; + ModuleRootSignature MRS = RSA.getRootSignature(); + SmallString<256> Data; raw_svector_ostream OS(Data); RootSignatureHeader RSH; - RSH.Flags = MRS->Flags; + RSH.Flags = MRS.Flags; RSH.write(OS); diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index c85291186f61807..f051de8f8c896e2 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -15,17 +15,23 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" +#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" +#include "llvm/Support/Error.h" +#include <optional> using namespace llvm; using namespace llvm::dxil; -static bool reportError(Twine Message) { - report_fatal_error(Message, false); +bool ModuleRootSignature::reportError(Twine Message, + DiagnosticSeverity Severity) { + Ctx->diagnose(DiagnosticInfoGeneric(Message, Severity)); return true; } @@ -130,43 +136,33 @@ bool ModuleRootSignature::parse(NamedMDNode *Root, const Function *EF) { return HasError; } -bool ModuleRootSignature::validateRootFlag() { - // Root Element validation, as specified: - // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation - if ((Flags & ~0x80000fff) != 0) - return reportError("Invalid flag value for RootFlag"); - - return false; -} - bool ModuleRootSignature::validate() { - if (validateRootFlag()) + if (dxbc::RootSignatureValidations::validateRootFlag(Flags)) { return reportError("Invalid flag value for RootFlag"); - + } return false; } -ModuleRootSignature ModuleRootSignature::analyzeModule(Module &M, - const Function *F) { - ModuleRootSignature MRS; +OptionalRootSignature ModuleRootSignature::analyzeModule(Module &M, + const Function *F) { + ModuleRootSignature MRS(&M.getContext()); NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures"); - if (RootSignatureNode) { - if (MRS.parse(RootSignatureNode, F) || MRS.validate()) - llvm_unreachable("Invalid Root Signature Metadata."); - } + if (RootSignatureNode == nullptr || MRS.parse(RootSignatureNode, F) || + MRS.validate()) + return std::nullopt; return MRS; } AnalysisKey RootSignatureAnalysis::Key; -ModuleRootSignature RootSignatureAnalysis::run(Module &M, - ModuleAnalysisManager &AM) { +OptionalRootSignature RootSignatureAnalysis::run(Module &M, + ModuleAnalysisManager &AM) { auto MMI = AM.getResult<DXILMetadataAnalysis>(M); if (MMI.ShaderProfile == Triple::Library) - return ModuleRootSignature(); + return std::nullopt; assert(MMI.EntryPropertyVec.size() == 1); @@ -186,7 +182,6 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) { const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; MRS = ModuleRootSignature::analyzeModule(M, EntryFunction); - return false; } diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h index f79597721c3501f..da38078ad42f85d 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.h +++ b/llvm/lib/Target/DirectX/DXILRootSignature.h @@ -12,10 +12,13 @@ /// //===----------------------------------------------------------------------===// +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include <optional> +#include <utility> namespace llvm { namespace dxil { @@ -31,19 +34,25 @@ enum class RootSignatureElementKind { struct ModuleRootSignature { uint32_t Flags = 0; - - ModuleRootSignature() = default; - static ModuleRootSignature analyzeModule(Module &M, const Function *F); + ModuleRootSignature() { Ctx = nullptr; }; + ModuleRootSignature(LLVMContext *Ctx) : Ctx(Ctx) {} + static std::optional<ModuleRootSignature> analyzeModule(Module &M, + const Function *F); private: + LLVMContext *Ctx; + bool parse(NamedMDNode *Root, const Function *F); bool parseRootSignatureElement(MDNode *Element); bool parseRootFlags(MDNode *RootFlagNode); bool validate(); - bool validateRootFlag(); + + bool reportError(Twine Message, DiagnosticSeverity Severity = DS_Error); }; +using OptionalRootSignature = std::optional<ModuleRootSignature>; + class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { friend AnalysisInfoMixin<RootSignatureAnalysis>; static AnalysisKey Key; @@ -51,9 +60,9 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { public: RootSignatureAnalysis() = default; - using Result = ModuleRootSignature; + using Result = OptionalRootSignature; - ModuleRootSignature run(Module &M, ModuleAnalysisManager &AM); + OptionalRootSignature run(Module &M, ModuleAnalysisManager &AM); }; /// Wrapper pass for the legacy pass manager. @@ -61,14 +70,16 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> { /// This is required because the passes that will depend on this are codegen /// passes which run through the legacy pass manager. class RootSignatureAnalysisWrapper : public ModulePass { - std::optional<ModuleRootSignature> MRS; +private: + OptionalRootSignature MRS; public: static char ID; RootSignatureAnalysisWrapper() : ModulePass(ID) {} - const std::optional<ModuleRootSignature> &getRootSignature() { return MRS; } + const ModuleRootSignature &getRootSignature() { return MRS.value(); } + bool hasRootSignature() { return MRS.has_value(); } bool runOnModule(Module &M) override; diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll index cbcd8e56c1c0463..0f0c7cc39d73b53 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Error.ll @@ -2,7 +2,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: LLVM ERROR: Invalid format for Root Signature Definition. Pairs of function, root signature expected. +; CHECK: error: Invalid format for Root Signature Definition. Pairs of function, root signature expected. define void @main() #0 { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll index 9b4208011bba508..630bd5c1e3836e2 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Error.ll @@ -1,8 +1,8 @@ -; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s +; RUN: not llc %s --filetype=obj -o - target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: LLVM ERROR: Invalid Root Element: NOTRootFlags +; expected-error@-1: Invalid Root Element: NOTRootFlags define void @main() #0 { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll index 85e6f4d6748d5c4..dae3c75e70cb80b 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll @@ -1,8 +1,6 @@ -; RUN: not llc %s --filetype=obj -o - 2>&1 | FileCheck %s - +; RUN: not llc %s --filetype=obj -o - target triple = "dxil-unknown-shadermodel6.0-compute" - -; CHECK: LLVM ERROR: Invalid flag value for RootFlag +; expected-error@-1: Invalid flag value for RootFlag define void @main() #0 { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll index 501e3438943a3c9..80f969e849d25b1 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootElement-Error.ll @@ -2,7 +2,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: LLVM ERROR: Missing Root Element Metadata Node. +; CHECK: error: Missing Root Element Metadata Node. define void @main() #0 { _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits