[llvm-branch-commits] [llvm] [DXIL] Add support for root signature flag element in DXContainer (PR #123147)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Feb 5 17:32:48 PST 2025
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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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.saffran at 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 at -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 at -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 {
More information about the llvm-branch-commits
mailing list