[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
Thu Jan 30 14:31:21 PST 2025


https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/123147

>From 6043ffc97b263c6df78008bbe011a6ebe3dd1fd2 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/13] 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 ef12138b0dbef6ddd8a2b38a2a095f19d4a76ccc 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/13] 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 b65114f5569ae4b741e61a4792a56dec2a269349 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/13] 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 122396a59fd27501f7622a53f0ddccdacea32741 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/13] 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 1d8539181f3cf538e01e4979dca366be352860ee 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/13] 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 985546872a8b358..f3febcb09400ffd 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -16,6 +16,7 @@
 #include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Object/DXContainer.h"
 #include "llvm/Support/ScopedPrinter.h"
+#include <cstdint>
 
 namespace llvm {
 

>From 00c550249217852fb799a2fd35d5d94a711c984c 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/13] 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 040d6d5cf5aae3888cc4f9e2cf55c9e50a646140 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/13] 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 3d346c94a12cb327ee2e2a56853f4090c939cacc 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/13] 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 6ab48125b10eb394c454e8443237d5a32ab70a1d 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/13] 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 f3febcb09400ffd..985546872a8b358 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -16,7 +16,6 @@
 #include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Object/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 d59738d80db80b33e7605120703534d94e3561a9 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/13] 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 f16432fc49b2e2c0276d752ee680a1e3a76322ba 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/13] 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 62f4455b357c121ff7c6d635a58e07d3e2af5807 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/13] removing version

---
 llvm/include/llvm/MC/DXContainerRootSignature.h | 1 -
 llvm/include/llvm/Object/DXContainer.h          | 3 ---
 llvm/include/llvm/ObjectYAML/DXContainerYAML.h  | 1 -
 llvm/lib/MC/DXContainerRootSignature.cpp        | 1 -
 llvm/lib/Object/DXContainer.cpp                 | 3 ---
 llvm/lib/ObjectYAML/DXContainerEmitter.cpp      | 1 -
 llvm/lib/ObjectYAML/DXContainerYAML.cpp         | 4 ++--
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp  | 2 +-
 llvm/lib/Target/DirectX/DXILRootSignature.cpp   | 5 ++---
 llvm/lib/Target/DirectX/DXILRootSignature.h     | 3 +--
 10 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 23de2709088c667..20b4f5a4285f69b 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -15,7 +15,6 @@ class raw_ostream;
 
 namespace mcdxbc {
 struct RootSignatureHeader {
-  uint32_t Version;
   uint32_t Flags;
 
   void swapBytes();
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 290fbd69991864e..5f7737d2fa41d26 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -121,7 +121,6 @@ class RootSignature {
 private:
   StringRef Data;
   uint32_t Size;
-  uint32_t Version;
   uint32_t Flags;
 
 public:
@@ -131,8 +130,6 @@ class RootSignature {
 
   uint32_t getSize() const { return Size; }
 
-  uint32_t getVersion() const { return Version; }
-
   uint32_t getFlags() const { return Flags; }
 };
 
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 6b01f105a544bf7..9b3259f3bf6c603 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -80,7 +80,6 @@ struct RootSignatureDesc {
 
   uint32_t getEncodedFlags();
   uint32_t Size;
-  uint32_t Version;
   uint32_t NumParameters;
   SmallVector<dxbc::RootParameter> Parameters;
 
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index 0bb87c2cc38324f..4e085654a1e5e1b 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -18,6 +18,5 @@ void RootSignatureHeader::write(raw_ostream &OS) {
 
   uint32_t SizeInfo = sizeof(this);
   support::endian::write(OS, SizeInfo, llvm::endianness::little);
-  support::endian::write(OS, Version, llvm::endianness::little);
   support::endian::write(OS, Flags, llvm::endianness::little);
 }
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index ffb0b6884831ba0..6743911059cfd43 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -248,9 +248,6 @@ Error DirectX::RootSignature::parse() {
   Size = support::endian::read<uint32_t, llvm::endianness::little>(Current);
   Current += sizeof(uint32_t);
 
-  Version = support::endian::read<uint32_t, llvm::endianness::little>(Current);
-  Current += sizeof(uint32_t);
-
   Flags = support::endian::read<uint32_t, llvm::endianness::little>(Current);
   Current += sizeof(uint32_t);
 
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index 0504f6b88a7db5a..ada7383ea3c6b8f 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -267,7 +267,6 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
         continue;
 
       mcdxbc::RootSignatureHeader Header;
-      Header.Version = P.RootSignature->Version;
       Header.Flags = P.RootSignature->getEncodedFlags();
 
       Header.write(OS);
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 985546872a8b358..fb15a9554752332 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -32,7 +32,7 @@ DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
 
 DXContainerYAML::RootSignatureDesc::RootSignatureDesc(
     const object::DirectX::RootSignature &Data)
-    : Size(Data.getSize()), Version(Data.getVersion()) {
+    : Size(Data.getSize()) {
   uint32_t Flags = Data.getFlags();
 #define ROOT_ELEMENT_FLAG(Num, Val, Str)                                       \
   Val = (Flags & (uint32_t)dxbc::RootElementFlag::Val) > 0;
@@ -210,7 +210,7 @@ void MappingTraits<DXContainerYAML::Signature>::mapping(
 void MappingTraits<DXContainerYAML::RootSignatureDesc>::mapping(
     IO &IO, DXContainerYAML::RootSignatureDesc &S) {
   IO.mapRequired("Size", S.Size);
-  IO.mapRequired("Version", S.Version);
+  IO.mapRequired("Parameters", S.Parameters);
 #define ROOT_ELEMENT_FLAG(Num, Val, Str) IO.mapOptional(#Val, S.Val, false);
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 }
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 d3193fddcff402c6df5b24c5919f3fa6177c911a 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/13] fix test

---
 llvm/include/llvm/BinaryFormat/DXContainer.h  | 28 -------------------
 .../include/llvm/ObjectYAML/DXContainerYAML.h |  2 --
 llvm/lib/ObjectYAML/DXContainerYAML.cpp       |  1 -
 .../ContainerData/RootSignature-Flags.ll      |  8 ++++--
 .../DXContainer/RootSignature-Flags.yaml      |  8 ++----
 5 files changed, 8 insertions(+), 39 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 9268c28dbc69d23..71a6d15e46a81db 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -63,40 +63,12 @@ struct ShaderHash {
   void swapBytes() { sys::swapByteOrder(Flags); }
 };
 
-#define ROOT_PARAMETER(RootParameter) RootParameter,
-enum class RootParameterType {
-#include "DXContainerConstants.def"
-};
-
-#define SHADER_VISIBILITY(ShaderVisibility) ShaderVisibility,
-enum class ShaderVisibilityFlag {
-#include "DXContainerConstants.def"
-};
-
-struct RootConstants {
-  uint32_t ShaderRegister;
-  uint32_t RegisterSpace;
-  uint32_t Num32BitValues;
-};
-
-struct RootParameter {
-  RootParameterType ParameterType;
-  union {
-    RootConstants Constants;
-  };
-  ShaderVisibilityFlag ShaderVisibility;
-};
-
 struct RootSignatureDesc {
   uint32_t Size;
-  uint32_t Version;
   uint32_t Flags;
-  uint32_t NumParameters;
-  RootParameter *Parameters;
 
   void swapBytes() {
     sys::swapByteOrder(Size);
-    sys::swapByteOrder(Version);
     sys::swapByteOrder(Flags);
   }
 };
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 9b3259f3bf6c603..a82083fa18de6b1 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -80,8 +80,6 @@ struct RootSignatureDesc {
 
   uint32_t getEncodedFlags();
   uint32_t Size;
-  uint32_t NumParameters;
-  SmallVector<dxbc::RootParameter> Parameters;
 
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 };
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index fb15a9554752332..fd85d75dc32eb35 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -210,7 +210,6 @@ void MappingTraits<DXContainerYAML::Signature>::mapping(
 void MappingTraits<DXContainerYAML::RootSignatureDesc>::mapping(
     IO &IO, DXContainerYAML::RootSignatureDesc &S) {
   IO.mapRequired("Size", S.Size);
-  IO.mapRequired("Parameters", S.Parameters);
 #define ROOT_ELEMENT_FLAG(Num, Val, Str) IO.mapOptional(#Val, S.Val, false);
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 }
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
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
index 6c0ccda2e4ca5f5..cc4e51b3c4c2794 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml
@@ -10,15 +10,13 @@ Header:
   PartOffsets:     [ 60 ]
 Parts:
   - Name:            RTS0
-    Size:            8
+    Size:            4
     RootSignature:
-      Size: 8
-      Version:         1
+      Size: 4
       AllowInputAssemblerInputLayout: true
   
 #CHECK:    - Name: RTS0
-#CHECK-NEXT: Size: 8
+#CHECK-NEXT: Size: 4
 #CHECK-NEXT: RootSignature:
 #CHECK-NEXT:   Size: 8
-#CHECK-NEXT:   Version: 1
 #CHECK-NEXT:   AllowInputAssemblerInputLayout: true



More information about the llvm-branch-commits mailing list