[clang] [llvm] [DirectX] Validate registers are bound to root signature (PR #146785)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 14 16:51:02 PDT 2025


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

>From 0e8828c291d6e7e35ed3c0bce0504d8f731f9667 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 26 Jun 2025 19:28:01 +0000
Subject: [PATCH 01/68] refactoring

---
 .../lib/Target/DirectX/DXContainerGlobals.cpp |  2 +-
 llvm/lib/Target/DirectX/DXILRootSignature.cpp | 12 ++---
 llvm/lib/Target/DirectX/DXILRootSignature.h   | 45 ++++++++++++++-----
 3 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 9c38901f6821f..83f787da66403 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -160,7 +160,7 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   assert(MMI.EntryPropertyVec.size() == 1);
 
-  auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>();
+  auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
   const auto &FuncRs = RSA.find(EntryFunction);
 
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 29e78fcce5262..4094df160ef6f 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -554,9 +554,9 @@ analyzeModule(Module &M) {
 
 AnalysisKey RootSignatureAnalysis::Key;
 
-SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>
-RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
-  return analyzeModule(M);
+RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M,
+                                                    ModuleAnalysisManager &AM) {
+  return RootSignatureBindingInfo(analyzeModule(M));
 }
 
 //===----------------------------------------------------------------------===//
@@ -564,8 +564,7 @@ RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
 PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
                                                     ModuleAnalysisManager &AM) {
 
-  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> &RSDMap =
-      AM.getResult<RootSignatureAnalysis>(M);
+  RootSignatureBindingInfo &RSDMap = AM.getResult<RootSignatureAnalysis>(M);
 
   OS << "Root Signature Definitions"
      << "\n";
@@ -636,7 +635,8 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
-  FuncToRsMap = analyzeModule(M);
+  FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
+      RootSignatureBindingInfo(analyzeModule(M)));
   return false;
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index b45cebc15fd39..fef933811f840 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -33,16 +33,43 @@ enum class RootSignatureElementKind {
   CBV = 5,
   DescriptorTable = 6,
 };
+
+class RootSignatureBindingInfo {
+  private:
+    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+
+  public:
+  using iterator =
+        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+
+  RootSignatureBindingInfo () = default;
+  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
+
+  iterator find(const Function *F) { return FuncToRsMap.find(F); }
+
+  iterator end() { return FuncToRsMap.end(); }
+
+  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) {
+    const auto FuncRs = find(F);
+    if (FuncRs == end())
+      return std::nullopt;
+
+    return FuncRs->second;
+  }
+  
+};
+
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   friend AnalysisInfoMixin<RootSignatureAnalysis>;
   static AnalysisKey Key;
 
 public:
-  RootSignatureAnalysis() = default;
 
-  using Result = SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>;
+RootSignatureAnalysis() = default;
 
-  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>
+  using Result = RootSignatureBindingInfo;
+  
+  RootSignatureBindingInfo
   run(Module &M, ModuleAnalysisManager &AM);
 };
 
@@ -52,20 +79,16 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
 /// passes which run through the legacy pass manager.
 class RootSignatureAnalysisWrapper : public ModulePass {
 private:
-  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+  std::unique_ptr<RootSignatureBindingInfo> FuncToRsMap;
 
 public:
   static char ID;
+  using Result = RootSignatureBindingInfo;
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
 
-  using iterator =
-      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
-
-  iterator find(const Function *F) { return FuncToRsMap.find(F); }
-
-  iterator end() { return FuncToRsMap.end(); }
-
+  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
+  
   bool runOnModule(Module &M) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;

>From 2edd215e118e9dc947b1a6d2bc52bb8b6c78e3b2 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 26 Jun 2025 19:28:01 +0000
Subject: [PATCH 02/68] refactoring

---
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp |  7 +++----
 llvm/lib/Target/DirectX/DXILRootSignature.cpp  | 12 +++++++++---
 llvm/lib/Target/DirectX/DXILRootSignature.h    | 10 +++++++---
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 83f787da66403..6c8ae8eaaea77 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -162,16 +162,15 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
-  const auto &FuncRs = RSA.find(EntryFunction);
+  const auto &RS = RSA.getDescForFunction(EntryFunction);
 
-  if (FuncRs == RSA.end())
+  if (!RS)
     return;
 
-  const RootSignatureDesc &RS = FuncRs->second;
   SmallString<256> Data;
   raw_svector_ostream OS(Data);
 
-  RS.write(OS);
+  RS->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 4094df160ef6f..12b0f0b74837a 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
+#include <memory>
 #include <optional>
 #include <utility>
 
@@ -554,9 +555,12 @@ analyzeModule(Module &M) {
 
 AnalysisKey RootSignatureAnalysis::Key;
 
-RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M,
-                                                    ModuleAnalysisManager &AM) {
-  return RootSignatureBindingInfo(analyzeModule(M));
+RootSignatureAnalysis::Result
+RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
+  if (!AnalysisResult)
+    AnalysisResult = std::make_unique<RootSignatureBindingInfo>(
+        RootSignatureBindingInfo(analyzeModule(M)));
+  return *AnalysisResult;
 }
 
 //===----------------------------------------------------------------------===//
@@ -635,6 +639,8 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
+  if (HasRun)
+    return false;
   FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
       RootSignatureBindingInfo(analyzeModule(M)));
   return false;
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index fef933811f840..c143d45a13d88 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -19,6 +19,7 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/MC/DXContainerRootSignature.h"
 #include "llvm/Pass.h"
+#include <memory>
 #include <optional>
 
 namespace llvm {
@@ -68,9 +69,11 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
 RootSignatureAnalysis() = default;
 
   using Result = RootSignatureBindingInfo;
-  
-  RootSignatureBindingInfo
-  run(Module &M, ModuleAnalysisManager &AM);
+
+  Result run(Module &M, ModuleAnalysisManager &AM);
+
+private:
+  std::unique_ptr<RootSignatureBindingInfo> AnalysisResult;
 };
 
 /// Wrapper pass for the legacy pass manager.
@@ -80,6 +83,7 @@ RootSignatureAnalysis() = default;
 class RootSignatureAnalysisWrapper : public ModulePass {
 private:
   std::unique_ptr<RootSignatureBindingInfo> FuncToRsMap;
+  bool HasRun = false;
 
 public:
   static char ID;

>From 242545e5f40ccbf698e7f6935d8d9efa86cf5cb4 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 2 Jul 2025 21:10:21 +0000
Subject: [PATCH 03/68] clean up

---
 llvm/lib/Target/DirectX/DXILRootSignature.cpp | 8 +++-----
 llvm/lib/Target/DirectX/DXILRootSignature.h   | 2 --
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 12b0f0b74837a..5a53ea8a3631b 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -28,7 +28,6 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
-#include <memory>
 #include <optional>
 #include <utility>
 
@@ -639,10 +638,9 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
-  if (HasRun)
-    return false;
-  FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
-      RootSignatureBindingInfo(analyzeModule(M)));
+  if (!FuncToRsMap)
+    FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
+        RootSignatureBindingInfo(analyzeModule(M)));
   return false;
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index c143d45a13d88..8a057404e01c1 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -19,7 +19,6 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/MC/DXContainerRootSignature.h"
 #include "llvm/Pass.h"
-#include <memory>
 #include <optional>
 
 namespace llvm {
@@ -83,7 +82,6 @@ RootSignatureAnalysis() = default;
 class RootSignatureAnalysisWrapper : public ModulePass {
 private:
   std::unique_ptr<RootSignatureBindingInfo> FuncToRsMap;
-  bool HasRun = false;
 
 public:
   static char ID;

>From 3f8dec410b55a610f41cec9d7b38c15c52f82837 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 2 Jul 2025 21:22:55 +0000
Subject: [PATCH 04/68] format

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 25 +++++++++++----------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 8a057404e01c1..60ae7c0a6b2b1 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -35,28 +35,30 @@ enum class RootSignatureElementKind {
 };
 
 class RootSignatureBindingInfo {
-  private:
-    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+private:
+  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
 
-  public:
+public:
   using iterator =
-        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
 
-  RootSignatureBindingInfo () = default;
-  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
+  RootSignatureBindingInfo() = default;
+  RootSignatureBindingInfo(
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
+      : FuncToRsMap(Map){};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) {
+  std::optional<mcdxbc::RootSignatureDesc>
+  getDescForFunction(const Function *F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
       return std::nullopt;
 
     return FuncRs->second;
   }
-  
 };
 
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
@@ -64,8 +66,7 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   static AnalysisKey Key;
 
 public:
-
-RootSignatureAnalysis() = default;
+  RootSignatureAnalysis() = default;
 
   using Result = RootSignatureBindingInfo;
 
@@ -89,8 +90,8 @@ class RootSignatureAnalysisWrapper : public ModulePass {
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
 
-  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
-  
+  RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }
+
   bool runOnModule(Module &M) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;

>From 3b1ce3bee8112f55b22ed55c2881bd128793b3e2 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 2 Jul 2025 21:49:19 +0000
Subject: [PATCH 05/68] formating

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 60ae7c0a6b2b1..41c2251c5f1e2 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -45,7 +45,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map){};
+      : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 

>From f5720afd4c34075e17c2220dd92d0f10a60bbb43 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 4 Jul 2025 02:10:03 +0000
Subject: [PATCH 06/68] fix import issues

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 41c2251c5f1e2..e02f47ff60ae8 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -10,6 +10,8 @@
 ///       Root Signatures.
 ///
 //===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H
+#define LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
@@ -45,7 +47,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map) {};
+      : FuncToRsMap(Map){};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
@@ -109,3 +111,4 @@ class RootSignatureAnalysisPrinter
 
 } // namespace dxil
 } // namespace llvm
+#endif

>From ea54904cdc29c624cd40ecff7f4ce5fe0af17af6 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 4 Jul 2025 19:28:15 +0000
Subject: [PATCH 07/68] formating

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index e02f47ff60ae8..3832182277050 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -47,7 +47,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map){};
+      : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 

>From a49aa19297811e5800ffce364d8d6a225109d93f Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 26 Jun 2025 19:28:01 +0000
Subject: [PATCH 08/68] refactoring

---
 .../lib/Target/DirectX/DXContainerGlobals.cpp |  4 ++-
 llvm/lib/Target/DirectX/DXILRootSignature.cpp | 14 +++-----
 llvm/lib/Target/DirectX/DXILRootSignature.h   | 33 +++++++++----------
 3 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 6c8ae8eaaea77..e076283b65193 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -160,11 +160,13 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   assert(MMI.EntryPropertyVec.size() == 1);
 
+  auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
   const auto &RS = RSA.getDescForFunction(EntryFunction);
+  const auto &RS = RSA.getDescForFunction(EntryFunction);
 
-  if (!RS)
+  if (!RS )
     return;
 
   SmallString<256> Data;
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 5a53ea8a3631b..4094df160ef6f 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -554,12 +554,9 @@ analyzeModule(Module &M) {
 
 AnalysisKey RootSignatureAnalysis::Key;
 
-RootSignatureAnalysis::Result
-RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
-  if (!AnalysisResult)
-    AnalysisResult = std::make_unique<RootSignatureBindingInfo>(
-        RootSignatureBindingInfo(analyzeModule(M)));
-  return *AnalysisResult;
+RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M,
+                                                    ModuleAnalysisManager &AM) {
+  return RootSignatureBindingInfo(analyzeModule(M));
 }
 
 //===----------------------------------------------------------------------===//
@@ -638,9 +635,8 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
-  if (!FuncToRsMap)
-    FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
-        RootSignatureBindingInfo(analyzeModule(M)));
+  FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
+      RootSignatureBindingInfo(analyzeModule(M)));
   return false;
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 3832182277050..24b1a8d3d2abe 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -37,30 +37,28 @@ enum class RootSignatureElementKind {
 };
 
 class RootSignatureBindingInfo {
-private:
-  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+  private:
+    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
 
-public:
+  public:
   using iterator =
-      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
 
-  RootSignatureBindingInfo() = default;
-  RootSignatureBindingInfo(
-      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map) {};
+  RootSignatureBindingInfo () = default;
+  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc>
-  getDescForFunction(const Function *F) {
+  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
       return std::nullopt;
 
     return FuncRs->second;
   }
+  
 };
 
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
@@ -68,14 +66,13 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   static AnalysisKey Key;
 
 public:
-  RootSignatureAnalysis() = default;
-
-  using Result = RootSignatureBindingInfo;
 
-  Result run(Module &M, ModuleAnalysisManager &AM);
+RootSignatureAnalysis() = default;
 
-private:
-  std::unique_ptr<RootSignatureBindingInfo> AnalysisResult;
+  using Result = RootSignatureBindingInfo;
+  
+  RootSignatureBindingInfo
+  run(Module &M, ModuleAnalysisManager &AM);
 };
 
 /// Wrapper pass for the legacy pass manager.
@@ -92,8 +89,8 @@ class RootSignatureAnalysisWrapper : public ModulePass {
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
 
-  RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }
-
+  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
+  
   bool runOnModule(Module &M) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;

>From d90676feb6bfc0ca8bbdaee5c347ecc49e396b5b Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 26 Jun 2025 21:37:11 +0000
Subject: [PATCH 09/68] init refactoring

---
 .../SemaHLSL/RootSignature-Validation.hlsl    | 42 +++++++++++++++++
 .../lib/Target/DirectX/DXContainerGlobals.cpp |  2 +-
 .../DXILPostOptimizationValidation.cpp        | 47 +++++++++++++++++--
 llvm/lib/Target/DirectX/DXILRootSignature.h   | 30 ++++++------
 4 files changed, 102 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/SemaHLSL/RootSignature-Validation.hlsl

diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
new file mode 100644
index 0000000000000..8a4a97f87cb65
--- /dev/null
+++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
@@ -0,0 +1,42 @@
+// RUN: %clang_dxc -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify
+
+#define ROOT_SIGNATURE \
+    "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \
+    "CBV(b0, visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(SRV(t0, numDescriptors=3), visibility=SHADER_VISIBILITY_PIXEL), " \
+    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL), " \
+    "DescriptorTable(UAV(u0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)"
+
+cbuffer CB : register(b3, space2) {
+  float a;
+}
+
+StructuredBuffer<int> In : register(t0);
+RWStructuredBuffer<int> Out : register(u0);
+
+RWBuffer<float> UAV : register(u3);
+
+RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
+
+RWBuffer<float> UAV3 : register(space5);
+
+float f : register(c5);
+
+int4 intv : register(c2);
+
+double dar[5] :  register(c3);
+
+struct S {
+  int a;
+};
+
+S s : register(c10);
+
+// Compute Shader for UAV testing
+[numthreads(8, 8, 1)]
+[RootSignature(ROOT_SIGNATURE)]
+void CSMain(uint3 id : SV_DispatchThreadID)
+{
+    In[0] = id;
+    Out[0] = In[0];
+}
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index e076283b65193..5c763c24a210a 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -166,7 +166,7 @@ void DXContainerGlobals::addRootSignature(Module &M,
   const auto &RS = RSA.getDescForFunction(EntryFunction);
   const auto &RS = RSA.getDescForFunction(EntryFunction);
 
-  if (!RS )
+  if (!RS)
     return;
 
   SmallString<256> Data;
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 398dcbb8d1737..daf53fefe5f17 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -7,11 +7,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "DXILPostOptimizationValidation.h"
+#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
@@ -85,7 +88,9 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
 }
 
 static void reportErrors(Module &M, DXILResourceMap &DRM,
-                         DXILResourceBindingInfo &DRBI) {
+                         DXILResourceBindingInfo &DRBI,
+                         RootSignatureBindingInfo &RSBI,
+                         dxil::ModuleMetadataInfo &MMI) {
   if (DRM.hasInvalidCounterDirection())
     reportInvalidDirection(M, DRM);
 
@@ -94,6 +99,30 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
                                        "DXILResourceImplicitBinding pass");
+  // Assuming this is used to validate only the root signature assigned to the
+  // entry function.
+  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
+      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
+  if (!RootSigDesc)
+    return;
+
+  for (const mcdxbc::RootParameterInfo &Info :
+       RootSigDesc->ParametersContainer) {
+    const auto &[Type, Loc] =
+        RootSigDesc->ParametersContainer.getTypeAndLocForParameter(
+            Info.Location);
+    switch (Type) {
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+      dxbc::RTS0::v2::RootDescriptor Desc =
+          RootSigDesc->ParametersContainer.getRootDescriptor(Loc);
+
+      llvm::dxil::ResourceInfo::ResourceBinding Binding;
+      Binding.LowerBound = Desc.ShaderRegister;
+      Binding.Space = Desc.RegisterSpace;
+      Binding.Size = 1;
+      break;
+    }
+  }
 }
 } // namespace
 
@@ -101,7 +130,10 @@ PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
   DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
   DXILResourceBindingInfo &DRBI = MAM.getResult<DXILResourceBindingAnalysis>(M);
-  reportErrors(M, DRM, DRBI);
+  RootSignatureBindingInfo &RSBI = MAM.getResult<RootSignatureAnalysis>(M);
+  ModuleMetadataInfo &MMI = MAM.getResult<DXILMetadataAnalysis>(M);
+
+  reportErrors(M, DRM, DRBI, RSBI, MMI);
   return PreservedAnalyses::all();
 }
 
@@ -113,7 +145,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
         getAnalysis<DXILResourceWrapperPass>().getResourceMap();
     DXILResourceBindingInfo &DRBI =
         getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();
-    reportErrors(M, DRM, DRBI);
+
+    RootSignatureBindingInfo &RSBI =
+        getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
+    dxil::ModuleMetadataInfo &MMI =
+        getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
+
+    reportErrors(M, DRM, DRBI, RSBI, MMI);
     return false;
   }
   StringRef getPassName() const override {
@@ -125,10 +163,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
   void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
     AU.addRequired<DXILResourceWrapperPass>();
     AU.addRequired<DXILResourceBindingWrapperPass>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
+    AU.addRequired<DXILMetadataAnalysisWrapperPass>();
     AU.addPreserved<DXILResourceWrapperPass>();
     AU.addPreserved<DXILResourceBindingWrapperPass>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
+    AU.addPreserved<RootSignatureAnalysisWrapper>();
   }
 };
 char DXILPostOptimizationValidationLegacy::ID = 0;
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 24b1a8d3d2abe..ecfc577d1b97d 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -37,28 +37,30 @@ enum class RootSignatureElementKind {
 };
 
 class RootSignatureBindingInfo {
-  private:
-    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+private:
+  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
 
-  public:
+public:
   using iterator =
-        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
 
-  RootSignatureBindingInfo () = default;
-  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
+  RootSignatureBindingInfo() = default;
+  RootSignatureBindingInfo(
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
+      : FuncToRsMap(Map){};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function* F) {
+  std::optional<mcdxbc::RootSignatureDesc>
+  getDescForFunction(const Function *F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
       return std::nullopt;
 
     return FuncRs->second;
   }
-  
 };
 
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
@@ -66,13 +68,11 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   static AnalysisKey Key;
 
 public:
-
-RootSignatureAnalysis() = default;
+  RootSignatureAnalysis() = default;
 
   using Result = RootSignatureBindingInfo;
-  
-  RootSignatureBindingInfo
-  run(Module &M, ModuleAnalysisManager &AM);
+
+  RootSignatureBindingInfo run(Module &M, ModuleAnalysisManager &AM);
 };
 
 /// Wrapper pass for the legacy pass manager.
@@ -89,8 +89,8 @@ class RootSignatureAnalysisWrapper : public ModulePass {
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
 
-  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
-  
+  RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }
+
   bool runOnModule(Module &M) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;

>From a04eb9ff37d20499f05c7b1cc0ab3187f729609b Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 2 Jul 2025 17:58:56 +0000
Subject: [PATCH 10/68] adding validation

---
 .../SemaHLSL/RootSignature-Validation.hlsl    | 28 ++++---------
 .../DXILPostOptimizationValidation.cpp        | 42 +++++++++++++++----
 2 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
index 8a4a97f87cb65..62ba704b95c7d 100644
--- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
@@ -1,42 +1,30 @@
-// RUN: %clang_dxc -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify
 
 #define ROOT_SIGNATURE \
     "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \
-    "CBV(b0, visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(SRV(t0, numDescriptors=3), visibility=SHADER_VISIBILITY_PIXEL), " \
-    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL), " \
-    "DescriptorTable(UAV(u0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)"
+    "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)"
 
 cbuffer CB : register(b3, space2) {
   float a;
 }
 
-StructuredBuffer<int> In : register(t0);
+StructuredBuffer<int> In : register(t0, space0);
 RWStructuredBuffer<int> Out : register(u0);
 
 RWBuffer<float> UAV : register(u3);
 
 RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
 
-RWBuffer<float> UAV3 : register(space5);
+RWBuffer<float> UAV3 : register(space0);
 
-float f : register(c5);
 
-int4 intv : register(c2);
-
-double dar[5] :  register(c3);
-
-struct S {
-  int a;
-};
-
-S s : register(c10);
 
 // Compute Shader for UAV testing
 [numthreads(8, 8, 1)]
 [RootSignature(ROOT_SIGNATURE)]
-void CSMain(uint3 id : SV_DispatchThreadID)
+void CSMain(uint id : SV_GroupID)
 {
-    In[0] = id;
-    Out[0] = In[0];
+    Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0];
 }
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index daf53fefe5f17..3e542e502c2d5 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -10,6 +10,7 @@
 #include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
+#include "llvm/ADT/IntervalMap.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
@@ -86,7 +87,9 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
     }
   }
 }
-
+  uint64_t combine_uint32_to_uint64(uint32_t high, uint32_t low) {
+      return (static_cast<uint64_t>(high) << 32) | low;
+  }
 static void reportErrors(Module &M, DXILResourceMap &DRM,
                          DXILResourceBindingInfo &DRBI,
                          RootSignatureBindingInfo &RSBI,
@@ -101,18 +104,24 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
                                        "DXILResourceImplicitBinding pass");
   // Assuming this is used to validate only the root signature assigned to the
   // entry function.
+  //Start test stuff
+  if(MMI.EntryPropertyVec.size() == 0)
+    return;
+
   std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
       RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
   if (!RootSigDesc)
     return;
 
-  for (const mcdxbc::RootParameterInfo &Info :
-       RootSigDesc->ParametersContainer) {
+  using MapT = llvm::IntervalMap<uint64_t, llvm::dxil::ResourceInfo::ResourceBinding, sizeof(llvm::dxil::ResourceInfo::ResourceBinding), llvm::IntervalMapInfo<uint64_t>>;
+  MapT::Allocator Allocator;
+  MapT BindingsMap(Allocator);
+  auto RSD = *RootSigDesc;
+   for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
     const auto &[Type, Loc] =
-        RootSigDesc->ParametersContainer.getTypeAndLocForParameter(
-            Info.Location);
+        RootSigDesc->ParametersContainer.getTypeAndLocForParameter(I);
     switch (Type) {
-    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):{
       dxbc::RTS0::v2::RootDescriptor Desc =
           RootSigDesc->ParametersContainer.getRootDescriptor(Loc);
 
@@ -120,8 +129,27 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
       Binding.LowerBound = Desc.ShaderRegister;
       Binding.Space = Desc.RegisterSpace;
       Binding.Size = 1;
+
+      BindingsMap.insert(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1), Binding);
       break;
     }
+    // case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{
+    //   mcdxbc::DescriptorTable Table =
+    //       RootSigDesc->ParametersContainer.getDescriptorTable(Loc);
+    //   for (const dxbc::RTS0::v2::DescriptorRange &Range : Table){
+    //     Range.
+    //   }
+      
+    //   break;
+    // }
+    }
+
+  }
+
+  for(const auto &CBuf : DRM.cbuffers()) {
+    auto Binding = CBuf.getBinding();
+    if(!BindingsMap.overlaps(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1)))
+      auto X = 1;
   }
 }
 } // namespace
@@ -146,7 +174,7 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
     DXILResourceBindingInfo &DRBI =
         getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();
 
-    RootSignatureBindingInfo &RSBI =
+    RootSignatureBindingInfo& RSBI =
         getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
     dxil::ModuleMetadataInfo &MMI =
         getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();

>From 5994b8f8f4ea24115a66c0046c8fc344905b41d4 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 2 Jul 2025 21:19:37 +0000
Subject: [PATCH 11/68] clean

---
 .../DXILPostOptimizationValidation.cpp        |  6 +----
 .../DirectX/DXILPostOptimizationValidation.h  |  3 +++
 llvm/lib/Target/DirectX/DXILRootSignature.h   | 24 +++++++++----------
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 3e542e502c2d5..4c29b56304391 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -10,12 +10,9 @@
 #include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
-#include "llvm/ADT/IntervalMap.h"
-#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
@@ -173,8 +170,7 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
         getAnalysis<DXILResourceWrapperPass>().getResourceMap();
     DXILResourceBindingInfo &DRBI =
         getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();
-
-    RootSignatureBindingInfo& RSBI =
+    RootSignatureBindingInfo &RSBI =
         getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
     dxil::ModuleMetadataInfo &MMI =
         getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index cb5e624514272..151843daf068d 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -14,6 +14,9 @@
 #ifndef LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
 #define LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
 
+#include "DXILRootSignature.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/Analysis/DXILResource.h"
 #include "llvm/IR/PassManager.h"
 
 namespace llvm {
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index ecfc577d1b97d..d0d5c7785bda3 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -37,30 +37,28 @@ enum class RootSignatureElementKind {
 };
 
 class RootSignatureBindingInfo {
-private:
-  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+  private:
+    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
 
-public:
+  public:
   using iterator =
-      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
 
-  RootSignatureBindingInfo() = default;
-  RootSignatureBindingInfo(
-      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map){};
+RootSignatureBindingInfo () = default;
+  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc>
-  getDescForFunction(const Function *F) {
+  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function *F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
       return std::nullopt;
 
     return FuncRs->second;
   }
+
 };
 
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
@@ -68,7 +66,7 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   static AnalysisKey Key;
 
 public:
-  RootSignatureAnalysis() = default;
+RootSignatureAnalysis() = default;
 
   using Result = RootSignatureBindingInfo;
 
@@ -88,8 +86,8 @@ class RootSignatureAnalysisWrapper : public ModulePass {
   using Result = RootSignatureBindingInfo;
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
-
-  RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }
+  
+  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
 
   bool runOnModule(Module &M) override;
 

>From e8b14bf32e47cf8c059d2f492e57a602375ceeaa Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 4 Jul 2025 02:03:26 +0000
Subject: [PATCH 12/68] implementing

---
 .../RootSignature-Validation-Fail.hlsl        |  35 ++++
 .../SemaHLSL/RootSignature-Validation.hlsl    |  11 +-
 .../DXILPostOptimizationValidation.cpp        | 166 +++++++++++++-----
 .../DirectX/DXILPostOptimizationValidation.h  |  88 ++++++++++
 llvm/lib/Target/DirectX/DXILRootSignature.h   |  24 +--
 .../RootSignature-DescriptorTable.ll          |   4 +-
 6 files changed, 271 insertions(+), 57 deletions(-)
 create mode 100644 clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl

diff --git a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl
new file mode 100644
index 0000000000000..b590ed67e7085
--- /dev/null
+++ b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl
@@ -0,0 +1,35 @@
+// RUN: not %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 | FileCheck %s
+
+// CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature
+// CHECK: error: register srv (space=0, register=0) is not defined in Root Signature
+// CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature
+
+
+#define ROOT_SIGNATURE \
+    "CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX), " \
+    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)"
+
+cbuffer CB : register(b3, space665) {
+  float a;
+}
+
+StructuredBuffer<int> In : register(t0, space0);
+RWStructuredBuffer<int> Out : register(u0);
+
+RWBuffer<float> UAV : register(u4294967295);
+
+RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
+
+RWBuffer<float> UAV3 : register(space0);
+
+
+
+// Compute Shader for UAV testing
+[numthreads(8, 8, 1)]
+[RootSignature(ROOT_SIGNATURE)]
+void CSMain(uint id : SV_GroupID)
+{
+    Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0];
+}
diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
index 62ba704b95c7d..5a7f5baf00619 100644
--- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
@@ -1,19 +1,22 @@
+// RUN: %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 
+
+// expected-no-diagnostics
+
 
 #define ROOT_SIGNATURE \
-    "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \
     "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \
     "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \
+    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX), " \
     "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)"
 
-cbuffer CB : register(b3, space2) {
+cbuffer CB : register(b3, space1) {
   float a;
 }
 
 StructuredBuffer<int> In : register(t0, space0);
 RWStructuredBuffer<int> Out : register(u0);
 
-RWBuffer<float> UAV : register(u3);
+RWBuffer<float> UAV : register(u4294967294);
 
 RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 4c29b56304391..23bb5d1a7f651 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -84,9 +84,57 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
     }
   }
 }
-  uint64_t combine_uint32_to_uint64(uint32_t high, uint32_t low) {
-      return (static_cast<uint64_t>(high) << 32) | low;
+
+static void reportRegNotBound(Module &M, Twine Type,
+                              ResourceInfo::ResourceBinding Binding) {
+  SmallString<128> Message;
+  raw_svector_ostream OS(Message);
+  OS << "register " << Type << " (space=" << Binding.Space
+     << ", register=" << Binding.LowerBound << ")"
+     << " is not defined in Root Signature";
+  M.getContext().diagnose(DiagnosticInfoGeneric(Message));
+}
+
+static dxbc::ShaderVisibility
+tripleToVisibility(llvm::Triple::EnvironmentType ET) {
+  assert((ET == Triple::Pixel || ET == Triple::Vertex ||
+          ET == Triple::Geometry || ET == Triple::Hull ||
+          ET == Triple::Domain || ET == Triple::Mesh ||
+          ET == Triple::Compute) &&
+         "Invalid Triple to shader stage conversion");
+
+  switch (ET) {
+  case Triple::Pixel:
+    return dxbc::ShaderVisibility::Pixel;
+  case Triple::Vertex:
+    return dxbc::ShaderVisibility::Vertex;
+  case Triple::Geometry:
+    return dxbc::ShaderVisibility::Geometry;
+  case Triple::Hull:
+    return dxbc::ShaderVisibility::Hull;
+  case Triple::Domain:
+    return dxbc::ShaderVisibility::Domain;
+  case Triple::Mesh:
+    return dxbc::ShaderVisibility::Mesh;
+  case Triple::Compute:
+    return dxbc::ShaderVisibility::All;
+  default:
+    llvm_unreachable("Invalid triple to shader stage conversion");
   }
+}
+
+std::optional<mcdxbc::RootSignatureDesc>
+getRootSignature(RootSignatureBindingInfo &RSBI,
+                 dxil::ModuleMetadataInfo &MMI) {
+  if (MMI.EntryPropertyVec.size() == 0)
+    return std::nullopt;
+  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
+      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
+  if (!RootSigDesc)
+    return std::nullopt;
+  return RootSigDesc;
+}
+
 static void reportErrors(Module &M, DXILResourceMap &DRM,
                          DXILResourceBindingInfo &DRBI,
                          RootSignatureBindingInfo &RSBI,
@@ -99,57 +147,95 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
                                        "DXILResourceImplicitBinding pass");
-  // Assuming this is used to validate only the root signature assigned to the
-  // entry function.
-  //Start test stuff
-  if(MMI.EntryPropertyVec.size() == 0)
-    return;
 
-  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
-      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
-  if (!RootSigDesc)
-    return;
+  if (auto RSD = getRootSignature(RSBI, MMI)) {
+
+    RootSignatureBindingValidation Validation;
+    Validation.addRsBindingInfo(*RSD, tripleToVisibility(MMI.ShaderProfile));
+
+    for (const auto &CBuf : DRM.cbuffers()) {
+      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
+      if (!Validation.checkCregBinding(Binding))
+        reportRegNotBound(M, "cbuffer", Binding);
+    }
+
+    for (const auto &CBuf : DRM.srvs()) {
+      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
+      if (!Validation.checkTRegBinding(Binding))
+        reportRegNotBound(M, "srv", Binding);
+    }
 
-  using MapT = llvm::IntervalMap<uint64_t, llvm::dxil::ResourceInfo::ResourceBinding, sizeof(llvm::dxil::ResourceInfo::ResourceBinding), llvm::IntervalMapInfo<uint64_t>>;
-  MapT::Allocator Allocator;
-  MapT BindingsMap(Allocator);
-  auto RSD = *RootSigDesc;
-   for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
+    for (const auto &CBuf : DRM.uavs()) {
+      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
+      if (!Validation.checkURegBinding(Binding))
+        reportRegNotBound(M, "uav", Binding);
+    }
+  }
+}
+} // namespace
+
+void RootSignatureBindingValidation::addRsBindingInfo(
+    mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
+  for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
     const auto &[Type, Loc] =
-        RootSigDesc->ParametersContainer.getTypeAndLocForParameter(I);
+        RSD.ParametersContainer.getTypeAndLocForParameter(I);
+
+    const auto &Header = RSD.ParametersContainer.getHeader(I);
     switch (Type) {
-    case llvm::to_underlying(dxbc::RootParameterType::CBV):{
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+    case llvm::to_underlying(dxbc::RootParameterType::CBV): {
       dxbc::RTS0::v2::RootDescriptor Desc =
-          RootSigDesc->ParametersContainer.getRootDescriptor(Loc);
+          RSD.ParametersContainer.getRootDescriptor(Loc);
 
-      llvm::dxil::ResourceInfo::ResourceBinding Binding;
-      Binding.LowerBound = Desc.ShaderRegister;
-      Binding.Space = Desc.RegisterSpace;
-      Binding.Size = 1;
+      if (Header.ShaderVisibility ==
+              llvm::to_underlying(dxbc::ShaderVisibility::All) ||
+          Header.ShaderVisibility == llvm::to_underlying(Visibility))
+        addRange(Desc, Type);
+      break;
+    }
+    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+      const mcdxbc::DescriptorTable &Table =
+          RSD.ParametersContainer.getDescriptorTable(Loc);
 
-      BindingsMap.insert(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1), Binding);
+      for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
+        if (Range.RangeType ==
+            llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
+          continue;
+
+        if (Header.ShaderVisibility ==
+                llvm::to_underlying(dxbc::ShaderVisibility::All) ||
+            Header.ShaderVisibility == llvm::to_underlying(Visibility))
+          addRange(Range);
+      }
       break;
     }
-    // case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{
-    //   mcdxbc::DescriptorTable Table =
-    //       RootSigDesc->ParametersContainer.getDescriptorTable(Loc);
-    //   for (const dxbc::RTS0::v2::DescriptorRange &Range : Table){
-    //     Range.
-    //   }
-      
-    //   break;
-    // }
     }
-
   }
+}
 
-  for(const auto &CBuf : DRM.cbuffers()) {
-    auto Binding = CBuf.getBinding();
-    if(!BindingsMap.overlaps(combine_uint32_to_uint64(Binding.Space, Binding.LowerBound), combine_uint32_to_uint64(Binding.Space, Binding.LowerBound + Binding.Size -1)))
-      auto X = 1;
-  }
+bool RootSignatureBindingValidation::checkCregBinding(
+    ResourceInfo::ResourceBinding Binding) {
+  return CRegBindingsMap.overlaps(
+      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+      combineUint32ToUint64(Binding.Space,
+                            Binding.LowerBound + Binding.Size - 1));
+}
+
+bool RootSignatureBindingValidation::checkTRegBinding(
+    ResourceInfo::ResourceBinding Binding) {
+  return TRegBindingsMap.overlaps(
+      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+      combineUint32ToUint64(Binding.Space, Binding.LowerBound + Binding.Size));
+}
+
+bool RootSignatureBindingValidation::checkURegBinding(
+    ResourceInfo::ResourceBinding Binding) {
+  return URegBindingsMap.overlaps(
+      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+      combineUint32ToUint64(Binding.Space,
+                            Binding.LowerBound + Binding.Size - 1));
 }
-} // namespace
 
 PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 151843daf068d..58113bf9f93c7 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -21,6 +21,94 @@
 
 namespace llvm {
 
+static uint64_t combineUint32ToUint64(uint32_t High, uint32_t Low) {
+  return (static_cast<uint64_t>(High) << 32) | Low;
+}
+
+class RootSignatureBindingValidation {
+  using MapT =
+      llvm::IntervalMap<uint64_t, dxil::ResourceInfo::ResourceBinding,
+                        sizeof(llvm::dxil::ResourceInfo::ResourceBinding),
+                        llvm::IntervalMapInfo<uint64_t>>;
+
+private:
+  MapT::Allocator Allocator;
+  MapT CRegBindingsMap;
+  MapT TRegBindingsMap;
+  MapT URegBindingsMap;
+
+  void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) {
+    assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) ||
+            Type == llvm::to_underlying(dxbc::RootParameterType::SRV) ||
+            Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) &&
+           "Invalid Type");
+
+    llvm::dxil::ResourceInfo::ResourceBinding Binding;
+    Binding.LowerBound = Desc.ShaderRegister;
+    Binding.Space = Desc.RegisterSpace;
+    Binding.Size = 1;
+
+    uint64_t LowRange =
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound);
+    uint64_t HighRange = combineUint32ToUint64(
+        Binding.Space, Binding.LowerBound + Binding.Size - 1);
+
+    switch (Type) {
+
+    case llvm::to_underlying(dxbc::RootParameterType::CBV):
+      CRegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+      TRegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+      URegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    }
+    llvm_unreachable("Invalid Type in add Range Method");
+  }
+
+  void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) {
+
+    llvm::dxil::ResourceInfo::ResourceBinding Binding;
+    Binding.LowerBound = Range.BaseShaderRegister;
+    Binding.Space = Range.RegisterSpace;
+    Binding.Size = Range.NumDescriptors;
+
+    uint64_t LowRange =
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound);
+    uint64_t HighRange = combineUint32ToUint64(
+        Binding.Space, Binding.LowerBound + Binding.Size - 1);
+
+    switch (Range.RangeType) {
+    case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
+      CRegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
+      TRegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
+      URegBindingsMap.insert(LowRange, HighRange, Binding);
+      return;
+    }
+    llvm_unreachable("Invalid Type in add Range Method");
+  }
+
+public:
+  RootSignatureBindingValidation()
+      : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator),
+        URegBindingsMap(Allocator) {}
+
+  void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD,
+                        dxbc::ShaderVisibility Visibility);
+
+  bool checkCregBinding(dxil::ResourceInfo::ResourceBinding Binding);
+
+  bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding);
+
+  bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding);
+};
+
 class DXILPostOptimizationValidation
     : public PassInfoMixin<DXILPostOptimizationValidation> {
 public:
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index d0d5c7785bda3..ecfc577d1b97d 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -37,28 +37,30 @@ enum class RootSignatureElementKind {
 };
 
 class RootSignatureBindingInfo {
-  private:
-    SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
+private:
+  SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
 
-  public:
+public:
   using iterator =
-        SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>::iterator;
 
-RootSignatureBindingInfo () = default;
-  RootSignatureBindingInfo(SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map) : FuncToRsMap(Map) {};
+  RootSignatureBindingInfo() = default;
+  RootSignatureBindingInfo(
+      SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
+      : FuncToRsMap(Map){};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc> getDescForFunction(const Function *F) {
+  std::optional<mcdxbc::RootSignatureDesc>
+  getDescForFunction(const Function *F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
       return std::nullopt;
 
     return FuncRs->second;
   }
-
 };
 
 class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
@@ -66,7 +68,7 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   static AnalysisKey Key;
 
 public:
-RootSignatureAnalysis() = default;
+  RootSignatureAnalysis() = default;
 
   using Result = RootSignatureBindingInfo;
 
@@ -86,8 +88,8 @@ class RootSignatureAnalysisWrapper : public ModulePass {
   using Result = RootSignatureBindingInfo;
 
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
-  
-  RootSignatureBindingInfo& getRSInfo() {return *FuncToRsMap;}
+
+  RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }
 
   bool runOnModule(Module &M) override;
 
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
index b516d66180247..8e9b4b43b11a6 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
@@ -16,7 +16,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
 !2 = !{ ptr @main, !3, i32 2 } ; function, root signature
 !3 = !{ !5 } ; list of root signature elements
 !5 = !{ !"DescriptorTable", i32 0, !6, !7 }
-!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 }
+!6 = !{ !"SRV", i32 1, i32 1, i32 0, i32 -1, i32 4 }
 !7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
 
 ; DXC:  - Name:            RTS0
@@ -35,7 +35,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
 ; DXC-NEXT:            RangesOffset:    44
 ; DXC-NEXT:            Ranges:
 ; DXC-NEXT:              - RangeType:       0
-; DXC-NEXT:                NumDescriptors:  0
+; DXC-NEXT:                NumDescriptors:  1
 ; DXC-NEXT:                BaseShaderRegister: 1
 ; DXC-NEXT:                RegisterSpace:   0
 ; DXC-NEXT:                OffsetInDescriptorsFromTableStart: 4294967295

>From 8f40e83ab0db147e90070f15708d0a0f4e1a9d1f Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 4 Jul 2025 19:24:25 +0000
Subject: [PATCH 13/68] finish implementing && fix tests

---
 .../DXILPostOptimizationValidation.cpp        | 45 +++++-----------
 .../DirectX/DXILPostOptimizationValidation.h  | 54 ++++++++++++++-----
 llvm/lib/Target/DirectX/DXILRootSignature.cpp |  5 +-
 ...criptorTable-AllValidFlagCombinationsV1.ll |  4 +-
 llvm/test/CodeGen/DirectX/llc-pipeline.ll     |  1 +
 5 files changed, 59 insertions(+), 50 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 23bb5d1a7f651..a52a04323514c 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -153,23 +153,29 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
     RootSignatureBindingValidation Validation;
     Validation.addRsBindingInfo(*RSD, tripleToVisibility(MMI.ShaderProfile));
 
-    for (const auto &CBuf : DRM.cbuffers()) {
+    for (const ResourceInfo &CBuf : DRM.cbuffers()) {
       ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
-      if (!Validation.checkCregBinding(Binding))
+      if (!Validation.checkCRegBinding(Binding))
         reportRegNotBound(M, "cbuffer", Binding);
     }
 
-    for (const auto &CBuf : DRM.srvs()) {
-      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
+    for (const ResourceInfo &SRV : DRM.srvs()) {
+      ResourceInfo::ResourceBinding Binding = SRV.getBinding();
       if (!Validation.checkTRegBinding(Binding))
         reportRegNotBound(M, "srv", Binding);
     }
 
-    for (const auto &CBuf : DRM.uavs()) {
-      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
+    for (const ResourceInfo &UAV : DRM.uavs()) {
+      ResourceInfo::ResourceBinding Binding = UAV.getBinding();
       if (!Validation.checkURegBinding(Binding))
         reportRegNotBound(M, "uav", Binding);
     }
+
+    for (const ResourceInfo &Sampler : DRM.samplers()) {
+      ResourceInfo::ResourceBinding Binding = Sampler.getBinding();
+      if (!Validation.checkSamplerBinding(Binding))
+        reportRegNotBound(M, "sampler", Binding);
+    }
   }
 }
 } // namespace
@@ -199,10 +205,6 @@ void RootSignatureBindingValidation::addRsBindingInfo(
           RSD.ParametersContainer.getDescriptorTable(Loc);
 
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-        if (Range.RangeType ==
-            llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
-          continue;
-
         if (Header.ShaderVisibility ==
                 llvm::to_underlying(dxbc::ShaderVisibility::All) ||
             Header.ShaderVisibility == llvm::to_underlying(Visibility))
@@ -214,29 +216,6 @@ void RootSignatureBindingValidation::addRsBindingInfo(
   }
 }
 
-bool RootSignatureBindingValidation::checkCregBinding(
-    ResourceInfo::ResourceBinding Binding) {
-  return CRegBindingsMap.overlaps(
-      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-      combineUint32ToUint64(Binding.Space,
-                            Binding.LowerBound + Binding.Size - 1));
-}
-
-bool RootSignatureBindingValidation::checkTRegBinding(
-    ResourceInfo::ResourceBinding Binding) {
-  return TRegBindingsMap.overlaps(
-      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-      combineUint32ToUint64(Binding.Space, Binding.LowerBound + Binding.Size));
-}
-
-bool RootSignatureBindingValidation::checkURegBinding(
-    ResourceInfo::ResourceBinding Binding) {
-  return URegBindingsMap.overlaps(
-      combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-      combineUint32ToUint64(Binding.Space,
-                            Binding.LowerBound + Binding.Size - 1));
-}
-
 PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
   DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 58113bf9f93c7..0fa0285425d7e 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -36,12 +36,13 @@ class RootSignatureBindingValidation {
   MapT CRegBindingsMap;
   MapT TRegBindingsMap;
   MapT URegBindingsMap;
+  MapT SamplersBindingsMap;
 
   void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) {
     assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) ||
             Type == llvm::to_underlying(dxbc::RootParameterType::SRV) ||
             Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) &&
-           "Invalid Type");
+           "Invalid Type in add Range Method");
 
     llvm::dxil::ResourceInfo::ResourceBinding Binding;
     Binding.LowerBound = Desc.ShaderRegister;
@@ -53,19 +54,20 @@ class RootSignatureBindingValidation {
     uint64_t HighRange = combineUint32ToUint64(
         Binding.Space, Binding.LowerBound + Binding.Size - 1);
 
+    assert(LowRange <= HighRange && "Invalid range configuration");
+
     switch (Type) {
 
     case llvm::to_underlying(dxbc::RootParameterType::CBV):
       CRegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
     case llvm::to_underlying(dxbc::RootParameterType::SRV):
       TRegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
     case llvm::to_underlying(dxbc::RootParameterType::UAV):
       URegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
     }
-    llvm_unreachable("Invalid Type in add Range Method");
   }
 
   void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) {
@@ -80,33 +82,59 @@ class RootSignatureBindingValidation {
     uint64_t HighRange = combineUint32ToUint64(
         Binding.Space, Binding.LowerBound + Binding.Size - 1);
 
+    assert(LowRange <= HighRange && "Invalid range configuration");
+
     switch (Range.RangeType) {
     case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
       CRegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
     case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
       TRegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
     case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
       URegBindingsMap.insert(LowRange, HighRange, Binding);
-      return;
+      break;
+    case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler):
+      SamplersBindingsMap.insert(LowRange, HighRange, Binding);
+      break;
     }
-    llvm_unreachable("Invalid Type in add Range Method");
   }
 
 public:
   RootSignatureBindingValidation()
       : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator),
-        URegBindingsMap(Allocator) {}
+        URegBindingsMap(Allocator), SamplersBindingsMap(Allocator) {}
 
   void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD,
                         dxbc::ShaderVisibility Visibility);
 
-  bool checkCregBinding(dxil::ResourceInfo::ResourceBinding Binding);
+  bool checkCRegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
+    return CRegBindingsMap.overlaps(
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+        combineUint32ToUint64(Binding.Space,
+                              Binding.LowerBound + Binding.Size - 1));
+  }
 
-  bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding);
+  bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
+    return TRegBindingsMap.overlaps(
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+        combineUint32ToUint64(Binding.Space,
+                              Binding.LowerBound + Binding.Size - 1));
+  }
 
-  bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding);
+  bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
+    return URegBindingsMap.overlaps(
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+        combineUint32ToUint64(Binding.Space,
+                              Binding.LowerBound + Binding.Size - 1));
+  }
+
+  bool checkSamplerBinding(dxil::ResourceInfo::ResourceBinding Binding) {
+    return SamplersBindingsMap.overlaps(
+        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
+        combineUint32ToUint64(Binding.Space,
+                              Binding.LowerBound + Binding.Size - 1));
+  }
 };
 
 class DXILPostOptimizationValidation
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 4094df160ef6f..2a68a4c324a09 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -635,8 +635,9 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
-  FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
-      RootSignatureBindingInfo(analyzeModule(M)));
+  if (!FuncToRsMap)
+    FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
+        RootSignatureBindingInfo(analyzeModule(M)));
   return false;
 }
 
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
index 9d89dbdd9107b..053721de1eb1f 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
@@ -13,7 +13,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
 !2 = !{ ptr @main, !3, i32 1 } ; function, root signature
 !3 = !{ !5 } ; list of root signature elements
 !5 = !{ !"DescriptorTable", i32 0, !6, !7 }
-!6 = !{ !"Sampler", i32 0, i32 1, i32 0, i32 -1, i32 1 }
+!6 = !{ !"Sampler", i32 1, i32 1, i32 0, i32 -1, i32 1 }
 !7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 3 }
 
 
@@ -33,7 +33,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
 ; DXC-NEXT:             RangesOffset:    44
 ; DXC-NEXT:             Ranges:
 ; DXC-NEXT:               - RangeType:       3
-; DXC-NEXT:                 NumDescriptors:  0
+; DXC-NEXT:                 NumDescriptors:  1
 ; DXC-NEXT:                 BaseShaderRegister: 1
 ; DXC-NEXT:                 RegisterSpace:   0
 ; DXC-NEXT:                 OffsetInDescriptorsFromTableStart: 4294967295
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 2b29fd30a7a56..8d75249dc6ecb 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -31,6 +31,7 @@
 ; CHECK-NEXT:   DXIL Module Metadata analysis
 ; CHECK-NEXT:   DXIL Shader Flag Analysis
 ; CHECK-NEXT:   DXIL Translate Metadata
+; CHECK-NEXT:   DXIL Root Signature Analysis
 ; CHECK-NEXT:   DXIL Post Optimization Validation
 ; CHECK-NEXT:   DXIL Op Lowering
 ; CHECK-NEXT:   DXIL Prepare Module

>From 28350b2dfe2a896b2199260953c1d061550badba Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 5 Jul 2025 00:35:07 +0000
Subject: [PATCH 14/68] fix issue

---
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 5c763c24a210a..6c8ae8eaaea77 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -160,11 +160,9 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   assert(MMI.EntryPropertyVec.size() == 1);
 
-  auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
   const auto &RS = RSA.getDescForFunction(EntryFunction);
-  const auto &RS = RSA.getDescForFunction(EntryFunction);
 
   if (!RS)
     return;

>From 4fd2e0bfdda5f87a3204982aa01d8b158945eadf Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 5 Jul 2025 00:37:12 +0000
Subject: [PATCH 15/68] sync parent

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index ecfc577d1b97d..3832182277050 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -47,7 +47,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map){};
+      : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
@@ -72,7 +72,10 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
 
   using Result = RootSignatureBindingInfo;
 
-  RootSignatureBindingInfo run(Module &M, ModuleAnalysisManager &AM);
+  Result run(Module &M, ModuleAnalysisManager &AM);
+
+private:
+  std::unique_ptr<RootSignatureBindingInfo> AnalysisResult;
 };
 
 /// Wrapper pass for the legacy pass manager.

>From e25ee87104bbb7013da38761df2beee7c98f4a9a Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Sat, 5 Jul 2025 00:39:18 +0000
Subject: [PATCH 16/68] sync parent

---
 llvm/lib/Target/DirectX/DXILRootSignature.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 2a68a4c324a09..5a53ea8a3631b 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -554,9 +554,12 @@ analyzeModule(Module &M) {
 
 AnalysisKey RootSignatureAnalysis::Key;
 
-RootSignatureBindingInfo RootSignatureAnalysis::run(Module &M,
-                                                    ModuleAnalysisManager &AM) {
-  return RootSignatureBindingInfo(analyzeModule(M));
+RootSignatureAnalysis::Result
+RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
+  if (!AnalysisResult)
+    AnalysisResult = std::make_unique<RootSignatureBindingInfo>(
+        RootSignatureBindingInfo(analyzeModule(M)));
+  return *AnalysisResult;
 }
 
 //===----------------------------------------------------------------------===//

>From 881dd365da77a817dd2be4f2aed2426b15a38d24 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 7 Jul 2025 20:14:49 +0000
Subject: [PATCH 17/68] address comments

---
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 3 ++-
 llvm/lib/Target/DirectX/DXILRootSignature.h    | 4 +---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 6c8ae8eaaea77..b6e8ce7d78b23 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -162,7 +162,8 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
-  const auto &RS = RSA.getDescForFunction(EntryFunction);
+  const std::optional<mcdxbc::RootSignatureDesc> &RS =
+      RSA.getDescForFunction(EntryFunction);
 
   if (!RS)
     return;
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 3832182277050..e975ceb22ea54 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -47,7 +47,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map) {};
+      : FuncToRsMap(Map){};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 
@@ -88,8 +88,6 @@ class RootSignatureAnalysisWrapper : public ModulePass {
 
 public:
   static char ID;
-  using Result = RootSignatureBindingInfo;
-
   RootSignatureAnalysisWrapper() : ModulePass(ID) {}
 
   RootSignatureBindingInfo &getRSInfo() { return *FuncToRsMap; }

>From c16f15b4cd469a3f6efc2e4b0e098190d7fd0787 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 8 Jul 2025 17:00:28 +0000
Subject: [PATCH 18/68] fix test

---
 clang/test/SemaHLSL/RootSignature-Validation.hlsl | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
index 5a7f5baf00619..c4ea897c6f490 100644
--- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
@@ -16,11 +16,11 @@ cbuffer CB : register(b3, space1) {
 StructuredBuffer<int> In : register(t0, space0);
 RWStructuredBuffer<int> Out : register(u0);
 
-RWBuffer<float> UAV : register(u4294967294);
+RWStructuredBuffer<float> UAV : register(u4294967294);
 
-RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
+RWStructuredBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
 
-RWBuffer<float> UAV3 : register(space0);
+RWStructuredBuffer<float> UAV3 : register(space0);
 
 
 

>From c7d5be77bd7c5421aca2e105dbab84854e335703 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 8 Jul 2025 17:18:15 +0000
Subject: [PATCH 19/68] format

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index e975ceb22ea54..41c63939f93a6 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -47,7 +47,7 @@ class RootSignatureBindingInfo {
   RootSignatureBindingInfo() = default;
   RootSignatureBindingInfo(
       SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> Map)
-      : FuncToRsMap(Map){};
+      : FuncToRsMap(Map) {};
 
   iterator find(const Function *F) { return FuncToRsMap.find(F); }
 

>From cc5afaefcafe97e92547c42c43c8747c0c7981fe Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 8 Jul 2025 19:02:00 +0000
Subject: [PATCH 20/68] address changes

---
 llvm/lib/Target/DirectX/DXILRootSignature.cpp | 12 ++++--------
 llvm/lib/Target/DirectX/DXILRootSignature.h   |  3 ---
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 5a53ea8a3631b..3848ad63dc468 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -556,10 +556,7 @@ AnalysisKey RootSignatureAnalysis::Key;
 
 RootSignatureAnalysis::Result
 RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
-  if (!AnalysisResult)
-    AnalysisResult = std::make_unique<RootSignatureBindingInfo>(
-        RootSignatureBindingInfo(analyzeModule(M)));
-  return *AnalysisResult;
+  return RootSignatureBindingInfo(analyzeModule(M));
 }
 
 //===----------------------------------------------------------------------===//
@@ -638,15 +635,14 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
 
 //===----------------------------------------------------------------------===//
 bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
-  if (!FuncToRsMap)
-    FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
-        RootSignatureBindingInfo(analyzeModule(M)));
+  FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(
+      RootSignatureBindingInfo(analyzeModule(M)));
   return false;
 }
 
 void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
 }
 
 char RootSignatureAnalysisWrapper::ID = 0;
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 41c63939f93a6..07dbd51bed391 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -73,9 +73,6 @@ class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
   using Result = RootSignatureBindingInfo;
 
   Result run(Module &M, ModuleAnalysisManager &AM);
-
-private:
-  std::unique_ptr<RootSignatureBindingInfo> AnalysisResult;
 };
 
 /// Wrapper pass for the legacy pass manager.

>From 571a0ef25df4ffffe56cdc7d7274ebe9d23996be Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 8 Jul 2025 20:31:43 +0000
Subject: [PATCH 21/68] fix tests

---
 .../RootSignature-Validation-Fail.hlsl        |  35 ----
 .../SemaHLSL/RootSignature-Validation.hlsl    |  33 ----
 .../DirectX/rootsignature-validation-fail.ll  | 160 ++++++++++++++++++
 .../DirectX/rootsignature-validation.ll       | 149 ++++++++++++++++
 4 files changed, 309 insertions(+), 68 deletions(-)
 delete mode 100644 clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl
 delete mode 100644 clang/test/SemaHLSL/RootSignature-Validation.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation.ll

diff --git a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl b/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl
deleted file mode 100644
index b590ed67e7085..0000000000000
--- a/clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: not %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 | FileCheck %s
-
-// CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature
-// CHECK: error: register srv (space=0, register=0) is not defined in Root Signature
-// CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature
-
-
-#define ROOT_SIGNATURE \
-    "CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX), " \
-    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)"
-
-cbuffer CB : register(b3, space665) {
-  float a;
-}
-
-StructuredBuffer<int> In : register(t0, space0);
-RWStructuredBuffer<int> Out : register(u0);
-
-RWBuffer<float> UAV : register(u4294967295);
-
-RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
-
-RWBuffer<float> UAV3 : register(space0);
-
-
-
-// Compute Shader for UAV testing
-[numthreads(8, 8, 1)]
-[RootSignature(ROOT_SIGNATURE)]
-void CSMain(uint id : SV_GroupID)
-{
-    Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0];
-}
diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl
deleted file mode 100644
index c4ea897c6f490..0000000000000
--- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 
-
-// expected-no-diagnostics
-
-
-#define ROOT_SIGNATURE \
-    "CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL), " \
-    "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX), " \
-    "DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)"
-
-cbuffer CB : register(b3, space1) {
-  float a;
-}
-
-StructuredBuffer<int> In : register(t0, space0);
-RWStructuredBuffer<int> Out : register(u0);
-
-RWStructuredBuffer<float> UAV : register(u4294967294);
-
-RWStructuredBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
-
-RWStructuredBuffer<float> UAV3 : register(space0);
-
-
-
-// Compute Shader for UAV testing
-[numthreads(8, 8, 1)]
-[RootSignature(ROOT_SIGNATURE)]
-void CSMain(uint id : SV_GroupID)
-{
-    Out[0] = a + id + In[0] + UAV[0] + UAV1[0] + UAV3[0];
-}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
new file mode 100644
index 0000000000000..54802c9e7ed22
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
@@ -0,0 +1,160 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+
+; CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature
+; CHECK: error: register srv (space=0, register=0) is not defined in Root Signature
+; CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature
+
+;
+; Resource Bindings:
+;
+; Name                                 Type  Format         Dim      ID      HLSL Bind     Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
+; In                                texture  struct         r/o      T0             t0         1
+; Out                                   UAV  struct         r/w      U0             u0         1
+; UAV3                                  UAV     f32         buf      U1             u1         1
+; UAV1                                  UAV     f32         buf      U2             u2         1
+; UAV                                   UAV     f32         buf      U3    u4294967295         1
+; CB                                cbuffer      NA          NA     CB0   cb3,space665         1
+;
+; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl'
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxilv1.5-unknown-shadermodel6.5-compute"
+
+%__cblayout_CB = type <{ float }>
+%"StructuredBuffer<int32_t>" = type { i32 }
+%"RWStructuredBuffer<int32_t>" = type { i32 }
+%"RWBuffer<float>" = type { float }
+%CBuffer.CB = type { float }
+
+ at CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+ at .str = private unnamed_addr constant [3 x i8] c"In\00", align 1
+ at .str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
+ at .str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1
+ at .str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1
+ at .str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1
+ at In = external constant %"StructuredBuffer<int32_t>"
+ at Out = external constant %"RWStructuredBuffer<int32_t>"
+ at UAV3 = external constant %"RWBuffer<float>"
+ at UAV1 = external constant %"RWBuffer<float>"
+ at UAV = external constant %"RWBuffer<float>"
+ at CB = external constant %CBuffer.CB
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+define void @CSMain() local_unnamed_addr #1 {
+entry:
+  %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4
+  %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str)
+  %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2)
+  %2 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr nonnull @.str.4)
+  %3 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6)
+  %4 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10)
+  %5 = tail call i32 @llvm.dx.group.id(i32 0)
+  %6 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0)
+  %7 = extractvalue { float, float, float, float } %6, 0
+  %conv.i = uitofp i32 %5 to float
+  %add.i = fadd reassoc nnan ninf nsz arcp afn float %7, %conv.i
+  %8 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0)
+  %9 = extractvalue { i32, i1 } %8, 0
+  %conv1.i = sitofp i32 %9 to float
+  %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %conv1.i
+  %10 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %2, i32 0)
+  %11 = extractvalue { float, i1 } %10, 0
+  %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %11
+  %12 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %3, i32 0)
+  %13 = extractvalue { float, i1 } %12, 0
+  %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %13
+  %14 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %4, i32 0)
+  %15 = extractvalue { float, i1 } %14, 0
+  %add8.i = fadd reassoc nnan ninf nsz arcp afn float %add6.i, %15
+  %conv9.i = fptosi float %add8.i to i32
+  call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv9.i)
+  ret void
+}
+
+; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
+declare i32 @llvm.dx.group.id(i32) #2
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #0
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #3
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #3
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
+declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #3
+
+; uselistorder directives
+uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 }
+uselistorder ptr @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 }
+
+attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { mustprogress nofree nosync nounwind willreturn memory(none) }
+attributes #3 = { nocallback nofree nosync nounwind willreturn memory(read) }
+attributes #4 = { nocallback nofree nosync nounwind willreturn memory(write) }
+
+!dx.rootsignatures = !{!0}
+!llvm.module.flags = !{!9, !10}
+!dx.valver = !{!11}
+!llvm.ident = !{!12}
+!dx.shaderModel = !{!13}
+!dx.version = !{!14}
+!dx.resources = !{!15}
+!dx.entryPoints = !{!27}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{i32 7, !"frame-pointer", i32 2}
+!11 = !{i32 1, i32 8}
+!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"}
+!13 = !{!"cs", i32 6, i32 5}
+!14 = !{i32 1, i32 5}
+!15 = !{!16, !19, !25, null}
+!16 = !{!17}
+!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18}
+!18 = !{i32 1, i32 4}
+!19 = !{!20, !21, !23, !24}
+!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
+!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
+!22 = !{i32 0, i32 9}
+!23 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
+!24 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -1, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
+!25 = !{!26}
+!26 = !{i32 0, ptr @CB, !"CB", i32 665, i32 3, i32 1, i32 4, null}
+!27 = !{ptr @CSMain, !"CSMain", null, !15, !28}
+!28 = !{i32 0, i64 16, i32 4, !29}
+!29 = !{i32 8, i32 8, i32 1}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
new file mode 100644
index 0000000000000..eaf8512c284a7
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -0,0 +1,149 @@
+; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; expected-no-diagnostics
+
+;
+; Resource Bindings:
+;
+; Name                                 Type  Format         Dim      ID      HLSL Bind     Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
+; In                                texture  struct         r/o      T0             t0         1
+; Out                                   UAV  struct         r/w      U0             u0         1
+; UAV3                                  UAV  struct         r/w      U1             u1         1
+; UAV1                                  UAV  struct         r/w      U2             u2         1
+; UAV                                   UAV  struct         r/w      U3    u4294967294         1
+; CB                                cbuffer      NA          NA     CB0     cb3,space1         1
+;
+; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation.hlsl'
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxilv1.5-unknown-shadermodel6.5-compute"
+
+%__cblayout_CB = type <{ float }>
+%"StructuredBuffer<int32_t>" = type { i32 }
+%"RWStructuredBuffer<int32_t>" = type { i32 }
+%"RWStructuredBuffer<float>" = type { float }
+%CBuffer.CB = type { float }
+
+ at CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+ at .str = private unnamed_addr constant [3 x i8] c"In\00", align 1
+ at .str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
+ at .str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1
+ at .str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1
+ at .str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1
+ at In = external constant %"StructuredBuffer<int32_t>"
+ at Out = external constant %"RWStructuredBuffer<int32_t>"
+ at UAV3 = external constant %"RWStructuredBuffer<float>"
+ at UAV1 = external constant %"RWStructuredBuffer<float>"
+ at UAV = external constant %"RWStructuredBuffer<float>"
+ at CB = external constant %CBuffer.CB
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+define void @CSMain() local_unnamed_addr #1 {
+entry:
+  %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4
+  %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str)
+  %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2)
+  %2 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 -2, i32 1, i32 0, i1 false, ptr nonnull @.str.4)
+  %3 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6)
+  %4 = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10)
+  %5 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0)
+  %6 = extractvalue { float, float, float, float } %5, 0
+  %7 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0)
+  %8 = extractvalue { i32, i1 } %7, 0
+  %conv.i = sitofp i32 %8 to float
+  %add.i = fadd reassoc nnan ninf nsz arcp afn float %6, %conv.i
+  %9 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %2, i32 0, i32 0)
+  %10 = extractvalue { float, i1 } %9, 0
+  %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %10
+  %11 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %3, i32 0, i32 0)
+  %12 = extractvalue { float, i1 } %11, 0
+  %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %12
+  %13 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %4, i32 0, i32 0)
+  %14 = extractvalue { float, i1 } %13, 0
+  %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %14
+  %conv7.i = fptosi float %add6.i to i32
+  call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv7.i)
+  ret void
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32, i32, i32, i32, i1, ptr) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) #0
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #2
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32, i32) #2
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
+declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #3
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
+declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #2
+
+; uselistorder directives
+uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 }
+uselistorder ptr @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 }
+
+attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) }
+attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) }
+
+!dx.rootsignatures = !{!0}
+!llvm.module.flags = !{!9, !10}
+!dx.valver = !{!11}
+!llvm.ident = !{!12}
+!dx.shaderModel = !{!13}
+!dx.version = !{!14}
+!dx.resources = !{!15}
+!dx.entryPoints = !{!26}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4}
+!3 = !{!"DescriptorTable", i32 0, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 1, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{i32 7, !"frame-pointer", i32 2}
+!11 = !{i32 1, i32 8}
+!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"}
+!13 = !{!"cs", i32 6, i32 5}
+!14 = !{i32 1, i32 5}
+!15 = !{!16, !19, !24, null}
+!16 = !{!17}
+!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18}
+!18 = !{i32 1, i32 4}
+!19 = !{!20, !21, !22, !23}
+!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
+!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
+!22 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
+!23 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -2, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
+!24 = !{!25}
+!25 = !{i32 0, ptr @CB, !"CB", i32 1, i32 3, i32 1, i32 4, null}
+!26 = !{ptr @CSMain, !"CSMain", null, !15, !27}
+!27 = !{i32 0, i64 16, i32 4, !28}
+!28 = !{i32 8, i32 8, i32 1}

>From e0bc8623dba624c1d3b01bd73102b258df5cc006 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 8 Jul 2025 21:18:45 +0000
Subject: [PATCH 22/68] add preserved

---
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 +-
 llvm/test/CodeGen/DirectX/llc-pipeline.ll      | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index b6e8ce7d78b23..a6dfc11c9c44c 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -62,10 +62,10 @@ class DXContainerGlobals : public llvm::ModulePass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
     AU.addRequired<ShaderFlagsAnalysisWrapper>();
-    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
     AU.addRequired<DXILResourceTypeWrapperPass>();
     AU.addRequired<DXILResourceWrapperPass>();
+    AU.addPreserved<RootSignatureAnalysisWrapper>();
   }
 };
 
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 8d75249dc6ecb..e8612f4213539 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -40,7 +40,6 @@
 ; CHECK-ASM-NEXT: Print Module IR
 
 ; CHECK-OBJ-NEXT: DXIL Embedder
-; CHECK-OBJ-NEXT: DXIL Root Signature Analysis
 ; CHECK-OBJ-NEXT: DXContainer Global Emitter
 ; CHECK-OBJ-NEXT: FunctionPass Manager
 ; CHECK-OBJ-NEXT:   Lazy Machine Block Frequency Analysis

>From b5a0b32a43b04f9f20efb879a7b8644e937cfaf7 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 10 Jul 2025 17:46:07 +0000
Subject: [PATCH 23/68] addressing comments

---
 llvm/lib/Target/DirectX/DXILRootSignature.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 07dbd51bed391..ccffa3fd0a3e2 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -106,4 +106,4 @@ class RootSignatureAnalysisPrinter
 
 } // namespace dxil
 } // namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H

>From 5ccb842c9ba0cf558a30361793f8c33996c5f526 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 11 Jul 2025 06:27:26 +0000
Subject: [PATCH 24/68] updating

---
 .../lib/Target/DirectX/DXContainerGlobals.cpp |   2 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp    |   2 +
 .../DXILPostOptimizationValidation.cpp        | 160 +++++++++++-------
 .../DirectX/DXILPostOptimizationValidation.h  | 149 +++++-----------
 llvm/lib/Target/DirectX/DXILPrepare.cpp       |   1 -
 llvm/lib/Target/DirectX/DXILRootSignature.cpp |   3 +-
 llvm/test/CodeGen/DirectX/llc-pipeline.ll     |   1 -
 .../DirectX/rootsignature-validation-fail.ll  | 143 +---------------
 8 files changed, 147 insertions(+), 314 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index a6dfc11c9c44c..97cbb76da2a55 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -65,7 +65,7 @@ class DXContainerGlobals : public llvm::ModulePass {
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
     AU.addRequired<DXILResourceTypeWrapperPass>();
     AU.addRequired<DXILResourceWrapperPass>();
-    AU.addPreserved<RootSignatureAnalysisWrapper>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
   }
 };
 
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 0ec15a629d0a2..db7719e129ad0 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -9,6 +9,7 @@
 #include "DXILOpLowering.h"
 #include "DXILConstants.h"
 #include "DXILOpBuilder.h"
+#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallVector.h"
@@ -945,6 +946,7 @@ class DXILOpLoweringLegacy : public ModulePass {
     AU.addPreserved<DXILResourceWrapperPass>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
+    AU.addPreserved<RootSignatureAnalysisWrapper>();
   }
 };
 char DXILOpLoweringLegacy::ID = 0;
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index a52a04323514c..30a4cc6070971 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -10,9 +10,12 @@
 #include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
@@ -123,6 +126,70 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
+static uint32_t parameterToRangeType(uint32_t Type) {
+  switch (Type) {
+  case llvm::to_underlying(dxbc::RootParameterType::CBV):
+    return llvm::to_underlying(dxbc::DescriptorRangeType::CBV);
+  break;
+  case llvm::to_underlying(dxbc::RootParameterType::SRV):
+      return llvm::to_underlying(dxbc::DescriptorRangeType::SRV);
+  break;
+  case llvm::to_underlying(dxbc::RootParameterType::UAV):
+        return llvm::to_underlying(dxbc::DescriptorRangeType::UAV);
+  break;
+  default:
+    llvm_unreachable("Root Parameter Type has no Range Type equivalent");
+  }
+}
+
+static RootSignatureBindingValidation initRsBindingValdation(const mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
+
+  RootSignatureBindingValidation Validation;
+
+  for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
+    const auto &[Type, Loc] =
+        RSD.ParametersContainer.getTypeAndLocForParameter(I);
+
+    const auto &Header = RSD.ParametersContainer.getHeader(I);
+    if (Header.ShaderVisibility !=
+          llvm::to_underlying(dxbc::ShaderVisibility::All) &&
+          Header.ShaderVisibility != llvm::to_underlying(Visibility))
+          continue;
+          
+    switch (Type) {
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+    case llvm::to_underlying(dxbc::RootParameterType::CBV): {
+      dxbc::RTS0::v2::RootDescriptor Desc =
+          RSD.ParametersContainer.getRootDescriptor(Loc);
+
+      llvm::dxil::ResourceInfo::ResourceBinding Binding;
+      Binding.LowerBound = Desc.ShaderRegister;
+      Binding.Space = Desc.RegisterSpace;
+      Binding.Size = 1;
+  
+      Validation.addBinding(parameterToRangeType(Type), Binding);
+      break;
+    }
+    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+      const mcdxbc::DescriptorTable &Table =
+          RSD.ParametersContainer.getDescriptorTable(Loc);
+
+      for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
+          llvm::dxil::ResourceInfo::ResourceBinding Binding;
+          Binding.LowerBound = Range.BaseShaderRegister;
+          Binding.Space = Range.RegisterSpace;
+          Binding.Size = Range.NumDescriptors;
+          Validation.addBinding(Range.RangeType, Binding);
+      }
+      break;
+    }
+    }
+  }
+
+  return Validation;
+}
+
 std::optional<mcdxbc::RootSignatureDesc>
 getRootSignature(RootSignatureBindingInfo &RSBI,
                  dxil::ModuleMetadataInfo &MMI) {
@@ -135,6 +202,27 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
   return RootSigDesc;
 }
 
+static void reportUnboundRegisters(
+    Module &M,
+    const std::vector<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
+    iterator_range<SmallVector<dxil::ResourceInfo>::iterator> &Resources) {
+  for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) {
+    bool Bound = false;
+    ResourceInfo::ResourceBinding ResBinding = Res->getBinding();
+    for (const auto &Binding : Bindings) {
+      if (ResBinding.Space == Binding.Space &&
+          ResBinding.LowerBound >= Binding.LowerBound &&
+          ResBinding.LowerBound < Binding.LowerBound + Binding.Size) {
+        Bound = true;
+        break;
+      }
+    }
+    if (!Bound) {
+      reportRegNotBound(M, Res->getName(), Res->getBinding());
+    }
+  }
+}
+
 static void reportErrors(Module &M, DXILResourceMap &DRM,
                          DXILResourceBindingInfo &DRBI,
                          RootSignatureBindingInfo &RSBI,
@@ -150,72 +238,21 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   if (auto RSD = getRootSignature(RSBI, MMI)) {
 
-    RootSignatureBindingValidation Validation;
-    Validation.addRsBindingInfo(*RSD, tripleToVisibility(MMI.ShaderProfile));
-
-    for (const ResourceInfo &CBuf : DRM.cbuffers()) {
-      ResourceInfo::ResourceBinding Binding = CBuf.getBinding();
-      if (!Validation.checkCRegBinding(Binding))
-        reportRegNotBound(M, "cbuffer", Binding);
-    }
-
-    for (const ResourceInfo &SRV : DRM.srvs()) {
-      ResourceInfo::ResourceBinding Binding = SRV.getBinding();
-      if (!Validation.checkTRegBinding(Binding))
-        reportRegNotBound(M, "srv", Binding);
-    }
+    RootSignatureBindingValidation Validation = initRsBindingValdation(*RSD, tripleToVisibility(MMI.ShaderProfile));
 
-    for (const ResourceInfo &UAV : DRM.uavs()) {
-      ResourceInfo::ResourceBinding Binding = UAV.getBinding();
-      if (!Validation.checkURegBinding(Binding))
-        reportRegNotBound(M, "uav", Binding);
-    }
+    auto Cbufs = DRM.cbuffers();
+    auto SRVs = DRM.srvs();
+    auto UAVs = DRM.uavs();
+    auto Samplers = DRM.samplers();
 
-    for (const ResourceInfo &Sampler : DRM.samplers()) {
-      ResourceInfo::ResourceBinding Binding = Sampler.getBinding();
-      if (!Validation.checkSamplerBinding(Binding))
-        reportRegNotBound(M, "sampler", Binding);
-    }
+    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV), Cbufs);
+    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV), UAVs);
+    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler), Samplers);
+    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV), SRVs);
   }
 }
 } // namespace
 
-void RootSignatureBindingValidation::addRsBindingInfo(
-    mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
-  for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
-    const auto &[Type, Loc] =
-        RSD.ParametersContainer.getTypeAndLocForParameter(I);
-
-    const auto &Header = RSD.ParametersContainer.getHeader(I);
-    switch (Type) {
-    case llvm::to_underlying(dxbc::RootParameterType::SRV):
-    case llvm::to_underlying(dxbc::RootParameterType::UAV):
-    case llvm::to_underlying(dxbc::RootParameterType::CBV): {
-      dxbc::RTS0::v2::RootDescriptor Desc =
-          RSD.ParametersContainer.getRootDescriptor(Loc);
-
-      if (Header.ShaderVisibility ==
-              llvm::to_underlying(dxbc::ShaderVisibility::All) ||
-          Header.ShaderVisibility == llvm::to_underlying(Visibility))
-        addRange(Desc, Type);
-      break;
-    }
-    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
-      const mcdxbc::DescriptorTable &Table =
-          RSD.ParametersContainer.getDescriptorTable(Loc);
-
-      for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-        if (Header.ShaderVisibility ==
-                llvm::to_underlying(dxbc::ShaderVisibility::All) ||
-            Header.ShaderVisibility == llvm::to_underlying(Visibility))
-          addRange(Range);
-      }
-      break;
-    }
-    }
-  }
-}
-
 PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
   DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
@@ -252,8 +289,8 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
   void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
     AU.addRequired<DXILResourceWrapperPass>();
     AU.addRequired<DXILResourceBindingWrapperPass>();
-    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<DXILResourceWrapperPass>();
     AU.addPreserved<DXILResourceBindingWrapperPass>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
@@ -269,6 +306,7 @@ INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
 INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
 INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
                     "DXIL Post Optimization Validation", false, false)
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 0fa0285425d7e..9a6fe258b02c7 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -15,126 +15,55 @@
 #define LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
 
 #include "DXILRootSignature.h"
-#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/PassManager.h"
+#include <cstdint>
 
 namespace llvm {
 
-static uint64_t combineUint32ToUint64(uint32_t High, uint32_t Low) {
-  return (static_cast<uint64_t>(High) << 32) | Low;
-}
-
 class RootSignatureBindingValidation {
-  using MapT =
-      llvm::IntervalMap<uint64_t, dxil::ResourceInfo::ResourceBinding,
-                        sizeof(llvm::dxil::ResourceInfo::ResourceBinding),
-                        llvm::IntervalMapInfo<uint64_t>>;
-
 private:
-  MapT::Allocator Allocator;
-  MapT CRegBindingsMap;
-  MapT TRegBindingsMap;
-  MapT URegBindingsMap;
-  MapT SamplersBindingsMap;
-
-  void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) {
-    assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) ||
-            Type == llvm::to_underlying(dxbc::RootParameterType::SRV) ||
-            Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) &&
-           "Invalid Type in add Range Method");
-
-    llvm::dxil::ResourceInfo::ResourceBinding Binding;
-    Binding.LowerBound = Desc.ShaderRegister;
-    Binding.Space = Desc.RegisterSpace;
-    Binding.Size = 1;
-
-    uint64_t LowRange =
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound);
-    uint64_t HighRange = combineUint32ToUint64(
-        Binding.Space, Binding.LowerBound + Binding.Size - 1);
+    llvm::SmallVector<dxil::ResourceInfo::ResourceBinding, 16> Bindings;    
+    struct TypeRange {
+        uint32_t Start;
+        uint32_t End; 
+    };
+    std::unordered_map<uint32_t, TypeRange> Ranges;
 
-    assert(LowRange <= HighRange && "Invalid range configuration");
-
-    switch (Type) {
-
-    case llvm::to_underlying(dxbc::RootParameterType::CBV):
-      CRegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
-    case llvm::to_underlying(dxbc::RootParameterType::SRV):
-      TRegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
-    case llvm::to_underlying(dxbc::RootParameterType::UAV):
-      URegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
+public:
+    void addBinding(const uint32_t& Type, const dxil::ResourceInfo::ResourceBinding& Binding) {
+        auto It = Ranges.find(Type);
+        
+        if (It == Ranges.end()) {
+            uint32_t InsertPos = Bindings.size();
+            Bindings.push_back(Binding);
+            Ranges[Type] = {InsertPos, InsertPos + 1};
+        } else {
+            uint32_t InsertPos = It->second.End;
+            Bindings.insert(Bindings.begin() + InsertPos, Binding);
+            
+            It->second.End++;
+            
+            for (auto& [type, range] : Ranges) {
+                if (range.Start > InsertPos) {
+                    range.Start++;
+                    range.End++;
+                }
+            }
+        }
     }
-  }
-
-  void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) {
-
-    llvm::dxil::ResourceInfo::ResourceBinding Binding;
-    Binding.LowerBound = Range.BaseShaderRegister;
-    Binding.Space = Range.RegisterSpace;
-    Binding.Size = Range.NumDescriptors;
-
-    uint64_t LowRange =
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound);
-    uint64_t HighRange = combineUint32ToUint64(
-        Binding.Space, Binding.LowerBound + Binding.Size - 1);
-
-    assert(LowRange <= HighRange && "Invalid range configuration");
-
-    switch (Range.RangeType) {
-    case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
-      CRegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
-    case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
-      TRegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
-    case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
-      URegBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
-    case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler):
-      SamplersBindingsMap.insert(LowRange, HighRange, Binding);
-      break;
+    
+    llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding> getBindingsOfType(const dxbc::DescriptorRangeType& Type) const {
+        auto It = Ranges.find(llvm::to_underlying(Type));
+        if (It == Ranges.end()) {
+            return {};
+        }
+        return llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>(Bindings.data() + It->second.Start, 
+                                               It->second.End - It->second.Start);
     }
-  }
-
-public:
-  RootSignatureBindingValidation()
-      : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator),
-        URegBindingsMap(Allocator), SamplersBindingsMap(Allocator) {}
-
-  void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD,
-                        dxbc::ShaderVisibility Visibility);
-
-  bool checkCRegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
-    return CRegBindingsMap.overlaps(
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-        combineUint32ToUint64(Binding.Space,
-                              Binding.LowerBound + Binding.Size - 1));
-  }
-
-  bool checkTRegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
-    return TRegBindingsMap.overlaps(
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-        combineUint32ToUint64(Binding.Space,
-                              Binding.LowerBound + Binding.Size - 1));
-  }
-
-  bool checkURegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
-    return URegBindingsMap.overlaps(
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-        combineUint32ToUint64(Binding.Space,
-                              Binding.LowerBound + Binding.Size - 1));
-  }
-
-  bool checkSamplerBinding(dxil::ResourceInfo::ResourceBinding Binding) {
-    return SamplersBindingsMap.overlaps(
-        combineUint32ToUint64(Binding.Space, Binding.LowerBound),
-        combineUint32ToUint64(Binding.Space,
-                              Binding.LowerBound + Binding.Size - 1));
-  }
 };
 
 class DXILPostOptimizationValidation
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index c8866bfefdfc5..9c3eba83eba7c 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -300,7 +300,6 @@ class DXILPrepareModule : public ModulePass {
   DXILPrepareModule() : ModulePass(ID) {}
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
-    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<RootSignatureAnalysisWrapper>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index dfc81626da01f..70cb8bc47e00c 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -684,7 +684,7 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
 
 void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
+  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
 }
 
 char RootSignatureAnalysisWrapper::ID = 0;
@@ -692,6 +692,7 @@ char RootSignatureAnalysisWrapper::ID = 0;
 INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper,
                       "dxil-root-signature-analysis",
                       "DXIL Root Signature Analysis", true, true)
+INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
 INITIALIZE_PASS_END(RootSignatureAnalysisWrapper,
                     "dxil-root-signature-analysis",
                     "DXIL Root Signature Analysis", true, true)
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 6c5e9be63da58..e8612f4213539 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -34,7 +34,6 @@
 ; CHECK-NEXT:   DXIL Root Signature Analysis
 ; CHECK-NEXT:   DXIL Post Optimization Validation
 ; CHECK-NEXT:   DXIL Op Lowering
-; CHECK-NEXT:   DXIL Root Signature Analysis
 ; CHECK-NEXT:   DXIL Prepare Module
 
 ; CHECK-ASM-NEXT: DXIL Metadata Pretty Printer
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
index 54802c9e7ed22..e52647fe888b1 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
@@ -1,132 +1,18 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register cbuffer (space=665, register=3) is not defined in Root Signature
-; CHECK: error: register srv (space=0, register=0) is not defined in Root Signature
-; CHECK: error: register uav (space=0, register=4294967295) is not defined in Root Signature
-
-;
-; Resource Bindings:
-;
-; Name                                 Type  Format         Dim      ID      HLSL Bind     Count
-; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
-; In                                texture  struct         r/o      T0             t0         1
-; Out                                   UAV  struct         r/w      U0             u0         1
-; UAV3                                  UAV     f32         buf      U1             u1         1
-; UAV1                                  UAV     f32         buf      U2             u2         1
-; UAV                                   UAV     f32         buf      U3    u4294967295         1
-; CB                                cbuffer      NA          NA     CB0   cb3,space665         1
-;
-; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation-Fail.hlsl'
-target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
-target triple = "dxilv1.5-unknown-shadermodel6.5-compute"
+; CHECK: error: register CB (space=665, register=3) is not defined in Root Signature
 
 %__cblayout_CB = type <{ float }>
-%"StructuredBuffer<int32_t>" = type { i32 }
-%"RWStructuredBuffer<int32_t>" = type { i32 }
-%"RWBuffer<float>" = type { float }
-%CBuffer.CB = type { float }
 
- at CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison
 @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
- at .str = private unnamed_addr constant [3 x i8] c"In\00", align 1
- at .str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
- at .str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1
- at .str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1
- at .str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1
- at In = external constant %"StructuredBuffer<int32_t>"
- at Out = external constant %"RWStructuredBuffer<int32_t>"
- at UAV3 = external constant %"RWBuffer<float>"
- at UAV1 = external constant %"RWBuffer<float>"
- at UAV = external constant %"RWBuffer<float>"
- at CB = external constant %CBuffer.CB
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0
 
-; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
-define void @CSMain() local_unnamed_addr #1 {
+define void @CSMain() "hlsl.shader"="compute" {
 entry:
-  %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4
-  %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str)
-  %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2)
-  %2 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr nonnull @.str.4)
-  %3 = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6)
-  %4 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10)
-  %5 = tail call i32 @llvm.dx.group.id(i32 0)
-  %6 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0)
-  %7 = extractvalue { float, float, float, float } %6, 0
-  %conv.i = uitofp i32 %5 to float
-  %add.i = fadd reassoc nnan ninf nsz arcp afn float %7, %conv.i
-  %8 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0)
-  %9 = extractvalue { i32, i1 } %8, 0
-  %conv1.i = sitofp i32 %9 to float
-  %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %conv1.i
-  %10 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %2, i32 0)
-  %11 = extractvalue { float, i1 } %10, 0
-  %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %11
-  %12 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %3, i32 0)
-  %13 = extractvalue { float, i1 } %12, 0
-  %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %13
-  %14 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %4, i32 0)
-  %15 = extractvalue { float, i1 } %14, 0
-  %add8.i = fadd reassoc nnan ninf nsz arcp afn float %add6.i, %15
-  %conv9.i = fptosi float %add8.i to i32
-  call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv9.i)
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
   ret void
 }
 
-; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
-declare i32 @llvm.dx.group.id(i32) #2
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #0
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #3
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #3
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
-declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #4
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #3
-
-; uselistorder directives
-uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 }
-uselistorder ptr @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_1_0_0t, { 2, 1, 0 }
-
-attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #2 = { mustprogress nofree nosync nounwind willreturn memory(none) }
-attributes #3 = { nocallback nofree nosync nounwind willreturn memory(read) }
-attributes #4 = { nocallback nofree nosync nounwind willreturn memory(write) }
-
 !dx.rootsignatures = !{!0}
-!llvm.module.flags = !{!9, !10}
-!dx.valver = !{!11}
-!llvm.ident = !{!12}
-!dx.shaderModel = !{!13}
-!dx.version = !{!14}
-!dx.resources = !{!15}
-!dx.entryPoints = !{!27}
 
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3, !5, !7}
@@ -137,24 +23,3 @@ attributes #4 = { nocallback nofree nosync nounwind willreturn memory(write) }
 !6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
 !7 = !{!"DescriptorTable", i32 0, !8}
 !8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
-!9 = !{i32 1, !"wchar_size", i32 4}
-!10 = !{i32 7, !"frame-pointer", i32 2}
-!11 = !{i32 1, i32 8}
-!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"}
-!13 = !{!"cs", i32 6, i32 5}
-!14 = !{i32 1, i32 5}
-!15 = !{!16, !19, !25, null}
-!16 = !{!17}
-!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18}
-!18 = !{i32 1, i32 4}
-!19 = !{!20, !21, !23, !24}
-!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
-!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
-!22 = !{i32 0, i32 9}
-!23 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
-!24 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -1, i32 1, i32 10, i1 false, i1 false, i1 false, !22}
-!25 = !{!26}
-!26 = !{i32 0, ptr @CB, !"CB", i32 665, i32 3, i32 1, i32 4, null}
-!27 = !{ptr @CSMain, !"CSMain", null, !15, !28}
-!28 = !{i32 0, i64 16, i32 4, !29}
-!29 = !{i32 8, i32 8, i32 1}

>From 5423aba8038731f6159266304fa8cad983b6af7c Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 14 Jul 2025 18:40:30 +0000
Subject: [PATCH 25/68] format

---
 .../DXILPostOptimizationValidation.cpp        | 50 ++++++++------
 .../DirectX/DXILPostOptimizationValidation.h  | 68 ++++++++++---------
 2 files changed, 64 insertions(+), 54 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 30a4cc6070971..035a5bd225ac8 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -130,19 +130,21 @@ static uint32_t parameterToRangeType(uint32_t Type) {
   switch (Type) {
   case llvm::to_underlying(dxbc::RootParameterType::CBV):
     return llvm::to_underlying(dxbc::DescriptorRangeType::CBV);
-  break;
+    break;
   case llvm::to_underlying(dxbc::RootParameterType::SRV):
-      return llvm::to_underlying(dxbc::DescriptorRangeType::SRV);
-  break;
+    return llvm::to_underlying(dxbc::DescriptorRangeType::SRV);
+    break;
   case llvm::to_underlying(dxbc::RootParameterType::UAV):
-        return llvm::to_underlying(dxbc::DescriptorRangeType::UAV);
-  break;
+    return llvm::to_underlying(dxbc::DescriptorRangeType::UAV);
+    break;
   default:
     llvm_unreachable("Root Parameter Type has no Range Type equivalent");
   }
 }
 
-static RootSignatureBindingValidation initRsBindingValdation(const mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
+static RootSignatureBindingValidation
+initRsBindingValdation(const mcdxbc::RootSignatureDesc &RSD,
+                       dxbc::ShaderVisibility Visibility) {
 
   RootSignatureBindingValidation Validation;
 
@@ -152,10 +154,10 @@ static RootSignatureBindingValidation initRsBindingValdation(const mcdxbc::RootS
 
     const auto &Header = RSD.ParametersContainer.getHeader(I);
     if (Header.ShaderVisibility !=
-          llvm::to_underlying(dxbc::ShaderVisibility::All) &&
-          Header.ShaderVisibility != llvm::to_underlying(Visibility))
-          continue;
-          
+            llvm::to_underlying(dxbc::ShaderVisibility::All) &&
+        Header.ShaderVisibility != llvm::to_underlying(Visibility))
+      continue;
+
     switch (Type) {
     case llvm::to_underlying(dxbc::RootParameterType::SRV):
     case llvm::to_underlying(dxbc::RootParameterType::UAV):
@@ -167,7 +169,7 @@ static RootSignatureBindingValidation initRsBindingValdation(const mcdxbc::RootS
       Binding.LowerBound = Desc.ShaderRegister;
       Binding.Space = Desc.RegisterSpace;
       Binding.Size = 1;
-  
+
       Validation.addBinding(parameterToRangeType(Type), Binding);
       break;
     }
@@ -176,11 +178,11 @@ static RootSignatureBindingValidation initRsBindingValdation(const mcdxbc::RootS
           RSD.ParametersContainer.getDescriptorTable(Loc);
 
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-          llvm::dxil::ResourceInfo::ResourceBinding Binding;
-          Binding.LowerBound = Range.BaseShaderRegister;
-          Binding.Space = Range.RegisterSpace;
-          Binding.Size = Range.NumDescriptors;
-          Validation.addBinding(Range.RangeType, Binding);
+        llvm::dxil::ResourceInfo::ResourceBinding Binding;
+        Binding.LowerBound = Range.BaseShaderRegister;
+        Binding.Space = Range.RegisterSpace;
+        Binding.Size = Range.NumDescriptors;
+        Validation.addBinding(Range.RangeType, Binding);
       }
       break;
     }
@@ -238,17 +240,23 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   if (auto RSD = getRootSignature(RSBI, MMI)) {
 
-    RootSignatureBindingValidation Validation = initRsBindingValdation(*RSD, tripleToVisibility(MMI.ShaderProfile));
+    RootSignatureBindingValidation Validation =
+        initRsBindingValdation(*RSD, tripleToVisibility(MMI.ShaderProfile));
 
     auto Cbufs = DRM.cbuffers();
     auto SRVs = DRM.srvs();
     auto UAVs = DRM.uavs();
     auto Samplers = DRM.samplers();
 
-    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV), Cbufs);
-    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV), UAVs);
-    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler), Samplers);
-    reportUnboundRegisters(M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV), SRVs);
+    reportUnboundRegisters(
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV), Cbufs);
+    reportUnboundRegisters(
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV), UAVs);
+    reportUnboundRegisters(
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler),
+        Samplers);
+    reportUnboundRegisters(
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV), SRVs);
   }
 }
 } // namespace
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 9a6fe258b02c7..f0e4c4d9d7164 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -26,44 +26,46 @@ namespace llvm {
 
 class RootSignatureBindingValidation {
 private:
-    llvm::SmallVector<dxil::ResourceInfo::ResourceBinding, 16> Bindings;    
-    struct TypeRange {
-        uint32_t Start;
-        uint32_t End; 
-    };
-    std::unordered_map<uint32_t, TypeRange> Ranges;
+  llvm::SmallVector<dxil::ResourceInfo::ResourceBinding, 16> Bindings;
+  struct TypeRange {
+    uint32_t Start;
+    uint32_t End;
+  };
+  std::unordered_map<uint32_t, TypeRange> Ranges;
 
 public:
-    void addBinding(const uint32_t& Type, const dxil::ResourceInfo::ResourceBinding& Binding) {
-        auto It = Ranges.find(Type);
-        
-        if (It == Ranges.end()) {
-            uint32_t InsertPos = Bindings.size();
-            Bindings.push_back(Binding);
-            Ranges[Type] = {InsertPos, InsertPos + 1};
-        } else {
-            uint32_t InsertPos = It->second.End;
-            Bindings.insert(Bindings.begin() + InsertPos, Binding);
-            
-            It->second.End++;
-            
-            for (auto& [type, range] : Ranges) {
-                if (range.Start > InsertPos) {
-                    range.Start++;
-                    range.End++;
-                }
-            }
+  void addBinding(const uint32_t &Type,
+                  const dxil::ResourceInfo::ResourceBinding &Binding) {
+    auto It = Ranges.find(Type);
+
+    if (It == Ranges.end()) {
+      uint32_t InsertPos = Bindings.size();
+      Bindings.push_back(Binding);
+      Ranges[Type] = {InsertPos, InsertPos + 1};
+    } else {
+      uint32_t InsertPos = It->second.End;
+      Bindings.insert(Bindings.begin() + InsertPos, Binding);
+
+      It->second.End++;
+
+      for (auto &[type, range] : Ranges) {
+        if (range.Start > InsertPos) {
+          range.Start++;
+          range.End++;
         }
+      }
     }
-    
-    llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding> getBindingsOfType(const dxbc::DescriptorRangeType& Type) const {
-        auto It = Ranges.find(llvm::to_underlying(Type));
-        if (It == Ranges.end()) {
-            return {};
-        }
-        return llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>(Bindings.data() + It->second.Start, 
-                                               It->second.End - It->second.Start);
+  }
+
+  llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>
+  getBindingsOfType(const dxbc::DescriptorRangeType &Type) const {
+    auto It = Ranges.find(llvm::to_underlying(Type));
+    if (It == Ranges.end()) {
+      return {};
     }
+    return llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>(
+        Bindings.data() + It->second.Start, It->second.End - It->second.Start);
+  }
 };
 
 class DXILPostOptimizationValidation

>From a7637a7848b6a3bfd60ab366568f6f708878287e Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 14 Jul 2025 19:31:23 +0000
Subject: [PATCH 26/68] adding tests

---
 .../DXILPostOptimizationValidation.cpp        |   7 -
 ... rootsignature-validation-fail-cbuffer.ll} |   9 ++
 .../rootsignature-validation-fail-sampler.ll  |  31 ++++
 .../rootsignature-validation-fail-srv.ll      |  30 ++++
 .../rootsignature-validation-fail-uav.ll      |  30 ++++
 .../DirectX/rootsignature-validation.ll       | 148 +++---------------
 6 files changed, 119 insertions(+), 136 deletions(-)
 rename llvm/test/CodeGen/DirectX/{rootsignature-validation-fail.ll => rootsignature-validation-fail-cbuffer.ll} (70%)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 035a5bd225ac8..f9218d571365c 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -7,15 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "DXILPostOptimizationValidation.h"
-#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
-#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/iterator_range.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
@@ -130,13 +126,10 @@ static uint32_t parameterToRangeType(uint32_t Type) {
   switch (Type) {
   case llvm::to_underlying(dxbc::RootParameterType::CBV):
     return llvm::to_underlying(dxbc::DescriptorRangeType::CBV);
-    break;
   case llvm::to_underlying(dxbc::RootParameterType::SRV):
     return llvm::to_underlying(dxbc::DescriptorRangeType::SRV);
-    break;
   case llvm::to_underlying(dxbc::RootParameterType::UAV):
     return llvm::to_underlying(dxbc::DescriptorRangeType::UAV);
-    break;
   default:
     llvm_unreachable("Root Parameter Type has no Range Type equivalent");
   }
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
similarity index 70%
rename from llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
rename to llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
index e52647fe888b1..cd8a87d04f31a 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
@@ -2,12 +2,21 @@
 
 ; CHECK: error: register CB (space=665, register=3) is not defined in Root Signature
 
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
 %__cblayout_CB = type <{ float }>
 
 @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
+; cbuffer CB : register(b3, space665) {
+;  float a;
+; }
   %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
   ret void
 }
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
new file mode 100644
index 0000000000000..8e7e0de96ccff
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -0,0 +1,31 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register Smp (space=2, register=3) is not defined in Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; SamplerState S1 : register(s3, space2);
+  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
+
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
new file mode 100644
index 0000000000000..166ac51a7d0de
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
@@ -0,0 +1,30 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register SB (space=0, register=0) is not defined in Root Signature 
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; StructuredBuffer<int> In : register(t0, space0);
+  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
new file mode 100644
index 0000000000000..8a1daea8f7d24
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
@@ -0,0 +1,30 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register RWB (space=0, register=4294967295) is not defined in Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; RWBuffer<float> UAV : register(u4294967295);
+  %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
index eaf8512c284a7..750679bf743c5 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -1,149 +1,39 @@
 ; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
 ; expected-no-diagnostics
 
-;
-; Resource Bindings:
-;
-; Name                                 Type  Format         Dim      ID      HLSL Bind     Count
-; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
-; In                                texture  struct         r/o      T0             t0         1
-; Out                                   UAV  struct         r/w      U0             u0         1
-; UAV3                                  UAV  struct         r/w      U1             u1         1
-; UAV1                                  UAV  struct         r/w      U2             u2         1
-; UAV                                   UAV  struct         r/w      U3    u4294967294         1
-; CB                                cbuffer      NA          NA     CB0     cb3,space1         1
-;
-; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation.hlsl'
-target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
-target triple = "dxilv1.5-unknown-shadermodel6.5-compute"
+
+; Root Signature(
+;   CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
 
 %__cblayout_CB = type <{ float }>
-%"StructuredBuffer<int32_t>" = type { i32 }
-%"RWStructuredBuffer<int32_t>" = type { i32 }
-%"RWStructuredBuffer<float>" = type { float }
-%CBuffer.CB = type { float }
 
- at CB.cb = local_unnamed_addr global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) poison
 @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
- at .str = private unnamed_addr constant [3 x i8] c"In\00", align 1
- at .str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
- at .str.4 = private unnamed_addr constant [4 x i8] c"UAV\00", align 1
- at .str.6 = private unnamed_addr constant [5 x i8] c"UAV1\00", align 1
- at .str.10 = private unnamed_addr constant [5 x i8] c"UAV3\00", align 1
- at In = external constant %"StructuredBuffer<int32_t>"
- at Out = external constant %"RWStructuredBuffer<int32_t>"
- at UAV3 = external constant %"RWStructuredBuffer<float>"
- at UAV1 = external constant %"RWStructuredBuffer<float>"
- at UAV = external constant %"RWStructuredBuffer<float>"
- at CB = external constant %CBuffer.CB
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32, i32, i32, i32, i1, ptr) #0
+ at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
+ at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
+ at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
 
-; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
-define void @CSMain() local_unnamed_addr #1 {
+define void @CSMain() "hlsl.shader"="compute" {
 entry:
-  %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4
-  %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str)
-  %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2)
-  %2 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 -2, i32 1, i32 0, i1 false, ptr nonnull @.str.4)
-  %3 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6)
-  %4 = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10)
-  %5 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0)
-  %6 = extractvalue { float, float, float, float } %5, 0
-  %7 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0)
-  %8 = extractvalue { i32, i1 } %7, 0
-  %conv.i = sitofp i32 %8 to float
-  %add.i = fadd reassoc nnan ninf nsz arcp afn float %6, %conv.i
-  %9 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %2, i32 0, i32 0)
-  %10 = extractvalue { float, i1 } %9, 0
-  %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %10
-  %11 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %3, i32 0, i32 0)
-  %12 = extractvalue { float, i1 } %11, 0
-  %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %12
-  %13 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %4, i32 0, i32 0)
-  %14 = extractvalue { float, i1 } %13, 0
-  %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %14
-  %conv7.i = fptosi float %add6.i to i32
-  call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv7.i)
-  ret void
-}
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32, i32, i32, i32, i1, ptr) #0
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #0
 
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32) #0
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
+  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
+  %RWB =  tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
 
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) #0
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0), i32, i32) #2
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32, i32) #2
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
-declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #3
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
-declare { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)), i32) #2
-
-; uselistorder directives
-uselistorder ptr @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 }
-uselistorder ptr @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t, { 2, 1, 0 }
-
-attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="false" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) }
-attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) }
+  ret void
+}
 
 !dx.rootsignatures = !{!0}
-!llvm.module.flags = !{!9, !10}
-!dx.valver = !{!11}
-!llvm.ident = !{!12}
-!dx.shaderModel = !{!13}
-!dx.version = !{!14}
-!dx.resources = !{!15}
-!dx.entryPoints = !{!26}
 
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3, !5, !7}
 !2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4}
 !3 = !{!"DescriptorTable", i32 0, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 1, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 5, i32 3, i32 2, i32 -1, i32 0}
 !7 = !{!"DescriptorTable", i32 0, !8}
 !8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
-!9 = !{i32 1, !"wchar_size", i32 4}
-!10 = !{i32 7, !"frame-pointer", i32 2}
-!11 = !{i32 1, i32 8}
-!12 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"}
-!13 = !{!"cs", i32 6, i32 5}
-!14 = !{i32 1, i32 5}
-!15 = !{!16, !19, !24, null}
-!16 = !{!17}
-!17 = !{i32 0, ptr @In, !"In", i32 0, i32 0, i32 1, i32 12, i32 0, !18}
-!18 = !{i32 1, i32 4}
-!19 = !{!20, !21, !22, !23}
-!20 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
-!21 = !{i32 1, ptr @UAV3, !"UAV3", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
-!22 = !{i32 2, ptr @UAV1, !"UAV1", i32 0, i32 2, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
-!23 = !{i32 3, ptr @UAV, !"UAV", i32 0, i32 -2, i32 1, i32 12, i1 false, i1 false, i1 false, !18}
-!24 = !{!25}
-!25 = !{i32 0, ptr @CB, !"CB", i32 1, i32 3, i32 1, i32 4, null}
-!26 = !{ptr @CSMain, !"CSMain", null, !15, !27}
-!27 = !{i32 0, i64 16, i32 4, !28}
-!28 = !{i32 8, i32 8, i32 1}

>From da42c0c2f6af1ee68f85779fe307bda2a7af597f Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 14 Jul 2025 20:30:37 +0000
Subject: [PATCH 27/68] clean up

---
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index f0e4c4d9d7164..cabf3d95e66e9 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -20,7 +20,6 @@
 #include "llvm/Analysis/DXILResource.h"
 #include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/PassManager.h"
-#include <cstdint>
 
 namespace llvm {
 

>From edb015dcae3bfb5d3168321b288d0b8cd1451ff9 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 15 Jul 2025 00:37:40 +0000
Subject: [PATCH 28/68] address comments

---
 .../DXILPostOptimizationValidation.cpp        | 32 ++++++++++---------
 .../DirectX/DXILPostOptimizationValidation.h  |  8 ++---
 2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index f9218d571365c..c01f52e07d230 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -10,6 +10,7 @@
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
 #include "llvm/IR/DiagnosticInfo.h"
@@ -136,8 +137,8 @@ static uint32_t parameterToRangeType(uint32_t Type) {
 }
 
 static RootSignatureBindingValidation
-initRsBindingValdation(const mcdxbc::RootSignatureDesc &RSD,
-                       dxbc::ShaderVisibility Visibility) {
+initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
+                        dxbc::ShaderVisibility Visibility) {
 
   RootSignatureBindingValidation Validation;
 
@@ -199,15 +200,17 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
 
 static void reportUnboundRegisters(
     Module &M,
-    const std::vector<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
-    iterator_range<SmallVector<dxil::ResourceInfo>::iterator> &Resources) {
+    const llvm::ArrayRef<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
+    const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
+        &Resources) {
   for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) {
     bool Bound = false;
     ResourceInfo::ResourceBinding ResBinding = Res->getBinding();
     for (const auto &Binding : Bindings) {
       if (ResBinding.Space == Binding.Space &&
           ResBinding.LowerBound >= Binding.LowerBound &&
-          ResBinding.LowerBound < Binding.LowerBound + Binding.Size) {
+          ResBinding.LowerBound + ResBinding.Size - 1 <
+              Binding.LowerBound + Binding.Size) {
         Bound = true;
         break;
       }
@@ -234,22 +237,20 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
   if (auto RSD = getRootSignature(RSBI, MMI)) {
 
     RootSignatureBindingValidation Validation =
-        initRsBindingValdation(*RSD, tripleToVisibility(MMI.ShaderProfile));
-
-    auto Cbufs = DRM.cbuffers();
-    auto SRVs = DRM.srvs();
-    auto UAVs = DRM.uavs();
-    auto Samplers = DRM.samplers();
+        initRSBindingValidation(*RSD, tripleToVisibility(MMI.ShaderProfile));
 
     reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV), Cbufs);
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV),
+        DRM.cbuffers());
     reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV), UAVs);
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV),
+        DRM.uavs());
     reportUnboundRegisters(
         M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler),
-        Samplers);
+        DRM.samplers());
     reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV), SRVs);
+        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV),
+        DRM.srvs());
   }
 }
 } // namespace
@@ -307,6 +308,7 @@ INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
 INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
 INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
                     "DXIL Post Optimization Validation", false, false)
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index cabf3d95e66e9..789bbe4573964 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -47,10 +47,10 @@ class RootSignatureBindingValidation {
 
       It->second.End++;
 
-      for (auto &[type, range] : Ranges) {
-        if (range.Start > InsertPos) {
-          range.Start++;
-          range.End++;
+      for (auto &[Type, Range] : Ranges) {
+        if (Range.Start > InsertPos) {
+          Range.Start++;
+          Range.End++;
         }
       }
     }

>From 9f3888ead4ed2934400cbf4ef3b92bdccc56645b Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 15 Jul 2025 18:17:45 +0000
Subject: [PATCH 29/68] adding root constants

---
 .../DXILPostOptimizationValidation.cpp        | 18 +++++++++++++++
 .../rootsignature-validation-constants.ll     | 22 +++++++++++++++++++
 ...rootsignature-validation-fail-constants.ll | 22 +++++++++++++++++++
 3 files changed, 62 insertions(+)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index c01f52e07d230..eb3ad6a6e56ee 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -9,10 +9,12 @@
 #include "DXILPostOptimizationValidation.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
@@ -153,6 +155,22 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
       continue;
 
     switch (Type) {
+    case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
+      dxbc::RTS0::v1::RootConstants Const =
+          RSD.ParametersContainer.getConstant(Loc);
+
+      llvm::dxil::ResourceInfo::ResourceBinding Binding;
+      Binding.LowerBound = Const.ShaderRegister;
+      Binding.Space = Const.RegisterSpace;
+      Binding.Size = 1;
+
+      // Root Constants Bind to CBuffers
+      Validation.addBinding(llvm::to_underlying(dxbc::DescriptorRangeType::CBV),
+                            Binding);
+
+      break;
+    }
+
     case llvm::to_underlying(dxbc::RootParameterType::SRV):
     case llvm::to_underlying(dxbc::RootParameterType::UAV):
     case llvm::to_underlying(dxbc::RootParameterType::CBV): {
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
new file mode 100644
index 0000000000000..3c33f1dc6bdf0
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
@@ -0,0 +1,22 @@
+; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; expected-no-diagnostics
+; Root Signature(RootConstants(num32BitConstants=4, b2))
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; cbuffer CB : register(b2, space0) {
+;  float a;
+; }
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2}
+!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
new file mode 100644
index 0000000000000..b7e1172c7304a
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
@@ -0,0 +1,22 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register CB (space=666, register=2) is not defined in Root Signature
+; Root Signature(RootConstants(num32BitConstants=4, b2))
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; cbuffer CB : register(b2, space666) {
+;  float a;
+; }
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 666, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2}
+!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}

>From 578a03bd33359497d0aa4820f2ceacad0b5c24e2 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 15 Jul 2025 21:28:24 +0000
Subject: [PATCH 30/68] clean

---
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 97cbb76da2a55..b6e8ce7d78b23 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -62,10 +62,10 @@ class DXContainerGlobals : public llvm::ModulePass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
     AU.addRequired<ShaderFlagsAnalysisWrapper>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
     AU.addRequired<DXILResourceTypeWrapperPass>();
     AU.addRequired<DXILResourceWrapperPass>();
-    AU.addRequired<RootSignatureAnalysisWrapper>();
   }
 };
 

>From b4a0e16bf068d35d563c5fc02bbe7f9875528b92 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 17 Jul 2025 00:10:17 +0000
Subject: [PATCH 31/68] moving code arround

---
 .../Frontend/HLSL/RootSignatureValidations.h  |  46 ++++++
 .../llvm/MC/DXContainerRootSignature.h        |   3 +
 .../HLSL/RootSignatureValidations.cpp         |  26 ++++
 .../DXILPostOptimizationValidation.cpp        | 140 +++++++++++-------
 .../DirectX/DXILPostOptimizationValidation.h  |  50 -------
 .../rootsignature-validation-fail-cbuffer.ll  |   2 +-
 ...rootsignature-validation-fail-constants.ll |   2 +-
 .../rootsignature-validation-fail-sampler.ll  |   2 +-
 .../rootsignature-validation-fail-srv.ll      |   2 +-
 .../rootsignature-validation-fail-uav.ll      |   2 +-
 10 files changed, 164 insertions(+), 111 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index ea63a253b6661..e298cb4250db9 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/Frontend/HLSL/HLSLRootSignature.h"
+#include "llvm/Support/DXILABI.h"
 
 namespace llvm {
 namespace hlsl {
@@ -136,6 +137,51 @@ struct OverlappingRanges {
 llvm::SmallVector<OverlappingRanges>
 findOverlappingRanges(llvm::SmallVector<RangeInfo> &Infos);
 
+class RootSignatureBindingValidation {
+private:
+  llvm::SmallVector<RangeInfo, 16> Bindings;
+  struct TypeRange {
+    uint32_t Start;
+    uint32_t End;
+  };
+  std::unordered_map<dxil::ResourceClass, TypeRange> Ranges;
+
+public:
+  void addBinding(dxil::ResourceClass Type, const RangeInfo &Binding) {
+    auto It = Ranges.find(Type);
+
+    if (It == Ranges.end()) {
+      uint32_t InsertPos = Bindings.size();
+      Bindings.push_back(Binding);
+      Ranges[Type] = {InsertPos, InsertPos + 1};
+    } else {
+      uint32_t InsertPos = It->second.End;
+      Bindings.insert(Bindings.begin() + InsertPos, Binding);
+
+      It->second.End++;
+
+      for (auto &[Type, Range] : Ranges) {
+        if (Range.Start > InsertPos) {
+          Range.Start++;
+          Range.End++;
+        }
+      }
+    }
+  }
+
+  llvm::ArrayRef<RangeInfo>
+  getBindingsOfType(const dxil::ResourceClass &Type) const {
+    auto It = Ranges.find(Type);
+    if (It == Ranges.end()) {
+      return {};
+    }
+    return llvm::ArrayRef<RangeInfo>(Bindings.data() + It->second.Start,
+                                     It->second.End - It->second.Start);
+  }
+};
+llvm::SmallVector<RangeInfo>
+findUnboundRanges(const llvm::SmallVectorImpl<RangeInfo> &Ranges,
+                  const llvm::ArrayRef<RangeInfo> &Bindings);
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 4b6b42f7d74f7..eb4524d547892 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -5,6 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_DXCONTAINERROOTSIGNATURE_H
+#define LLVM_MC_DXCONTAINERROOTSIGNATURE_H
 
 #include "llvm/BinaryFormat/DXContainer.h"
 #include <cstdint>
@@ -116,3 +118,4 @@ struct RootSignatureDesc {
 };
 } // namespace mcdxbc
 } // namespace llvm
+#endif // LLVM_MC_DXCONTAINERROOTSIGNATURE_H
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 278c42e97667b..77492eaf13aee 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -316,6 +316,32 @@ findOverlappingRanges(llvm::SmallVector<RangeInfo> &Infos) {
   return Overlaps;
 }
 
+llvm::SmallVector<RangeInfo>
+findUnboundRanges(const llvm::SmallVectorImpl<RangeInfo> &Ranges,
+                  const llvm::ArrayRef<RangeInfo> &Bindings) {
+  llvm::SmallVector<RangeInfo> Unbounds;
+  for (const auto &Range : Ranges) {
+    bool Bound = false;
+    // hlsl::rootsig::RangeInfo Range;
+    // Range.Space = ResBinding.Space;
+    // Range.LowerBound = ResBinding.LowerBound;
+    // Range.UpperBound = Range.LowerBound + ResBinding.Size - 1;
+
+    for (const auto &Binding : Bindings) {
+      if (Range.Space == Binding.Space &&
+          Range.LowerBound >= Binding.LowerBound &&
+          Range.UpperBound <= Binding.UpperBound) {
+        Bound = true;
+        break;
+      }
+    }
+    if (!Bound) {
+      Unbounds.push_back(Range);
+    }
+  }
+  return Unbounds;
+}
+
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index eb3ad6a6e56ee..9b89646050e17 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "DXILPostOptimizationValidation.h"
+#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/STLForwardCompat.h"
@@ -15,11 +16,14 @@
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
 #include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Frontend/HLSL/RootSignatureValidations.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/MC/DXContainerRootSignature.h"
+#include "llvm/Support/DXILABI.h"
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 
@@ -27,6 +31,48 @@ using namespace llvm;
 using namespace llvm::dxil;
 
 namespace {
+static const char *ResourceClassToString(llvm::dxil::ResourceClass Class) {
+  switch (Class) {
+  case ResourceClass::SRV:
+    return "SRV";
+  case ResourceClass::UAV:
+    return "UAV";
+  case ResourceClass::CBuffer:
+    return "CBuffer";
+  case ResourceClass::Sampler:
+    return "Sampler";
+  }
+}
+
+static ResourceClass RangeToResourceClass(uint32_t RangeType) {
+  using namespace dxbc;
+  switch (static_cast<DescriptorRangeType>(RangeType)) {
+  case DescriptorRangeType::SRV:
+    return ResourceClass::SRV;
+  case DescriptorRangeType::UAV:
+    return ResourceClass::UAV;
+  case DescriptorRangeType::CBV:
+    return ResourceClass::CBuffer;
+  case DescriptorRangeType::Sampler:
+    return ResourceClass::Sampler;
+  }
+}
+
+ResourceClass ParameterToResourceClass(uint32_t Type) {
+  using namespace dxbc;
+  switch (Type) {
+  case llvm::to_underlying(RootParameterType::Constants32Bit):
+    return ResourceClass::CBuffer;
+  case llvm::to_underlying(RootParameterType::SRV):
+    return ResourceClass::SRV;
+  case llvm::to_underlying(RootParameterType::UAV):
+    return ResourceClass::UAV;
+  case llvm::to_underlying(RootParameterType::CBV):
+    return ResourceClass::CBuffer;
+  default:
+    llvm_unreachable("Unknown RootParameterType");
+  }
+}
 
 static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
   for (const auto &UAV : DRM.uavs()) {
@@ -87,12 +133,13 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
-static void reportRegNotBound(Module &M, Twine Type,
-                              ResourceInfo::ResourceBinding Binding) {
+static void reportRegNotBound(Module &M,
+                              llvm::hlsl::rootsig::RangeInfo Unbound) {
   SmallString<128> Message;
   raw_svector_ostream OS(Message);
-  OS << "register " << Type << " (space=" << Binding.Space
-     << ", register=" << Binding.LowerBound << ")"
+  OS << "register " << ResourceClassToString(Unbound.Class)
+     << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
+     << ")"
      << " is not defined in Root Signature";
   M.getContext().diagnose(DiagnosticInfoGeneric(Message));
 }
@@ -125,24 +172,11 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
-static uint32_t parameterToRangeType(uint32_t Type) {
-  switch (Type) {
-  case llvm::to_underlying(dxbc::RootParameterType::CBV):
-    return llvm::to_underlying(dxbc::DescriptorRangeType::CBV);
-  case llvm::to_underlying(dxbc::RootParameterType::SRV):
-    return llvm::to_underlying(dxbc::DescriptorRangeType::SRV);
-  case llvm::to_underlying(dxbc::RootParameterType::UAV):
-    return llvm::to_underlying(dxbc::DescriptorRangeType::UAV);
-  default:
-    llvm_unreachable("Root Parameter Type has no Range Type equivalent");
-  }
-}
-
-static RootSignatureBindingValidation
+static hlsl::rootsig::RootSignatureBindingValidation
 initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
                         dxbc::ShaderVisibility Visibility) {
 
-  RootSignatureBindingValidation Validation;
+  hlsl::rootsig::RootSignatureBindingValidation Validation;
 
   for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
     const auto &[Type, Loc] =
@@ -159,14 +193,13 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
       dxbc::RTS0::v1::RootConstants Const =
           RSD.ParametersContainer.getConstant(Loc);
 
-      llvm::dxil::ResourceInfo::ResourceBinding Binding;
+      hlsl::rootsig::RangeInfo Binding;
       Binding.LowerBound = Const.ShaderRegister;
       Binding.Space = Const.RegisterSpace;
-      Binding.Size = 1;
+      Binding.UpperBound = Binding.LowerBound;
 
       // Root Constants Bind to CBuffers
-      Validation.addBinding(llvm::to_underlying(dxbc::DescriptorRangeType::CBV),
-                            Binding);
+      Validation.addBinding(ResourceClass::CBuffer, Binding);
 
       break;
     }
@@ -177,12 +210,12 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
       dxbc::RTS0::v2::RootDescriptor Desc =
           RSD.ParametersContainer.getRootDescriptor(Loc);
 
-      llvm::dxil::ResourceInfo::ResourceBinding Binding;
+      hlsl::rootsig::RangeInfo Binding;
       Binding.LowerBound = Desc.ShaderRegister;
       Binding.Space = Desc.RegisterSpace;
-      Binding.Size = 1;
+      Binding.UpperBound = Binding.LowerBound;
 
-      Validation.addBinding(parameterToRangeType(Type), Binding);
+      Validation.addBinding(ParameterToResourceClass(Type), Binding);
       break;
     }
     case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
@@ -190,11 +223,11 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
           RSD.ParametersContainer.getDescriptorTable(Loc);
 
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-        llvm::dxil::ResourceInfo::ResourceBinding Binding;
+        hlsl::rootsig::RangeInfo Binding;
         Binding.LowerBound = Range.BaseShaderRegister;
         Binding.Space = Range.RegisterSpace;
-        Binding.Size = Range.NumDescriptors;
-        Validation.addBinding(Range.RangeType, Binding);
+        Binding.UpperBound = Binding.LowerBound + Range.NumDescriptors - 1;
+        Validation.addBinding(RangeToResourceClass(Range.RangeType), Binding);
       }
       break;
     }
@@ -218,25 +251,26 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
 
 static void reportUnboundRegisters(
     Module &M,
-    const llvm::ArrayRef<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
+    const llvm::hlsl::rootsig::RootSignatureBindingValidation &Validation,
+    ResourceClass Class,
     const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
         &Resources) {
+  SmallVector<hlsl::rootsig::RangeInfo> Ranges;
   for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) {
-    bool Bound = false;
     ResourceInfo::ResourceBinding ResBinding = Res->getBinding();
-    for (const auto &Binding : Bindings) {
-      if (ResBinding.Space == Binding.Space &&
-          ResBinding.LowerBound >= Binding.LowerBound &&
-          ResBinding.LowerBound + ResBinding.Size - 1 <
-              Binding.LowerBound + Binding.Size) {
-        Bound = true;
-        break;
-      }
-    }
-    if (!Bound) {
-      reportRegNotBound(M, Res->getName(), Res->getBinding());
-    }
+    hlsl::rootsig::RangeInfo Range;
+    Range.Space = ResBinding.Space;
+    Range.LowerBound = ResBinding.LowerBound;
+    Range.UpperBound = Range.LowerBound + ResBinding.Size - 1;
+    Range.Class = Class;
+    Ranges.push_back(Range);
   }
+
+  SmallVector<hlsl::rootsig::RangeInfo> Unbounds =
+      hlsl::rootsig::findUnboundRanges(Ranges,
+                                       Validation.getBindingsOfType(Class));
+  for (const auto &Unbound : Unbounds)
+    reportRegNotBound(M, Unbound);
 }
 
 static void reportErrors(Module &M, DXILResourceMap &DRM,
@@ -254,21 +288,15 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   if (auto RSD = getRootSignature(RSBI, MMI)) {
 
-    RootSignatureBindingValidation Validation =
+    llvm::hlsl::rootsig::RootSignatureBindingValidation Validation =
         initRSBindingValidation(*RSD, tripleToVisibility(MMI.ShaderProfile));
 
-    reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV),
-        DRM.cbuffers());
-    reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV),
-        DRM.uavs());
-    reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler),
-        DRM.samplers());
-    reportUnboundRegisters(
-        M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV),
-        DRM.srvs());
+    reportUnboundRegisters(M, Validation, ResourceClass::CBuffer,
+                           DRM.cbuffers());
+    reportUnboundRegisters(M, Validation, ResourceClass::UAV, DRM.uavs());
+    reportUnboundRegisters(M, Validation, ResourceClass::Sampler,
+                           DRM.samplers());
+    reportUnboundRegisters(M, Validation, ResourceClass::SRV, DRM.srvs());
   }
 }
 } // namespace
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 789bbe4573964..2535c6979c5d5 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -14,59 +14,9 @@
 #ifndef LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
 #define LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
 
-#include "DXILRootSignature.h"
-#include "llvm/ADT/STLForwardCompat.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/PassManager.h"
 
 namespace llvm {
-
-class RootSignatureBindingValidation {
-private:
-  llvm::SmallVector<dxil::ResourceInfo::ResourceBinding, 16> Bindings;
-  struct TypeRange {
-    uint32_t Start;
-    uint32_t End;
-  };
-  std::unordered_map<uint32_t, TypeRange> Ranges;
-
-public:
-  void addBinding(const uint32_t &Type,
-                  const dxil::ResourceInfo::ResourceBinding &Binding) {
-    auto It = Ranges.find(Type);
-
-    if (It == Ranges.end()) {
-      uint32_t InsertPos = Bindings.size();
-      Bindings.push_back(Binding);
-      Ranges[Type] = {InsertPos, InsertPos + 1};
-    } else {
-      uint32_t InsertPos = It->second.End;
-      Bindings.insert(Bindings.begin() + InsertPos, Binding);
-
-      It->second.End++;
-
-      for (auto &[Type, Range] : Ranges) {
-        if (Range.Start > InsertPos) {
-          Range.Start++;
-          Range.End++;
-        }
-      }
-    }
-  }
-
-  llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>
-  getBindingsOfType(const dxbc::DescriptorRangeType &Type) const {
-    auto It = Ranges.find(llvm::to_underlying(Type));
-    if (It == Ranges.end()) {
-      return {};
-    }
-    return llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding>(
-        Bindings.data() + It->second.Start, It->second.End - It->second.Start);
-  }
-};
-
 class DXILPostOptimizationValidation
     : public PassInfoMixin<DXILPostOptimizationValidation> {
 public:
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
index cd8a87d04f31a..ac97d79c6a2eb 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register CB (space=665, register=3) is not defined in Root Signature
+; CHECK: error: register CBuffer (space=665, register=3) is not defined in Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
index b7e1172c7304a..fadc0db046ec7 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CB (space=666, register=2) is not defined in Root Signature
+; CHECK: error: register CBuffer (space=666, register=2) is not defined in Root Signature
 ; Root Signature(RootConstants(num32BitConstants=4, b2))
 
 %__cblayout_CB = type <{ float }>
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index 8e7e0de96ccff..2ec3505cbec41 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register Smp (space=2, register=3) is not defined in Root Signature
+; CHECK: error: register Sampler (space=2, register=3) is not defined in Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
index 166ac51a7d0de..32098a45ce97c 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register SB (space=0, register=0) is not defined in Root Signature 
+; CHECK: error: register SRV (space=0, register=0) is not defined in Root Signature 
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
index 8a1daea8f7d24..2bc54f811d62e 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register RWB (space=0, register=4294967295) is not defined in Root Signature
+; CHECK: error: register UAV (space=0, register=4294967295) is not defined in Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)

>From ef1463806a4d965d38c2b41e3b626644dda75b10 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 17 Jul 2025 00:34:12 +0000
Subject: [PATCH 32/68] clean

---
 llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h | 1 -
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 5 -----
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h   | 1 +
 3 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index e298cb4250db9..b334bf0996ae9 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -16,7 +16,6 @@
 
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/Frontend/HLSL/HLSLRootSignature.h"
-#include "llvm/Support/DXILABI.h"
 
 namespace llvm {
 namespace hlsl {
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 9b89646050e17..3a6ccf9145d5a 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -10,20 +10,15 @@
 #include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
-#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Frontend/HLSL/RootSignatureValidations.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
-#include "llvm/MC/DXContainerRootSignature.h"
-#include "llvm/Support/DXILABI.h"
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
index 2535c6979c5d5..cb5e624514272 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.h
@@ -17,6 +17,7 @@
 #include "llvm/IR/PassManager.h"
 
 namespace llvm {
+
 class DXILPostOptimizationValidation
     : public PassInfoMixin<DXILPostOptimizationValidation> {
 public:

>From 662c3a84f05f2bd78be2ab6f78fbd63678d90fa6 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Mon, 21 Jul 2025 22:24:26 +0000
Subject: [PATCH 33/68] addressing comments

---
 llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h      | 2 +-
 llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp             | 2 +-
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp      | 2 +-
 .../CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll    | 2 +-
 .../CodeGen/DirectX/rootsignature-validation-fail-constants.ll  | 2 +-
 .../CodeGen/DirectX/rootsignature-validation-fail-sampler.ll    | 2 +-
 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll  | 2 +-
 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll  | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index b334bf0996ae9..4bc7771a0f83d 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -179,7 +179,7 @@ class RootSignatureBindingValidation {
   }
 };
 llvm::SmallVector<RangeInfo>
-findUnboundRanges(const llvm::SmallVectorImpl<RangeInfo> &Ranges,
+findUnboundRanges(const llvm::ArrayRef<RangeInfo> &Ranges,
                   const llvm::ArrayRef<RangeInfo> &Bindings);
 } // namespace rootsig
 } // namespace hlsl
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 77492eaf13aee..b7204a4bf82a3 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -317,7 +317,7 @@ findOverlappingRanges(llvm::SmallVector<RangeInfo> &Infos) {
 }
 
 llvm::SmallVector<RangeInfo>
-findUnboundRanges(const llvm::SmallVectorImpl<RangeInfo> &Ranges,
+findUnboundRanges(const llvm::ArrayRef<RangeInfo> &Ranges,
                   const llvm::ArrayRef<RangeInfo> &Bindings) {
   llvm::SmallVector<RangeInfo> Unbounds;
   for (const auto &Range : Ranges) {
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 3a6ccf9145d5a..ba357f95ea8d8 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -135,7 +135,7 @@ static void reportRegNotBound(Module &M,
   OS << "register " << ResourceClassToString(Unbound.Class)
      << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
      << ")"
-     << " is not defined in Root Signature";
+     << " does not have a binding in the Root Signature";
   M.getContext().diagnose(DiagnosticInfoGeneric(Message));
 }
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
index ac97d79c6a2eb..e5133810c0f32 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register CBuffer (space=665, register=3) is not defined in Root Signature
+; CHECK: error: register CBuffer (space=665, register=3) does not have a binding in the Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
index fadc0db046ec7..dc7657e79ec97 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CBuffer (space=666, register=2) is not defined in Root Signature
+; CHECK: error: register CBuffer (space=666, register=2) does not have a binding in the Root Signature
 ; Root Signature(RootConstants(num32BitConstants=4, b2))
 
 %__cblayout_CB = type <{ float }>
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index 2ec3505cbec41..152c363fdf75b 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register Sampler (space=2, register=3) is not defined in Root Signature
+; CHECK: error: register Sampler (space=2, register=3) does not have a binding in the Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
index 32098a45ce97c..ebefa7b1a3d85 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register SRV (space=0, register=0) is not defined in Root Signature 
+; CHECK: error: register SRV (space=0, register=0) does not have a binding in the Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
index 2bc54f811d62e..1bd0f6da62478 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register UAV (space=0, register=4294967295) is not defined in Root Signature
+; CHECK: error: register UAV (space=0, register=4294967295) does not have a binding in the Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)

>From 260633c526c0c405a4df012c7f785adbff4f4271 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Fri, 25 Jul 2025 13:22:44 -0700
Subject: [PATCH 34/68] address comments

---
 llvm/include/llvm/Analysis/DXILResource.h     | 14 +++++++++++++
 .../Frontend/HLSL/RootSignatureValidations.h  | 21 +++++++++----------
 llvm/lib/Analysis/DXILResource.cpp            | 14 -------------
 .../HLSL/RootSignatureValidations.cpp         |  3 +--
 .../DXILPostOptimizationValidation.cpp        | 16 ++------------
 5 files changed, 27 insertions(+), 41 deletions(-)

diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 9e2dc1ad771cf..b06c9c7394c09 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -32,6 +32,20 @@ class DXILResourceTypeMap;
 
 namespace dxil {
 
+inline StringRef getResourceClassName(ResourceClass RC) {
+  switch (RC) {
+  case ResourceClass::SRV:
+    return "SRV";
+  case ResourceClass::UAV:
+    return "UAV";
+  case ResourceClass::CBuffer:
+    return "CBuffer";
+  case ResourceClass::Sampler:
+    return "Sampler";
+  }
+  llvm_unreachable("Unhandled ResourceClass");
+}
+
 // Returns the resource name from dx_resource_handlefrombinding or
 // dx_resource_handlefromimplicitbinding call
 LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI);
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index 4bc7771a0f83d..2e74d6d216ab8 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -153,17 +153,17 @@ class RootSignatureBindingValidation {
       uint32_t InsertPos = Bindings.size();
       Bindings.push_back(Binding);
       Ranges[Type] = {InsertPos, InsertPos + 1};
-    } else {
-      uint32_t InsertPos = It->second.End;
-      Bindings.insert(Bindings.begin() + InsertPos, Binding);
+      return;
+    } 
+    uint32_t InsertPos = It->second.End;
+    Bindings.insert(Bindings.begin() + InsertPos, Binding);
 
-      It->second.End++;
+    It->second.End++;
 
-      for (auto &[Type, Range] : Ranges) {
-        if (Range.Start > InsertPos) {
-          Range.Start++;
-          Range.End++;
-        }
+    for (auto &[Type, Range] : Ranges) {
+      if (Range.Start > InsertPos) {
+        Range.Start++;
+        Range.End++;
       }
     }
   }
@@ -171,9 +171,8 @@ class RootSignatureBindingValidation {
   llvm::ArrayRef<RangeInfo>
   getBindingsOfType(const dxil::ResourceClass &Type) const {
     auto It = Ranges.find(Type);
-    if (It == Ranges.end()) {
+    if (It == Ranges.end()) 
       return {};
-    }
     return llvm::ArrayRef<RangeInfo>(Bindings.data() + It->second.Start,
                                      It->second.End - It->second.Start);
   }
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index 2da6468ec3dcf..04e6ef0e1c1bf 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -29,20 +29,6 @@
 using namespace llvm;
 using namespace dxil;
 
-static StringRef getResourceClassName(ResourceClass RC) {
-  switch (RC) {
-  case ResourceClass::SRV:
-    return "SRV";
-  case ResourceClass::UAV:
-    return "UAV";
-  case ResourceClass::CBuffer:
-    return "CBuffer";
-  case ResourceClass::Sampler:
-    return "Sampler";
-  }
-  llvm_unreachable("Unhandled ResourceClass");
-}
-
 static StringRef getResourceKindName(ResourceKind RK) {
   switch (RK) {
   case ResourceKind::Texture1D:
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index b7204a4bf82a3..5984fe2a43f5f 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -335,9 +335,8 @@ findUnboundRanges(const llvm::ArrayRef<RangeInfo> &Ranges,
         break;
       }
     }
-    if (!Bound) {
+    if (!Bound) 
       Unbounds.push_back(Range);
-    }
   }
   return Unbounds;
 }
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index ba357f95ea8d8..b5b2c20f2b9ce 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -11,6 +11,7 @@
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
 #include "llvm/Frontend/HLSL/RootSignatureValidations.h"
@@ -26,19 +27,6 @@ using namespace llvm;
 using namespace llvm::dxil;
 
 namespace {
-static const char *ResourceClassToString(llvm::dxil::ResourceClass Class) {
-  switch (Class) {
-  case ResourceClass::SRV:
-    return "SRV";
-  case ResourceClass::UAV:
-    return "UAV";
-  case ResourceClass::CBuffer:
-    return "CBuffer";
-  case ResourceClass::Sampler:
-    return "Sampler";
-  }
-}
-
 static ResourceClass RangeToResourceClass(uint32_t RangeType) {
   using namespace dxbc;
   switch (static_cast<DescriptorRangeType>(RangeType)) {
@@ -132,7 +120,7 @@ static void reportRegNotBound(Module &M,
                               llvm::hlsl::rootsig::RangeInfo Unbound) {
   SmallString<128> Message;
   raw_svector_ostream OS(Message);
-  OS << "register " << ResourceClassToString(Unbound.Class)
+  OS << "register " << getResourceClassName(Unbound.Class)
      << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
      << ")"
      << " does not have a binding in the Root Signature";

>From 6db6224726db1a2394ac8d61cf46b69234490df7 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 1 Aug 2025 02:50:08 +0000
Subject: [PATCH 35/68] update code

---
 llvm/include/llvm/Frontend/HLSL/HLSLBinding.h |   4 +
 .../Frontend/HLSL/RootSignatureValidations.h  |  45 --------
 llvm/lib/Frontend/HLSL/HLSLBinding.cpp        |  17 +++
 .../DXILPostOptimizationValidation.cpp        | 108 +++++++-----------
 .../rootsignature-validation-fail-uav.ll      |   8 +-
 5 files changed, 69 insertions(+), 113 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
index 70a2eeb632f1b..a97dc3bd13ce0 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/DXILABI.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
 
 namespace llvm {
 namespace hlsl {
@@ -57,6 +58,7 @@ class BindingInfo {
     }
     // Size == -1 means unbounded array
     LLVM_ABI std::optional<uint32_t> findAvailableBinding(int32_t Size);
+    LLVM_ABI bool isBound(BindingRange B);
   };
 
   struct BindingSpaces {
@@ -95,6 +97,8 @@ class BindingInfo {
   LLVM_ABI std::optional<uint32_t>
   findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, int32_t Size);
 
+  LLVM_ABI bool isBound(dxil::ResourceClass RC, uint32_t Space, BindingRange B);
+
   friend class BindingInfoBuilder;
 };
 
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index 08cfd3e5fa134..e38017f0c6b4e 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -148,51 +148,6 @@ struct OverlappingRanges {
 ///      B: Check for overlap with any overlapping Visibility ResourceRange
 LLVM_ABI llvm::SmallVector<OverlappingRanges>
 findOverlappingRanges(ArrayRef<RangeInfo> Infos);
-
-class RootSignatureBindingValidation {
-private:
-  llvm::SmallVector<RangeInfo, 16> Bindings;
-  struct TypeRange {
-    uint32_t Start;
-    uint32_t End;
-  };
-  std::unordered_map<dxil::ResourceClass, TypeRange> Ranges;
-
-public:
-  void addBinding(dxil::ResourceClass Type, const RangeInfo &Binding) {
-    auto It = Ranges.find(Type);
-
-    if (It == Ranges.end()) {
-      uint32_t InsertPos = Bindings.size();
-      Bindings.push_back(Binding);
-      Ranges[Type] = {InsertPos, InsertPos + 1};
-      return;
-    } 
-    uint32_t InsertPos = It->second.End;
-    Bindings.insert(Bindings.begin() + InsertPos, Binding);
-
-    It->second.End++;
-
-    for (auto &[Type, Range] : Ranges) {
-      if (Range.Start > InsertPos) {
-        Range.Start++;
-        Range.End++;
-      }
-    }
-  }
-
-  llvm::ArrayRef<RangeInfo>
-  getBindingsOfType(const dxil::ResourceClass &Type) const {
-    auto It = Ranges.find(Type);
-    if (It == Ranges.end()) 
-      return {};
-    return llvm::ArrayRef<RangeInfo>(Bindings.data() + It->second.Start,
-                                     It->second.End - It->second.Start);
-  }
-};
-llvm::SmallVector<RangeInfo>
-findUnboundRanges(const llvm::ArrayRef<RangeInfo> &Ranges,
-                  const llvm::ArrayRef<RangeInfo> &Bindings);
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm
diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
index d581311f22028..cf6d4b741ed14 100644
--- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Frontend/HLSL/HLSLBinding.h"
 #include "llvm/ADT/STLExtras.h"
+#include <cstdint>
 
 using namespace llvm;
 using namespace hlsl;
@@ -66,6 +67,22 @@ BindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
   return std::nullopt;
 }
 
+bool BindingInfo::RegisterSpace::isBound(BindingRange B) {
+  for (BindingRange &R : FreeRanges) {
+    if (B.LowerBound >= R.LowerBound && B.LowerBound < R.UpperBound &&
+        B.UpperBound > R.LowerBound && B.UpperBound <= R.UpperBound)
+      return false;
+  }
+  return true;
+}
+
+bool BindingInfo::isBound(dxil::ResourceClass RC, uint32_t Space,
+                          BindingRange B) {
+  BindingSpaces &BS = getBindingSpaces(RC);
+  RegisterSpace &RS = BS.getOrInsertSpace(Space);
+  return RS.isBound(B);
+}
+
 BindingInfo BindingInfoBuilder::calculateBindingInfo(
     llvm::function_ref<void(const BindingInfoBuilder &Builder,
                             const Binding &Overlapping)>
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index b5b2c20f2b9ce..b63404d7a760a 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -14,12 +14,16 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Frontend/HLSL/HLSLBinding.h"
 #include "llvm/Frontend/HLSL/RootSignatureValidations.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/Support/DXILABI.h"
+#include <utility>
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 
@@ -116,11 +120,12 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
-static void reportRegNotBound(Module &M,
-                              llvm::hlsl::rootsig::RangeInfo Unbound) {
+static void
+reportRegNotBound(Module &M, ResourceClass Class,
+                  llvm::dxil::ResourceInfo::ResourceBinding Unbound) {
   SmallString<128> Message;
   raw_svector_ostream OS(Message);
-  OS << "register " << getResourceClassName(Unbound.Class)
+  OS << "register " << getResourceClassName(Class)
      << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
      << ")"
      << " does not have a binding in the Root Signature";
@@ -155,12 +160,9 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
-static hlsl::rootsig::RootSignatureBindingValidation
-initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
-                        dxbc::ShaderVisibility Visibility) {
-
-  hlsl::rootsig::RootSignatureBindingValidation Validation;
-
+static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
+                                    const mcdxbc::RootSignatureDesc &RSD,
+                                    dxbc::ShaderVisibility Visibility) {
   for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
     const auto &[Type, Loc] =
         RSD.ParametersContainer.getTypeAndLocForParameter(I);
@@ -175,15 +177,10 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
     case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
       dxbc::RTS0::v1::RootConstants Const =
           RSD.ParametersContainer.getConstant(Loc);
-
-      hlsl::rootsig::RangeInfo Binding;
-      Binding.LowerBound = Const.ShaderRegister;
-      Binding.Space = Const.RegisterSpace;
-      Binding.UpperBound = Binding.LowerBound;
-
-      // Root Constants Bind to CBuffers
-      Validation.addBinding(ResourceClass::CBuffer, Binding);
-
+      Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
+                           Const.ShaderRegister,
+                           Const.ShaderRegister + Const.Num32BitValues,
+                           nullptr);
       break;
     }
 
@@ -192,13 +189,9 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
     case llvm::to_underlying(dxbc::RootParameterType::CBV): {
       dxbc::RTS0::v2::RootDescriptor Desc =
           RSD.ParametersContainer.getRootDescriptor(Loc);
+      Builder.trackBinding(ParameterToResourceClass(Type), Desc.RegisterSpace,
+                           Desc.ShaderRegister, Desc.ShaderRegister, nullptr);
 
-      hlsl::rootsig::RangeInfo Binding;
-      Binding.LowerBound = Desc.ShaderRegister;
-      Binding.Space = Desc.RegisterSpace;
-      Binding.UpperBound = Binding.LowerBound;
-
-      Validation.addBinding(ParameterToResourceClass(Type), Binding);
       break;
     }
     case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
@@ -206,18 +199,15 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
           RSD.ParametersContainer.getDescriptorTable(Loc);
 
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-        hlsl::rootsig::RangeInfo Binding;
-        Binding.LowerBound = Range.BaseShaderRegister;
-        Binding.Space = Range.RegisterSpace;
-        Binding.UpperBound = Binding.LowerBound + Range.NumDescriptors - 1;
-        Validation.addBinding(RangeToResourceClass(Range.RangeType), Binding);
+        Builder.trackBinding(RangeToResourceClass(Range.RangeType),
+                             Range.RegisterSpace, Range.BaseShaderRegister,
+                             Range.BaseShaderRegister + Range.NumDescriptors,
+                             nullptr);
       }
       break;
     }
     }
   }
-
-  return Validation;
 }
 
 std::optional<mcdxbc::RootSignatureDesc>
@@ -232,30 +222,6 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
   return RootSigDesc;
 }
 
-static void reportUnboundRegisters(
-    Module &M,
-    const llvm::hlsl::rootsig::RootSignatureBindingValidation &Validation,
-    ResourceClass Class,
-    const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
-        &Resources) {
-  SmallVector<hlsl::rootsig::RangeInfo> Ranges;
-  for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) {
-    ResourceInfo::ResourceBinding ResBinding = Res->getBinding();
-    hlsl::rootsig::RangeInfo Range;
-    Range.Space = ResBinding.Space;
-    Range.LowerBound = ResBinding.LowerBound;
-    Range.UpperBound = Range.LowerBound + ResBinding.Size - 1;
-    Range.Class = Class;
-    Ranges.push_back(Range);
-  }
-
-  SmallVector<hlsl::rootsig::RangeInfo> Unbounds =
-      hlsl::rootsig::findUnboundRanges(Ranges,
-                                       Validation.getBindingsOfType(Class));
-  for (const auto &Unbound : Unbounds)
-    reportRegNotBound(M, Unbound);
-}
-
 static void reportErrors(Module &M, DXILResourceMap &DRM,
                          DXILResourceBindingInfo &DRBI,
                          RootSignatureBindingInfo &RSBI,
@@ -271,15 +237,29 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   if (auto RSD = getRootSignature(RSBI, MMI)) {
 
-    llvm::hlsl::rootsig::RootSignatureBindingValidation Validation =
-        initRSBindingValidation(*RSD, tripleToVisibility(MMI.ShaderProfile));
-
-    reportUnboundRegisters(M, Validation, ResourceClass::CBuffer,
-                           DRM.cbuffers());
-    reportUnboundRegisters(M, Validation, ResourceClass::UAV, DRM.uavs());
-    reportUnboundRegisters(M, Validation, ResourceClass::Sampler,
-                           DRM.samplers());
-    reportUnboundRegisters(M, Validation, ResourceClass::SRV, DRM.srvs());
+    hlsl::BindingInfoBuilder Builder;
+    dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
+    trackRootSigDescBinding(Builder, *RSD, Visibility);
+
+    bool HasOverlap;
+    hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap);
+
+    for (const auto &ResList :
+         {std::make_pair(ResourceClass::SRV, DRM.srvs()),
+          std::make_pair(ResourceClass::UAV, DRM.uavs()),
+          std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
+          std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
+      for (auto Res : ResList.second) {
+        llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
+        llvm::hlsl::BindingInfo::BindingRange ResRange(
+            ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
+
+        auto IsBound = Info.isBound(ResList.first, ResBinding.Space, ResRange);
+        if (!IsBound) {
+          reportRegNotBound(M, ResList.first, ResBinding);
+        }
+      }
+    }
   }
 }
 } // namespace
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
index 1bd0f6da62478..9cc5b6744a4a2 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 
-; CHECK: error: register UAV (space=0, register=4294967295) does not have a binding in the Root Signature
+; CHECK: error: register UAV (space=0, register=4294967294) does not have a binding in the Root Signature
 
 ; Root Signature(
 ;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
@@ -12,8 +12,8 @@
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
-; RWBuffer<float> UAV : register(u4294967295);
-  %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
+; RWBuffer<float> UAV : register(4294967294);
+  %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 4294967294, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
   ret void
 }
 
@@ -27,4 +27,4 @@ entry:
 !5 = !{!"DescriptorTable", i32 0, !6}
 !6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
 !7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
+!8 = !{!"UAV", i32 10, i32 0, i32 0, i32 -1, i32 2}

>From 04658b813a5b9b3863909fcdf522c662b1404409 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 1 Aug 2025 02:54:45 +0000
Subject: [PATCH 36/68] cleanup

---
 llvm/include/llvm/Frontend/HLSL/HLSLBinding.h |  1 -
 .../Frontend/HLSL/RootSignatureValidations.h  |  1 +
 llvm/lib/Frontend/HLSL/HLSLBinding.cpp        |  1 -
 .../HLSL/RootSignatureValidations.cpp         | 25 -------------------
 .../DXILPostOptimizationValidation.cpp        |  6 -----
 5 files changed, 1 insertion(+), 33 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
index a97dc3bd13ce0..af7f2402c0fa0 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
@@ -17,7 +17,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/DXILABI.h"
 #include "llvm/Support/ErrorHandling.h"
-#include <cstdint>
 
 namespace llvm {
 namespace hlsl {
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index e38017f0c6b4e..f1e223da95241 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -148,6 +148,7 @@ struct OverlappingRanges {
 ///      B: Check for overlap with any overlapping Visibility ResourceRange
 LLVM_ABI llvm::SmallVector<OverlappingRanges>
 findOverlappingRanges(ArrayRef<RangeInfo> Infos);
+
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm
diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
index cf6d4b741ed14..57075ca430d44 100644
--- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
@@ -8,7 +8,6 @@
 
 #include "llvm/Frontend/HLSL/HLSLBinding.h"
 #include "llvm/ADT/STLExtras.h"
-#include <cstdint>
 
 using namespace llvm;
 using namespace hlsl;
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index bdf7f353432df..f11c7d2033bfb 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -314,31 +314,6 @@ findOverlappingRanges(ArrayRef<RangeInfo> Infos) {
   return Overlaps;
 }
 
-llvm::SmallVector<RangeInfo>
-findUnboundRanges(const llvm::ArrayRef<RangeInfo> &Ranges,
-                  const llvm::ArrayRef<RangeInfo> &Bindings) {
-  llvm::SmallVector<RangeInfo> Unbounds;
-  for (const auto &Range : Ranges) {
-    bool Bound = false;
-    // hlsl::rootsig::RangeInfo Range;
-    // Range.Space = ResBinding.Space;
-    // Range.LowerBound = ResBinding.LowerBound;
-    // Range.UpperBound = Range.LowerBound + ResBinding.Size - 1;
-
-    for (const auto &Binding : Bindings) {
-      if (Range.Space == Binding.Space &&
-          Range.LowerBound >= Binding.LowerBound &&
-          Range.UpperBound <= Binding.UpperBound) {
-        Bound = true;
-        break;
-      }
-    }
-    if (!Bound) 
-      Unbounds.push_back(Range);
-  }
-  return Unbounds;
-}
-
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index b63404d7a760a..b661b71ffe3c2 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -11,19 +11,13 @@
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
-#include "llvm/Frontend/HLSL/HLSLBinding.h"
-#include "llvm/Frontend/HLSL/RootSignatureValidations.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
-#include "llvm/Support/DXILABI.h"
-#include <utility>
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 

>From adf3feb83461a743b43039b9e903f75e19ca06cc Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 10:45:23 -0700
Subject: [PATCH 37/68] address comments from inbelic

---
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index b661b71ffe3c2..0e25b8ff9897b 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -248,10 +248,8 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
         llvm::hlsl::BindingInfo::BindingRange ResRange(
             ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
 
-        auto IsBound = Info.isBound(ResList.first, ResBinding.Space, ResRange);
-        if (!IsBound) {
+        if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
           reportRegNotBound(M, ResList.first, ResBinding);
-        }
       }
     }
   }

>From c95ce6866488ee12da119bc66a864fd0d6df367f Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Thu, 26 Jun 2025 19:28:01 +0000
Subject: [PATCH 38/68] refactoring

refactoring

clean up

format

formating

fix import issues

formating

refactoring

init refactoring

adding validation

clean

implementing

finish implementing && fix tests

sync parent

sync parent

address comments

fix test

fix tests

format

address changes

add preserved

addressing comments

updating

format

adding tests

clean up

address comments

adding root constants

clean

moving code arround

clean

addressing comments

address comments

update code

cleanup

address comments from inbelic
---
 llvm/include/llvm/Analysis/DXILResource.h     |  14 ++
 llvm/include/llvm/Frontend/HLSL/HLSLBinding.h |   3 +
 .../Frontend/HLSL/RootSignatureValidations.h  | 129 +++++++++++--
 .../llvm/MC/DXContainerRootSignature.h        |   2 -
 llvm/lib/Analysis/DXILResource.cpp            |  14 --
 llvm/lib/Frontend/HLSL/HLSLBinding.cpp        |  16 ++
 llvm/lib/Target/DirectX/DXILOpLowering.cpp    |   2 +
 .../DXILPostOptimizationValidation.cpp        | 178 +++++++++++++++++-
 llvm/lib/Target/DirectX/DXILPrepare.cpp       |   1 -
 llvm/lib/Target/DirectX/DXILRootSignature.cpp |   5 +-
 llvm/lib/Target/DirectX/DXILRootSignature.h   |  12 +-
 llvm/test/CodeGen/DirectX/llc-pipeline.ll     |   2 +-
 .../rootsignature-validation-constants.ll     |  22 +++
 .../rootsignature-validation-fail-cbuffer.ll  |  34 ++++
 ...rootsignature-validation-fail-constants.ll |  22 +++
 .../rootsignature-validation-fail-sampler.ll  |  31 +++
 .../rootsignature-validation-fail-srv.ll      |  30 +++
 .../rootsignature-validation-fail-uav.ll      |  30 +++
 .../DirectX/rootsignature-validation.ll       |  39 ++++
 19 files changed, 546 insertions(+), 40 deletions(-)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation.ll

diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 93c6bfb057ef5..96d631698af0a 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -33,6 +33,20 @@ class DXILResourceTypeMap;
 
 namespace dxil {
 
+inline StringRef getResourceClassName(ResourceClass RC) {
+  switch (RC) {
+  case ResourceClass::SRV:
+    return "SRV";
+  case ResourceClass::UAV:
+    return "UAV";
+  case ResourceClass::CBuffer:
+    return "CBuffer";
+  case ResourceClass::Sampler:
+    return "Sampler";
+  }
+  llvm_unreachable("Unhandled ResourceClass");
+}
+
 // Returns the resource name from dx_resource_handlefrombinding or
 // dx_resource_handlefromimplicitbinding call
 LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI);
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
index 70a2eeb632f1b..af7f2402c0fa0 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
@@ -57,6 +57,7 @@ class BindingInfo {
     }
     // Size == -1 means unbounded array
     LLVM_ABI std::optional<uint32_t> findAvailableBinding(int32_t Size);
+    LLVM_ABI bool isBound(BindingRange B);
   };
 
   struct BindingSpaces {
@@ -95,6 +96,8 @@ class BindingInfo {
   LLVM_ABI std::optional<uint32_t>
   findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, int32_t Size);
 
+  LLVM_ABI bool isBound(dxil::ResourceClass RC, uint32_t Space, BindingRange B);
+
   friend class BindingInfoBuilder;
 };
 
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index fde32a1fff591..bb6aeeb177412 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -16,7 +16,6 @@
 
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/Frontend/HLSL/HLSLRootSignature.h"
-#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 namespace hlsl {
@@ -24,22 +23,118 @@ namespace rootsig {
 
 // Basic verification of RootElements
 
-LLVM_ABI bool verifyRootFlag(uint32_t Flags);
-LLVM_ABI bool verifyVersion(uint32_t Version);
-LLVM_ABI bool verifyRegisterValue(uint32_t RegisterValue);
-LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace);
-LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
-LLVM_ABI bool verifyRangeType(uint32_t Type);
-LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
-                                        uint32_t FlagsVal);
-LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors);
-LLVM_ABI bool verifySamplerFilter(uint32_t Value);
-LLVM_ABI bool verifyAddress(uint32_t Address);
-LLVM_ABI bool verifyMipLODBias(float MipLODBias);
-LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
-LLVM_ABI bool verifyComparisonFunc(uint32_t ComparisonFunc);
-LLVM_ABI bool verifyBorderColor(uint32_t BorderColor);
-LLVM_ABI bool verifyLOD(float LOD);
+bool verifyRootFlag(uint32_t Flags);
+bool verifyVersion(uint32_t Version);
+bool verifyRegisterValue(uint32_t RegisterValue);
+bool verifyRegisterSpace(uint32_t RegisterSpace);
+bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
+bool verifyRangeType(uint32_t Type);
+bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
+                               uint32_t FlagsVal);
+bool verifyNumDescriptors(uint32_t NumDescriptors);
+bool verifySamplerFilter(uint32_t Value);
+bool verifyAddress(uint32_t Address);
+bool verifyMipLODBias(float MipLODBias);
+bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
+bool verifyComparisonFunc(uint32_t ComparisonFunc);
+bool verifyBorderColor(uint32_t BorderColor);
+bool verifyLOD(float LOD);
+
+struct RangeInfo {
+  const static uint32_t Unbounded = ~0u;
+
+  // Interval information
+  uint32_t LowerBound;
+  uint32_t UpperBound;
+
+  // Information retained for determining overlap
+  llvm::dxil::ResourceClass Class;
+  uint32_t Space;
+  llvm::dxbc::ShaderVisibility Visibility;
+};
+
+class ResourceRange {
+public:
+  using MapT = llvm::IntervalMap<uint32_t, const RangeInfo *, 16,
+                                 llvm::IntervalMapInfo<uint32_t>>;
+
+private:
+  MapT Intervals;
+
+public:
+  ResourceRange(MapT::Allocator &Allocator) : Intervals(MapT(Allocator)) {}
+
+  // Returns a reference to the first RangeInfo that overlaps with
+  // [Info.LowerBound;Info.UpperBound], or, std::nullopt if there is no overlap
+  LLVM_ABI std::optional<const RangeInfo *>
+  getOverlapping(const RangeInfo &Info) const;
+
+  // Return the mapped RangeInfo at X or nullptr if no mapping exists
+  LLVM_ABI const RangeInfo *lookup(uint32_t X) const;
+
+  // Removes all entries of the ResourceRange
+  LLVM_ABI void clear();
+
+  // Insert the required (sub-)intervals such that the interval of [a;b] =
+  // [Info.LowerBound, Info.UpperBound] is covered and points to a valid
+  // RangeInfo &.
+  //
+  // For instance consider the following chain of inserting RangeInfos with the
+  // intervals denoting the Lower/Upper-bounds:
+  //
+  // A = [0;2]
+  //   insert(A) -> false
+  //   intervals: [0;2] -> &A
+  // B = [5;7]
+  //   insert(B) -> false
+  //   intervals: [0;2] -> &A, [5;7] -> &B
+  // C = [4;7]
+  //   insert(C) -> true
+  //   intervals: [0;2] -> &A, [4;7] -> &C
+  // D = [1;5]
+  //   insert(D) -> true
+  //   intervals: [0;2] -> &A, [3;3] -> &D, [4;7] -> &C
+  // E = [0;unbounded]
+  //   insert(E) -> true
+  //   intervals: [0;unbounded] -> E
+  //
+  // Returns a reference to the first RangeInfo that overlaps with
+  // [Info.LowerBound;Info.UpperBound], or, std::nullopt if there is no overlap
+  // (equivalent to getOverlapping)
+  LLVM_ABI std::optional<const RangeInfo *> insert(const RangeInfo &Info);
+};
+
+struct OverlappingRanges {
+  const RangeInfo *A;
+  const RangeInfo *B;
+
+  OverlappingRanges(const RangeInfo *A, const RangeInfo *B) : A(A), B(B) {}
+};
+
+/// The following conducts analysis on resource ranges to detect and report
+/// any overlaps in resource ranges.
+///
+/// A resource range overlaps with another resource range if they have:
+/// - equivalent ResourceClass (SRV, UAV, CBuffer, Sampler)
+/// - equivalent resource space
+/// - overlapping visbility
+///
+/// The algorithm is implemented in the following steps:
+///
+/// 1. The user will collect RangeInfo from relevant RootElements:
+///   - RangeInfo will retain the interval, ResourceClass, Space and Visibility
+///   - It will also contain an index so that it can be associated to
+/// additional diagnostic information
+/// 2. Sort the RangeInfo's such that they are grouped together by
+///  ResourceClass and Space
+/// 3. Iterate through the collected RangeInfos by their groups
+///   - For each group we will have a ResourceRange for each visibility
+///   - As we iterate through we will:
+///      A: Insert the current RangeInfo into the corresponding Visibility
+///   ResourceRange
+///      B: Check for overlap with any overlapping Visibility ResourceRange
+LLVM_ABI llvm::SmallVector<OverlappingRanges>
+findOverlappingRanges(ArrayRef<RangeInfo> Infos);
 
 } // namespace rootsig
 } // namespace hlsl
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 3c7c886e79fc3..a931b1d54b65c 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -5,7 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
 #ifndef LLVM_MC_DXCONTAINERROOTSIGNATURE_H
 #define LLVM_MC_DXCONTAINERROOTSIGNATURE_H
 
@@ -120,5 +119,4 @@ struct RootSignatureDesc {
 };
 } // namespace mcdxbc
 } // namespace llvm
-
 #endif // LLVM_MC_DXCONTAINERROOTSIGNATURE_H
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index 629fa7cddb9d4..b476026fcc718 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -29,20 +29,6 @@
 using namespace llvm;
 using namespace dxil;
 
-static StringRef getResourceClassName(ResourceClass RC) {
-  switch (RC) {
-  case ResourceClass::SRV:
-    return "SRV";
-  case ResourceClass::UAV:
-    return "UAV";
-  case ResourceClass::CBuffer:
-    return "CBuffer";
-  case ResourceClass::Sampler:
-    return "Sampler";
-  }
-  llvm_unreachable("Unhandled ResourceClass");
-}
-
 static StringRef getResourceKindName(ResourceKind RK) {
   switch (RK) {
   case ResourceKind::Texture1D:
diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
index d581311f22028..57075ca430d44 100644
--- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
@@ -66,6 +66,22 @@ BindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
   return std::nullopt;
 }
 
+bool BindingInfo::RegisterSpace::isBound(BindingRange B) {
+  for (BindingRange &R : FreeRanges) {
+    if (B.LowerBound >= R.LowerBound && B.LowerBound < R.UpperBound &&
+        B.UpperBound > R.LowerBound && B.UpperBound <= R.UpperBound)
+      return false;
+  }
+  return true;
+}
+
+bool BindingInfo::isBound(dxil::ResourceClass RC, uint32_t Space,
+                          BindingRange B) {
+  BindingSpaces &BS = getBindingSpaces(RC);
+  RegisterSpace &RS = BS.getOrInsertSpace(Space);
+  return RS.isBound(B);
+}
+
 BindingInfo BindingInfoBuilder::calculateBindingInfo(
     llvm::function_ref<void(const BindingInfoBuilder &Builder,
                             const Binding &Overlapping)>
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 0ec15a629d0a2..db7719e129ad0 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -9,6 +9,7 @@
 #include "DXILOpLowering.h"
 #include "DXILConstants.h"
 #include "DXILOpBuilder.h"
+#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallVector.h"
@@ -945,6 +946,7 @@ class DXILOpLoweringLegacy : public ModulePass {
     AU.addPreserved<DXILResourceWrapperPass>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
+    AU.addPreserved<RootSignatureAnalysisWrapper>();
   }
 };
 char DXILOpLoweringLegacy::ID = 0;
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 398dcbb8d1737..0e25b8ff9897b 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "DXILPostOptimizationValidation.h"
+#include "DXILRootSignature.h"
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/SmallString.h"
@@ -24,6 +25,35 @@ using namespace llvm;
 using namespace llvm::dxil;
 
 namespace {
+static ResourceClass RangeToResourceClass(uint32_t RangeType) {
+  using namespace dxbc;
+  switch (static_cast<DescriptorRangeType>(RangeType)) {
+  case DescriptorRangeType::SRV:
+    return ResourceClass::SRV;
+  case DescriptorRangeType::UAV:
+    return ResourceClass::UAV;
+  case DescriptorRangeType::CBV:
+    return ResourceClass::CBuffer;
+  case DescriptorRangeType::Sampler:
+    return ResourceClass::Sampler;
+  }
+}
+
+ResourceClass ParameterToResourceClass(uint32_t Type) {
+  using namespace dxbc;
+  switch (Type) {
+  case llvm::to_underlying(RootParameterType::Constants32Bit):
+    return ResourceClass::CBuffer;
+  case llvm::to_underlying(RootParameterType::SRV):
+    return ResourceClass::SRV;
+  case llvm::to_underlying(RootParameterType::UAV):
+    return ResourceClass::UAV;
+  case llvm::to_underlying(RootParameterType::CBV):
+    return ResourceClass::CBuffer;
+  default:
+    llvm_unreachable("Unknown RootParameterType");
+  }
+}
 
 static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
   for (const auto &UAV : DRM.uavs()) {
@@ -84,8 +114,112 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
+static void
+reportRegNotBound(Module &M, ResourceClass Class,
+                  llvm::dxil::ResourceInfo::ResourceBinding Unbound) {
+  SmallString<128> Message;
+  raw_svector_ostream OS(Message);
+  OS << "register " << getResourceClassName(Class)
+     << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
+     << ")"
+     << " does not have a binding in the Root Signature";
+  M.getContext().diagnose(DiagnosticInfoGeneric(Message));
+}
+
+static dxbc::ShaderVisibility
+tripleToVisibility(llvm::Triple::EnvironmentType ET) {
+  assert((ET == Triple::Pixel || ET == Triple::Vertex ||
+          ET == Triple::Geometry || ET == Triple::Hull ||
+          ET == Triple::Domain || ET == Triple::Mesh ||
+          ET == Triple::Compute) &&
+         "Invalid Triple to shader stage conversion");
+
+  switch (ET) {
+  case Triple::Pixel:
+    return dxbc::ShaderVisibility::Pixel;
+  case Triple::Vertex:
+    return dxbc::ShaderVisibility::Vertex;
+  case Triple::Geometry:
+    return dxbc::ShaderVisibility::Geometry;
+  case Triple::Hull:
+    return dxbc::ShaderVisibility::Hull;
+  case Triple::Domain:
+    return dxbc::ShaderVisibility::Domain;
+  case Triple::Mesh:
+    return dxbc::ShaderVisibility::Mesh;
+  case Triple::Compute:
+    return dxbc::ShaderVisibility::All;
+  default:
+    llvm_unreachable("Invalid triple to shader stage conversion");
+  }
+}
+
+static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
+                                    const mcdxbc::RootSignatureDesc &RSD,
+                                    dxbc::ShaderVisibility Visibility) {
+  for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
+    const auto &[Type, Loc] =
+        RSD.ParametersContainer.getTypeAndLocForParameter(I);
+
+    const auto &Header = RSD.ParametersContainer.getHeader(I);
+    if (Header.ShaderVisibility !=
+            llvm::to_underlying(dxbc::ShaderVisibility::All) &&
+        Header.ShaderVisibility != llvm::to_underlying(Visibility))
+      continue;
+
+    switch (Type) {
+    case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
+      dxbc::RTS0::v1::RootConstants Const =
+          RSD.ParametersContainer.getConstant(Loc);
+      Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
+                           Const.ShaderRegister,
+                           Const.ShaderRegister + Const.Num32BitValues,
+                           nullptr);
+      break;
+    }
+
+    case llvm::to_underlying(dxbc::RootParameterType::SRV):
+    case llvm::to_underlying(dxbc::RootParameterType::UAV):
+    case llvm::to_underlying(dxbc::RootParameterType::CBV): {
+      dxbc::RTS0::v2::RootDescriptor Desc =
+          RSD.ParametersContainer.getRootDescriptor(Loc);
+      Builder.trackBinding(ParameterToResourceClass(Type), Desc.RegisterSpace,
+                           Desc.ShaderRegister, Desc.ShaderRegister, nullptr);
+
+      break;
+    }
+    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+      const mcdxbc::DescriptorTable &Table =
+          RSD.ParametersContainer.getDescriptorTable(Loc);
+
+      for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
+        Builder.trackBinding(RangeToResourceClass(Range.RangeType),
+                             Range.RegisterSpace, Range.BaseShaderRegister,
+                             Range.BaseShaderRegister + Range.NumDescriptors,
+                             nullptr);
+      }
+      break;
+    }
+    }
+  }
+}
+
+std::optional<mcdxbc::RootSignatureDesc>
+getRootSignature(RootSignatureBindingInfo &RSBI,
+                 dxil::ModuleMetadataInfo &MMI) {
+  if (MMI.EntryPropertyVec.size() == 0)
+    return std::nullopt;
+  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
+      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
+  if (!RootSigDesc)
+    return std::nullopt;
+  return RootSigDesc;
+}
+
 static void reportErrors(Module &M, DXILResourceMap &DRM,
-                         DXILResourceBindingInfo &DRBI) {
+                         DXILResourceBindingInfo &DRBI,
+                         RootSignatureBindingInfo &RSBI,
+                         dxil::ModuleMetadataInfo &MMI) {
   if (DRM.hasInvalidCounterDirection())
     reportInvalidDirection(M, DRM);
 
@@ -94,6 +228,31 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
 
   assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
                                        "DXILResourceImplicitBinding pass");
+
+  if (auto RSD = getRootSignature(RSBI, MMI)) {
+
+    hlsl::BindingInfoBuilder Builder;
+    dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
+    trackRootSigDescBinding(Builder, *RSD, Visibility);
+
+    bool HasOverlap;
+    hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap);
+
+    for (const auto &ResList :
+         {std::make_pair(ResourceClass::SRV, DRM.srvs()),
+          std::make_pair(ResourceClass::UAV, DRM.uavs()),
+          std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
+          std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
+      for (auto Res : ResList.second) {
+        llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
+        llvm::hlsl::BindingInfo::BindingRange ResRange(
+            ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
+
+        if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
+          reportRegNotBound(M, ResList.first, ResBinding);
+      }
+    }
+  }
 }
 } // namespace
 
@@ -101,7 +260,10 @@ PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
   DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
   DXILResourceBindingInfo &DRBI = MAM.getResult<DXILResourceBindingAnalysis>(M);
-  reportErrors(M, DRM, DRBI);
+  RootSignatureBindingInfo &RSBI = MAM.getResult<RootSignatureAnalysis>(M);
+  ModuleMetadataInfo &MMI = MAM.getResult<DXILMetadataAnalysis>(M);
+
+  reportErrors(M, DRM, DRBI, RSBI, MMI);
   return PreservedAnalyses::all();
 }
 
@@ -113,7 +275,12 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
         getAnalysis<DXILResourceWrapperPass>().getResourceMap();
     DXILResourceBindingInfo &DRBI =
         getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();
-    reportErrors(M, DRM, DRBI);
+    RootSignatureBindingInfo &RSBI =
+        getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
+    dxil::ModuleMetadataInfo &MMI =
+        getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
+
+    reportErrors(M, DRM, DRBI, RSBI, MMI);
     return false;
   }
   StringRef getPassName() const override {
@@ -125,10 +292,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
   void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
     AU.addRequired<DXILResourceWrapperPass>();
     AU.addRequired<DXILResourceBindingWrapperPass>();
+    AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<DXILResourceWrapperPass>();
     AU.addPreserved<DXILResourceBindingWrapperPass>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
+    AU.addPreserved<RootSignatureAnalysisWrapper>();
   }
 };
 char DXILPostOptimizationValidationLegacy::ID = 0;
@@ -139,6 +309,8 @@ INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
 INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
 INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
                     "DXIL Post Optimization Validation", false, false)
 
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index c8866bfefdfc5..9c3eba83eba7c 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -300,7 +300,6 @@ class DXILPrepareModule : public ModulePass {
   DXILPrepareModule() : ModulePass(ID) {}
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
-    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<RootSignatureAnalysisWrapper>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index a4f5086c2f428..eb9ff5ab405e4 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -29,6 +29,8 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
+#include <optional>
+#include <utility>
 
 using namespace llvm;
 using namespace llvm::dxil;
@@ -233,7 +235,7 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
 
 void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
+  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
 }
 
 char RootSignatureAnalysisWrapper::ID = 0;
@@ -241,6 +243,7 @@ char RootSignatureAnalysisWrapper::ID = 0;
 INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper,
                       "dxil-root-signature-analysis",
                       "DXIL Root Signature Analysis", true, true)
+INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
 INITIALIZE_PASS_END(RootSignatureAnalysisWrapper,
                     "dxil-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 254b7ff504633..ccffa3fd0a3e2 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -26,6 +26,16 @@
 namespace llvm {
 namespace dxil {
 
+enum class RootSignatureElementKind {
+  Error = 0,
+  RootFlags = 1,
+  RootConstants = 2,
+  SRV = 3,
+  UAV = 4,
+  CBV = 5,
+  DescriptorTable = 6,
+};
+
 class RootSignatureBindingInfo {
 private:
   SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
@@ -96,4 +106,4 @@ class RootSignatureAnalysisPrinter
 
 } // namespace dxil
 } // namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 151603a7161c5..c31d2194a8de5 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -33,9 +33,9 @@
 ; CHECK-NEXT:   DXIL Module Metadata analysis
 ; CHECK-NEXT:   DXIL Shader Flag Analysis
 ; CHECK-NEXT:   DXIL Translate Metadata
+; CHECK-NEXT:   DXIL Root Signature Analysis
 ; CHECK-NEXT:   DXIL Post Optimization Validation
 ; CHECK-NEXT:   DXIL Op Lowering
-; CHECK-NEXT:   DXIL Root Signature Analysis
 ; CHECK-NEXT:   DXIL Prepare Module
 
 ; CHECK-ASM-NEXT: DXIL Metadata Pretty Printer
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
new file mode 100644
index 0000000000000..3c33f1dc6bdf0
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
@@ -0,0 +1,22 @@
+; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; expected-no-diagnostics
+; Root Signature(RootConstants(num32BitConstants=4, b2))
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; cbuffer CB : register(b2, space0) {
+;  float a;
+; }
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2}
+!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
new file mode 100644
index 0000000000000..e5133810c0f32
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
@@ -0,0 +1,34 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register CBuffer (space=665, register=3) does not have a binding in the Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; cbuffer CB : register(b3, space665) {
+;  float a;
+; }
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
new file mode 100644
index 0000000000000..dc7657e79ec97
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
@@ -0,0 +1,22 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register CBuffer (space=666, register=2) does not have a binding in the Root Signature
+; Root Signature(RootConstants(num32BitConstants=4, b2))
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; cbuffer CB : register(b2, space666) {
+;  float a;
+; }
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 666, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2}
+!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
new file mode 100644
index 0000000000000..152c363fdf75b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -0,0 +1,31 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register Sampler (space=2, register=3) does not have a binding in the Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; SamplerState S1 : register(s3, space2);
+  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
+
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
new file mode 100644
index 0000000000000..ebefa7b1a3d85
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
@@ -0,0 +1,30 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register SRV (space=0, register=0) does not have a binding in the Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; StructuredBuffer<int> In : register(t0, space0);
+  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
new file mode 100644
index 0000000000000..9cc5b6744a4a2
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
@@ -0,0 +1,30 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+
+; CHECK: error: register UAV (space=0, register=4294967294) does not have a binding in the Root Signature
+
+; Root Signature(
+;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+ at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+; RWBuffer<float> UAV : register(4294967294);
+  %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 4294967294, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
+!3 = !{!"DescriptorTable", i32 1, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 10, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
new file mode 100644
index 0000000000000..750679bf743c5
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -0,0 +1,39 @@
+; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; expected-no-diagnostics
+
+
+; Root Signature(
+;   CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
+;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
+;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
+
+%__cblayout_CB = type <{ float }>
+
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+ at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
+ at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
+ at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+
+  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
+  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
+  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
+  %RWB =  tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
+
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3, !5, !7}
+!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4}
+!3 = !{!"DescriptorTable", i32 0, !4}
+!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0}
+!5 = !{!"DescriptorTable", i32 0, !6}
+!6 = !{!"Sampler", i32 5, i32 3, i32 2, i32 -1, i32 0}
+!7 = !{!"DescriptorTable", i32 0, !8}
+!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}

>From af6aa531329212cfe71baf720196b62d0baa67bc Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 13:39:56 -0700
Subject: [PATCH 39/68] add tests

---
 .../DXILPostOptimizationValidation.cpp        | 59 +++++++++----------
 ...signature-validation-fail-cbuffer-range.ll | 15 +++++
 .../rootsignature-validation-fail-cbuffer.ll  | 34 -----------
 ...rootsignature-validation-fail-constants.ll | 22 -------
 ...-validation-fail-descriptor-table-range.ll | 15 +++++
 ...e-validation-fail-root-descriptor-range.ll | 15 +++++
 .../rootsignature-validation-fail-sampler.ll  | 31 ----------
 .../rootsignature-validation-fail-srv.ll      | 30 ----------
 ...re-validation-fail-static-sampler-range.ll | 13 ++++
 .../rootsignature-validation-fail-uav.ll      | 30 ----------
 10 files changed, 87 insertions(+), 177 deletions(-)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 0e25b8ff9897b..3da4cfbea23b8 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -114,15 +114,18 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
-static void
-reportRegNotBound(Module &M, ResourceClass Class,
-                  llvm::dxil::ResourceInfo::ResourceBinding Unbound) {
+static void reportOverlappingRegisters(
+    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &Reported,
+    const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping) {
   SmallString<128> Message;
   raw_svector_ostream OS(Message);
-  OS << "register " << getResourceClassName(Class)
-     << " (space=" << Unbound.Space << ", register=" << Unbound.LowerBound
-     << ")"
-     << " does not have a binding in the Root Signature";
+  OS << "register " << getResourceClassName(Reported.RC)
+     << " (space=" << Reported.Space << ", register=" << Reported.LowerBound
+     << ")" << " is overlapping with" << " register "
+     << getResourceClassName(Overlaping.RC) << " (space=" << Overlaping.Space
+     << ", register=" << Overlaping.LowerBound << ")"
+     << ", verify your root signature definition.";
+
   M.getContext().diagnose(DiagnosticInfoGeneric(Message));
 }
 
@@ -173,8 +176,7 @@ static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
           RSD.ParametersContainer.getConstant(Loc);
       Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
                            Const.ShaderRegister,
-                           Const.ShaderRegister + Const.Num32BitValues,
-                           nullptr);
+                           Const.ShaderRegister + Const.Num32BitValues, &Const);
       break;
     }
 
@@ -184,7 +186,7 @@ static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
       dxbc::RTS0::v2::RootDescriptor Desc =
           RSD.ParametersContainer.getRootDescriptor(Loc);
       Builder.trackBinding(ParameterToResourceClass(Type), Desc.RegisterSpace,
-                           Desc.ShaderRegister, Desc.ShaderRegister, nullptr);
+                           Desc.ShaderRegister, Desc.ShaderRegister, &Desc);
 
       break;
     }
@@ -195,13 +197,21 @@ static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
         Builder.trackBinding(RangeToResourceClass(Range.RangeType),
                              Range.RegisterSpace, Range.BaseShaderRegister,
-                             Range.BaseShaderRegister + Range.NumDescriptors,
-                             nullptr);
+                             Range.NumDescriptors == ~0U
+                                 ? Range.NumDescriptors
+                                 : Range.BaseShaderRegister +
+                                       Range.NumDescriptors,
+                             &Range);
       }
       break;
     }
     }
   }
+
+  for (auto &S : RSD.StaticSamplers) {
+    Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
+                         S.ShaderRegister, S.ShaderRegister, &S);
+  }
 }
 
 std::optional<mcdxbc::RootSignatureDesc>
@@ -234,24 +244,13 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
     hlsl::BindingInfoBuilder Builder;
     dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
     trackRootSigDescBinding(Builder, *RSD, Visibility);
-
-    bool HasOverlap;
-    hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap);
-
-    for (const auto &ResList :
-         {std::make_pair(ResourceClass::SRV, DRM.srvs()),
-          std::make_pair(ResourceClass::UAV, DRM.uavs()),
-          std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
-          std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
-      for (auto Res : ResList.second) {
-        llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
-        llvm::hlsl::BindingInfo::BindingRange ResRange(
-            ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
-
-        if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
-          reportRegNotBound(M, ResList.first, ResBinding);
-      }
-    }
+    hlsl::BindingInfo Info = Builder.calculateBindingInfo(
+        [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
+             const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
+          const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
+              Builder.findOverlapping(ReportedBinding);
+          reportOverlappingRegisters(M, ReportedBinding, Overlaping);
+        });
   }
 }
 } // namespace
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
new file mode 100644
index 0000000000000..5def38af0fbeb
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
@@ -0,0 +1,15 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register CBuffer (space=0, register=2) is overlapping with register CBuffer (space=0, register=0), verify your root signature definition.
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  ret void
+}
+
+; RootConstants(num32BitConstants=4, b2), DescriptorTable(CBV(b0, numDescriptors=3))
+!dx.rootsignatures = !{!0}
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3}
+!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
+!3 = !{!"DescriptorTable", i32 0, !4}
+!4 = !{!"CBV", i32 3, i32 0, i32 0, i32 -1, i32 4}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
deleted file mode 100644
index e5133810c0f32..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
-; CHECK: error: register CBuffer (space=665, register=3) does not have a binding in the Root Signature
-
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
-%__cblayout_CB = type <{ float }>
-
- at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; cbuffer CB : register(b3, space665) {
-;  float a;
-; }
-  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
-!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
-!3 = !{!"DescriptorTable", i32 1, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 0, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
-!7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
deleted file mode 100644
index dc7657e79ec97..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
+++ /dev/null
@@ -1,22 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CBuffer (space=666, register=2) does not have a binding in the Root Signature
-; Root Signature(RootConstants(num32BitConstants=4, b2))
-
-%__cblayout_CB = type <{ float }>
-
- at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; cbuffer CB : register(b2, space666) {
-;  float a;
-; }
-  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 666, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2}
-!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
new file mode 100644
index 0000000000000..7108d9834219e
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
@@ -0,0 +1,15 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register UAV (space=10, register=4294967295) is overlapping with register UAV (space=10, register=4294967295), verify your root signature definition.
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  ret void
+}
+
+; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), DescriptorTable(UAV(u2, numDescriptors=4))
+!dx.rootsignatures = !{!0}
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !4}
+!2 = !{!"DescriptorTable", i32 0, !3}
+!3 = !{!"UAV", i32 -1, i32 -1, i32 10, i32 -1, i32 2}
+!4 = !{!"DescriptorTable", i32 0, !5}
+!5 = !{ !"UAV", i32 -1, i32 -1, i32 10, i32 5, i32 2 }
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
new file mode 100644
index 0000000000000..7790230eb07a0
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
@@ -0,0 +1,15 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register UAV (space=1, register=3) is overlapping with register UAV (space=1, register=0), verify your root signature definition.
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  ret void
+}
+
+; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), UAV(u3, space=1)
+!dx.rootsignatures = !{!0}
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !4}
+!2 = !{!"RootUAV", i32 0, i32 3, i32 1, i32 4}
+!4 = !{!"DescriptorTable", i32 0, !5}
+!5 = !{!"UAV", i32 3, i32 0, i32 1, i32 -1, i32 2}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
deleted file mode 100644
index 152c363fdf75b..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ /dev/null
@@ -1,31 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
-; CHECK: error: register Sampler (space=2, register=3) does not have a binding in the Root Signature
-
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
- at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; SamplerState S1 : register(s3, space2);
-  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
-
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
-!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
-!3 = !{!"DescriptorTable", i32 1, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 0, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
-!7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
deleted file mode 100644
index ebefa7b1a3d85..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
+++ /dev/null
@@ -1,30 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
-; CHECK: error: register SRV (space=0, register=0) does not have a binding in the Root Signature
-
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
- at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; StructuredBuffer<int> In : register(t0, space0);
-  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
-!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
-!3 = !{!"DescriptorTable", i32 1, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 0, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
-!7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
new file mode 100644
index 0000000000000..bbcc42769d7be
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
@@ -0,0 +1,13 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register Sampler (space=0, register=42) is overlapping with register Sampler (space=0, register=42), verify your root signature definition.
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3}
+!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
+!3 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
deleted file mode 100644
index 9cc5b6744a4a2..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
+++ /dev/null
@@ -1,30 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
-; CHECK: error: register UAV (space=0, register=4294967294) does not have a binding in the Root Signature
-
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
- at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; RWBuffer<float> UAV : register(4294967294);
-  %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 4294967294, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
-!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
-!3 = !{!"DescriptorTable", i32 1, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 0, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
-!7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 10, i32 0, i32 0, i32 -1, i32 2}

>From 29eb893bcb28676157c6c2314f55ff6d7e33043f Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 14:43:51 -0700
Subject: [PATCH 40/68] cleanup

---
 llvm/include/llvm/Frontend/HLSL/HLSLBinding.h    |  3 ---
 llvm/lib/Frontend/HLSL/HLSLBinding.cpp           | 16 ----------------
 ...ature-validation-fail-static-sampler-range.ll |  2 +-
 3 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
index af7f2402c0fa0..70a2eeb632f1b 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLBinding.h
@@ -57,7 +57,6 @@ class BindingInfo {
     }
     // Size == -1 means unbounded array
     LLVM_ABI std::optional<uint32_t> findAvailableBinding(int32_t Size);
-    LLVM_ABI bool isBound(BindingRange B);
   };
 
   struct BindingSpaces {
@@ -96,8 +95,6 @@ class BindingInfo {
   LLVM_ABI std::optional<uint32_t>
   findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, int32_t Size);
 
-  LLVM_ABI bool isBound(dxil::ResourceClass RC, uint32_t Space, BindingRange B);
-
   friend class BindingInfoBuilder;
 };
 
diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
index 57075ca430d44..d581311f22028 100644
--- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
@@ -66,22 +66,6 @@ BindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
   return std::nullopt;
 }
 
-bool BindingInfo::RegisterSpace::isBound(BindingRange B) {
-  for (BindingRange &R : FreeRanges) {
-    if (B.LowerBound >= R.LowerBound && B.LowerBound < R.UpperBound &&
-        B.UpperBound > R.LowerBound && B.UpperBound <= R.UpperBound)
-      return false;
-  }
-  return true;
-}
-
-bool BindingInfo::isBound(dxil::ResourceClass RC, uint32_t Space,
-                          BindingRange B) {
-  BindingSpaces &BS = getBindingSpaces(RC);
-  RegisterSpace &RS = BS.getOrInsertSpace(Space);
-  return RS.isBound(B);
-}
-
 BindingInfo BindingInfoBuilder::calculateBindingInfo(
     llvm::function_ref<void(const BindingInfoBuilder &Builder,
                             const Binding &Overlapping)>
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
index bbcc42769d7be..340b0aed6d16b 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
@@ -10,4 +10,4 @@ entry:
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3}
 !2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
-!3 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
\ No newline at end of file
+!3 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }

>From ed4c5539bf15b241a3d2ec243068d714fbe37acb Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 14:46:26 -0700
Subject: [PATCH 41/68] clean

---
 .../rootsignature-validation-fail-descriptor-table-range.ll     | 2 +-
 .../rootsignature-validation-fail-root-descriptor-range.ll      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
index 7108d9834219e..dbc75ac86db5f 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
@@ -12,4 +12,4 @@ entry:
 !2 = !{!"DescriptorTable", i32 0, !3}
 !3 = !{!"UAV", i32 -1, i32 -1, i32 10, i32 -1, i32 2}
 !4 = !{!"DescriptorTable", i32 0, !5}
-!5 = !{ !"UAV", i32 -1, i32 -1, i32 10, i32 5, i32 2 }
\ No newline at end of file
+!5 = !{ !"UAV", i32 -1, i32 -1, i32 10, i32 5, i32 2 }
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
index 7790230eb07a0..9f70cc3f062a9 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
@@ -12,4 +12,4 @@ entry:
 !1 = !{!2, !4}
 !2 = !{!"RootUAV", i32 0, i32 3, i32 1, i32 4}
 !4 = !{!"DescriptorTable", i32 0, !5}
-!5 = !{!"UAV", i32 3, i32 0, i32 1, i32 -1, i32 2}
\ No newline at end of file
+!5 = !{!"UAV", i32 3, i32 0, i32 1, i32 -1, i32 2}

>From 28fb609226910ef2ae4ef6caa8b5116df846d114 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 17:21:18 -0700
Subject: [PATCH 42/68] clean up

---
 .../Frontend/HLSL/RootSignatureValidations.h  | 129 +++---------------
 .../llvm/MC/DXContainerRootSignature.h        |   2 +
 llvm/lib/Target/DirectX/DXILPrepare.cpp       |   1 +
 llvm/lib/Target/DirectX/DXILRootSignature.cpp |   5 +-
 llvm/lib/Target/DirectX/DXILRootSignature.h   |  12 +-
 ...signature-validation-fail-cbuffer-range.ll |   2 +-
 6 files changed, 23 insertions(+), 128 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index bb6aeeb177412..fde32a1fff591 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/Frontend/HLSL/HLSLRootSignature.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 namespace hlsl {
@@ -23,118 +24,22 @@ namespace rootsig {
 
 // Basic verification of RootElements
 
-bool verifyRootFlag(uint32_t Flags);
-bool verifyVersion(uint32_t Version);
-bool verifyRegisterValue(uint32_t RegisterValue);
-bool verifyRegisterSpace(uint32_t RegisterSpace);
-bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
-bool verifyRangeType(uint32_t Type);
-bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
-                               uint32_t FlagsVal);
-bool verifyNumDescriptors(uint32_t NumDescriptors);
-bool verifySamplerFilter(uint32_t Value);
-bool verifyAddress(uint32_t Address);
-bool verifyMipLODBias(float MipLODBias);
-bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
-bool verifyComparisonFunc(uint32_t ComparisonFunc);
-bool verifyBorderColor(uint32_t BorderColor);
-bool verifyLOD(float LOD);
-
-struct RangeInfo {
-  const static uint32_t Unbounded = ~0u;
-
-  // Interval information
-  uint32_t LowerBound;
-  uint32_t UpperBound;
-
-  // Information retained for determining overlap
-  llvm::dxil::ResourceClass Class;
-  uint32_t Space;
-  llvm::dxbc::ShaderVisibility Visibility;
-};
-
-class ResourceRange {
-public:
-  using MapT = llvm::IntervalMap<uint32_t, const RangeInfo *, 16,
-                                 llvm::IntervalMapInfo<uint32_t>>;
-
-private:
-  MapT Intervals;
-
-public:
-  ResourceRange(MapT::Allocator &Allocator) : Intervals(MapT(Allocator)) {}
-
-  // Returns a reference to the first RangeInfo that overlaps with
-  // [Info.LowerBound;Info.UpperBound], or, std::nullopt if there is no overlap
-  LLVM_ABI std::optional<const RangeInfo *>
-  getOverlapping(const RangeInfo &Info) const;
-
-  // Return the mapped RangeInfo at X or nullptr if no mapping exists
-  LLVM_ABI const RangeInfo *lookup(uint32_t X) const;
-
-  // Removes all entries of the ResourceRange
-  LLVM_ABI void clear();
-
-  // Insert the required (sub-)intervals such that the interval of [a;b] =
-  // [Info.LowerBound, Info.UpperBound] is covered and points to a valid
-  // RangeInfo &.
-  //
-  // For instance consider the following chain of inserting RangeInfos with the
-  // intervals denoting the Lower/Upper-bounds:
-  //
-  // A = [0;2]
-  //   insert(A) -> false
-  //   intervals: [0;2] -> &A
-  // B = [5;7]
-  //   insert(B) -> false
-  //   intervals: [0;2] -> &A, [5;7] -> &B
-  // C = [4;7]
-  //   insert(C) -> true
-  //   intervals: [0;2] -> &A, [4;7] -> &C
-  // D = [1;5]
-  //   insert(D) -> true
-  //   intervals: [0;2] -> &A, [3;3] -> &D, [4;7] -> &C
-  // E = [0;unbounded]
-  //   insert(E) -> true
-  //   intervals: [0;unbounded] -> E
-  //
-  // Returns a reference to the first RangeInfo that overlaps with
-  // [Info.LowerBound;Info.UpperBound], or, std::nullopt if there is no overlap
-  // (equivalent to getOverlapping)
-  LLVM_ABI std::optional<const RangeInfo *> insert(const RangeInfo &Info);
-};
-
-struct OverlappingRanges {
-  const RangeInfo *A;
-  const RangeInfo *B;
-
-  OverlappingRanges(const RangeInfo *A, const RangeInfo *B) : A(A), B(B) {}
-};
-
-/// The following conducts analysis on resource ranges to detect and report
-/// any overlaps in resource ranges.
-///
-/// A resource range overlaps with another resource range if they have:
-/// - equivalent ResourceClass (SRV, UAV, CBuffer, Sampler)
-/// - equivalent resource space
-/// - overlapping visbility
-///
-/// The algorithm is implemented in the following steps:
-///
-/// 1. The user will collect RangeInfo from relevant RootElements:
-///   - RangeInfo will retain the interval, ResourceClass, Space and Visibility
-///   - It will also contain an index so that it can be associated to
-/// additional diagnostic information
-/// 2. Sort the RangeInfo's such that they are grouped together by
-///  ResourceClass and Space
-/// 3. Iterate through the collected RangeInfos by their groups
-///   - For each group we will have a ResourceRange for each visibility
-///   - As we iterate through we will:
-///      A: Insert the current RangeInfo into the corresponding Visibility
-///   ResourceRange
-///      B: Check for overlap with any overlapping Visibility ResourceRange
-LLVM_ABI llvm::SmallVector<OverlappingRanges>
-findOverlappingRanges(ArrayRef<RangeInfo> Infos);
+LLVM_ABI bool verifyRootFlag(uint32_t Flags);
+LLVM_ABI bool verifyVersion(uint32_t Version);
+LLVM_ABI bool verifyRegisterValue(uint32_t RegisterValue);
+LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace);
+LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
+LLVM_ABI bool verifyRangeType(uint32_t Type);
+LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
+                                        uint32_t FlagsVal);
+LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors);
+LLVM_ABI bool verifySamplerFilter(uint32_t Value);
+LLVM_ABI bool verifyAddress(uint32_t Address);
+LLVM_ABI bool verifyMipLODBias(float MipLODBias);
+LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
+LLVM_ABI bool verifyComparisonFunc(uint32_t ComparisonFunc);
+LLVM_ABI bool verifyBorderColor(uint32_t BorderColor);
+LLVM_ABI bool verifyLOD(float LOD);
 
 } // namespace rootsig
 } // namespace hlsl
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index a931b1d54b65c..3c7c886e79fc3 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -5,6 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+
 #ifndef LLVM_MC_DXCONTAINERROOTSIGNATURE_H
 #define LLVM_MC_DXCONTAINERROOTSIGNATURE_H
 
@@ -119,4 +120,5 @@ struct RootSignatureDesc {
 };
 } // namespace mcdxbc
 } // namespace llvm
+
 #endif // LLVM_MC_DXCONTAINERROOTSIGNATURE_H
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 9c3eba83eba7c..c8866bfefdfc5 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -300,6 +300,7 @@ class DXILPrepareModule : public ModulePass {
   DXILPrepareModule() : ModulePass(ID) {}
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<RootSignatureAnalysisWrapper>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index eb9ff5ab405e4..a4f5086c2f428 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -29,8 +29,6 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
-#include <optional>
-#include <utility>
 
 using namespace llvm;
 using namespace llvm::dxil;
@@ -235,7 +233,7 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
 
 void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
 }
 
 char RootSignatureAnalysisWrapper::ID = 0;
@@ -243,7 +241,6 @@ char RootSignatureAnalysisWrapper::ID = 0;
 INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper,
                       "dxil-root-signature-analysis",
                       "DXIL Root Signature Analysis", true, true)
-INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
 INITIALIZE_PASS_END(RootSignatureAnalysisWrapper,
                     "dxil-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 ccffa3fd0a3e2..254b7ff504633 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -26,16 +26,6 @@
 namespace llvm {
 namespace dxil {
 
-enum class RootSignatureElementKind {
-  Error = 0,
-  RootFlags = 1,
-  RootConstants = 2,
-  SRV = 3,
-  UAV = 4,
-  CBV = 5,
-  DescriptorTable = 6,
-};
-
 class RootSignatureBindingInfo {
 private:
   SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> FuncToRsMap;
@@ -106,4 +96,4 @@ class RootSignatureAnalysisPrinter
 
 } // namespace dxil
 } // namespace llvm
-#endif // LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H
+#endif
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
index 5def38af0fbeb..47d2a5b8d5aab 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
@@ -12,4 +12,4 @@ entry:
 !1 = !{!2, !3}
 !2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
 !3 = !{!"DescriptorTable", i32 0, !4}
-!4 = !{!"CBV", i32 3, i32 0, i32 0, i32 -1, i32 4}
\ No newline at end of file
+!4 = !{!"CBV", i32 3, i32 0, i32 0, i32 -1, i32 4}

>From f5b5b3e86938b441218fa75a560eb030b04118d3 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 18:17:55 -0700
Subject: [PATCH 43/68] clean

---
 .../DXILPostOptimizationValidation.cpp        | 24 +++++++++----------
 llvm/lib/Target/DirectX/DXILPrepare.cpp       |  1 +
 llvm/lib/Target/DirectX/DXILRootSignature.cpp |  3 +--
 llvm/lib/Target/DirectX/DXILRootSignature.h   |  2 +-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 6e0913a838912..cef6c8381a88b 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -154,18 +154,6 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
-std::optional<mcdxbc::RootSignatureDesc>
-getRootSignature(RootSignatureBindingInfo &RSBI,
-                 dxil::ModuleMetadataInfo &MMI) {
-  if (MMI.EntryPropertyVec.size() == 0)
-    return std::nullopt;
-  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
-      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
-  if (!RootSigDesc)
-    return std::nullopt;
-  return RootSigDesc;
-}
-
 static void reportOverlappingRegisters(
     Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &Reported,
     const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping) {
@@ -238,6 +226,18 @@ static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
   }
 }
 
+std::optional<mcdxbc::RootSignatureDesc>
+getRootSignature(RootSignatureBindingInfo &RSBI,
+                 dxil::ModuleMetadataInfo &MMI) {
+  if (MMI.EntryPropertyVec.size() == 0)
+    return std::nullopt;
+  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
+      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
+  if (!RootSigDesc)
+    return std::nullopt;
+  return RootSigDesc;
+}
+
 static void reportErrors(Module &M, DXILResourceMap &DRM,
                          DXILResourceBindingInfo &DRBI,
                          RootSignatureBindingInfo &RSBI,
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 9c3eba83eba7c..c8866bfefdfc5 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -300,6 +300,7 @@ class DXILPrepareModule : public ModulePass {
   DXILPrepareModule() : ModulePass(ID) {}
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+    AU.addRequired<RootSignatureAnalysisWrapper>();
     AU.addPreserved<RootSignatureAnalysisWrapper>();
     AU.addPreserved<ShaderFlagsAnalysisWrapper>();
     AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index a0c64fbb752c7..a4f5086c2f428 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -233,7 +233,7 @@ bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {
 
 void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
 }
 
 char RootSignatureAnalysisWrapper::ID = 0;
@@ -241,7 +241,6 @@ char RootSignatureAnalysisWrapper::ID = 0;
 INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper,
                       "dxil-root-signature-analysis",
                       "DXIL Root Signature Analysis", true, true)
-INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
 INITIALIZE_PASS_END(RootSignatureAnalysisWrapper,
                     "dxil-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 4b6c6eb3726e5..254b7ff504633 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -96,4 +96,4 @@ class RootSignatureAnalysisPrinter
 
 } // namespace dxil
 } // namespace llvm
-#endif // LLVM_LIB_TARGET_DIRECTX_DXILROOTSIGNATURE_H
+#endif

>From 03d571a01c27f6dedb689544d379b2a6cf05c6c3 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 18:26:53 -0700
Subject: [PATCH 44/68] clean?

---
 .../DXILPostOptimizationValidation.cpp        | 30 +++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index cef6c8381a88b..3ed9ef8979a2f 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -114,6 +114,21 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
+static void reportOverlappingRegisters(
+    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &Reported,
+    const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping) {
+  SmallString<128> Message;
+  raw_svector_ostream OS(Message);
+  OS << "register " << getResourceClassName(Reported.RC)
+     << " (space=" << Reported.Space << ", register=" << Reported.LowerBound
+     << ")" << " is overlapping with" << " register "
+     << getResourceClassName(Overlaping.RC) << " (space=" << Overlaping.Space
+     << ", register=" << Overlaping.LowerBound << ")"
+     << ", verify your root signature definition.";
+
+  M.getContext().diagnose(DiagnosticInfoGeneric(Message));
+}
+
 static void
 reportRegNotBound(Module &M, ResourceClass Class,
                   llvm::dxil::ResourceInfo::ResourceBinding Unbound) {
@@ -154,21 +169,6 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
-static void reportOverlappingRegisters(
-    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &Reported,
-    const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping) {
-  SmallString<128> Message;
-  raw_svector_ostream OS(Message);
-  OS << "register " << getResourceClassName(Reported.RC)
-     << " (space=" << Reported.Space << ", register=" << Reported.LowerBound
-     << ")" << " is overlapping with" << " register "
-     << getResourceClassName(Overlaping.RC) << " (space=" << Overlaping.Space
-     << ", register=" << Overlaping.LowerBound << ")"
-     << ", verify your root signature definition.";
-
-  M.getContext().diagnose(DiagnosticInfoGeneric(Message));
-}
-
 static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
                                     const mcdxbc::RootSignatureDesc &RSD,
                                     dxbc::ShaderVisibility Visibility) {

>From ef51048d94229dbec1764a4defd513ee9928375d Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 5 Aug 2025 19:54:27 -0700
Subject: [PATCH 45/68] format

---
 .../DirectX/DXILPostOptimizationValidation.cpp       | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 3ed9ef8979a2f..69916dfd9f509 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -258,9 +258,10 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
     trackRootSigDescBinding(Builder, *RSD, Visibility);
     bool HasOverlap = false;
     hlsl::BindingInfo Info = Builder.calculateBindingInfo(
-        [&M, &HasOverlap](const llvm::hlsl::BindingInfoBuilder &Builder,
-             const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
-              HasOverlap = true;
+        [&M, &HasOverlap](
+            const llvm::hlsl::BindingInfoBuilder &Builder,
+            const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
+          HasOverlap = true;
           const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
               Builder.findOverlapping(ReportedBinding);
           reportOverlappingRegisters(M, ReportedBinding, Overlaping);
@@ -268,12 +269,13 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
     // Next checks require that the root signature definition is valid.
     if (!HasOverlap){
       for (const auto &ResList :
-          {std::make_pair(ResourceClass::SRV, DRM.srvs()),
+           {std::make_pair(ResourceClass::SRV, DRM.srvs()),
             std::make_pair(ResourceClass::UAV, DRM.uavs()),
             std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
             std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
         for (auto Res : ResList.second) {
-          llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
+          llvm::dxil::ResourceInfo::ResourceBinding ResBinding =
+              Res.getBinding();
           llvm::hlsl::BindingInfo::BindingRange ResRange(
               ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
 

>From 21675e61731acf7b204a117b89fb7e3a973f5277 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Wed, 6 Aug 2025 11:06:55 -0700
Subject: [PATCH 46/68] formating

---
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 69916dfd9f509..09e7d9a90de00 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -267,7 +267,7 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
           reportOverlappingRegisters(M, ReportedBinding, Overlaping);
         });
     // Next checks require that the root signature definition is valid.
-    if (!HasOverlap){
+    if (!HasOverlap) {
       for (const auto &ResList :
            {std::make_pair(ResourceClass::SRV, DRM.srvs()),
             std::make_pair(ResourceClass::UAV, DRM.uavs()),

>From 403972dbde579a83de8c6a2b7ec2468be2c2b202 Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Thu, 7 Aug 2025 15:07:56 -0700
Subject: [PATCH 47/68] addressing comments from bogner and inbelic

---
 llvm/include/llvm/Analysis/DXILResource.h     |  15 --
 llvm/include/llvm/Support/DXILABI.h           |   3 +
 llvm/lib/Support/DXILABI.cpp                  |  19 +++
 llvm/lib/Target/DirectX/DXILOpLowering.cpp    |   1 +
 .../DXILPostOptimizationValidation.cpp        | 135 ++++++++----------
 llvm/lib/Target/DirectX/DXILRootSignature.h   |   8 +-
 ...e-validation-fail-root-descriptor-range.ll |   3 +-
 7 files changed, 90 insertions(+), 94 deletions(-)
 create mode 100644 llvm/lib/Support/DXILABI.cpp

diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 96d631698af0a..557fc513c2a57 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -32,21 +32,6 @@ class Value;
 class DXILResourceTypeMap;
 
 namespace dxil {
-
-inline StringRef getResourceClassName(ResourceClass RC) {
-  switch (RC) {
-  case ResourceClass::SRV:
-    return "SRV";
-  case ResourceClass::UAV:
-    return "UAV";
-  case ResourceClass::CBuffer:
-    return "CBuffer";
-  case ResourceClass::Sampler:
-    return "Sampler";
-  }
-  llvm_unreachable("Unhandled ResourceClass");
-}
-
 // Returns the resource name from dx_resource_handlefrombinding or
 // dx_resource_handlefromimplicitbinding call
 LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI);
diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h
index b479f7c73eba3..397906a3466c5 100644
--- a/llvm/include/llvm/Support/DXILABI.h
+++ b/llvm/include/llvm/Support/DXILABI.h
@@ -17,6 +17,7 @@
 #ifndef LLVM_SUPPORT_DXILABI_H
 #define LLVM_SUPPORT_DXILABI_H
 
+#include "llvm/ADT/StringRef.h"
 #include <cstdint>
 
 namespace llvm {
@@ -99,6 +100,8 @@ enum class SamplerFeedbackType : uint32_t {
 const unsigned MinWaveSize = 4;
 const unsigned MaxWaveSize = 128;
 
+StringRef getResourceClassName(ResourceClass RC);
+
 } // namespace dxil
 } // namespace llvm
 
diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
new file mode 100644
index 0000000000000..510e15b403ab1
--- /dev/null
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -0,0 +1,19 @@
+
+#include "llvm/Support/DXILABI.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+StringRef getResourceClassName(dxil::ResourceClass RC) {
+  switch (RC) {
+  case dxil::ResourceClass::SRV:
+    return "SRV";
+  case dxil::ResourceClass::UAV:
+    return "UAV";
+  case dxil::ResourceClass::CBuffer:
+    return "CBuffer";
+  case dxil::ResourceClass::Sampler:
+    return "Sampler";
+  }
+  llvm_unreachable("Unhandled ResourceClass");
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index db7719e129ad0..1cfba523183c8 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -919,6 +919,7 @@ PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &MAM) {
   PA.preserve<DXILResourceAnalysis>();
   PA.preserve<DXILMetadataAnalysis>();
   PA.preserve<ShaderFlagsAnalysis>();
+  PA.preserve<RootSignatureAnalysisWrapper>();
   return PA;
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 3da4cfbea23b8..368c8c6b5dbba 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -13,21 +13,22 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include <cstdint>
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 
 using namespace llvm;
 using namespace llvm::dxil;
 
-namespace {
-static ResourceClass RangeToResourceClass(uint32_t RangeType) {
+static ResourceClass toResourceClass(dxbc::DescriptorRangeType RangeType) {
   using namespace dxbc;
-  switch (static_cast<DescriptorRangeType>(RangeType)) {
+  switch (RangeType) {
   case DescriptorRangeType::SRV:
     return ResourceClass::SRV;
   case DescriptorRangeType::UAV:
@@ -39,20 +40,21 @@ static ResourceClass RangeToResourceClass(uint32_t RangeType) {
   }
 }
 
-ResourceClass ParameterToResourceClass(uint32_t Type) {
+static ResourceClass toResourceClass(dxbc::RootParameterType Type) {
   using namespace dxbc;
   switch (Type) {
-  case llvm::to_underlying(RootParameterType::Constants32Bit):
+  case RootParameterType::Constants32Bit:
     return ResourceClass::CBuffer;
-  case llvm::to_underlying(RootParameterType::SRV):
+  case RootParameterType::SRV:
     return ResourceClass::SRV;
-  case llvm::to_underlying(RootParameterType::UAV):
+  case RootParameterType::UAV:
     return ResourceClass::UAV;
-  case llvm::to_underlying(RootParameterType::CBV):
+  case RootParameterType::CBV:
     return ResourceClass::CBuffer;
-  default:
-    llvm_unreachable("Unknown RootParameterType");
+  case dxbc::RootParameterType::DescriptorTable:
+    break;
   }
+  llvm_unreachable("Unconvertible RootParameterType");
 }
 
 static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
@@ -131,12 +133,6 @@ static void reportOverlappingRegisters(
 
 static dxbc::ShaderVisibility
 tripleToVisibility(llvm::Triple::EnvironmentType ET) {
-  assert((ET == Triple::Pixel || ET == Triple::Vertex ||
-          ET == Triple::Geometry || ET == Triple::Hull ||
-          ET == Triple::Domain || ET == Triple::Mesh ||
-          ET == Triple::Compute) &&
-         "Invalid Triple to shader stage conversion");
-
   switch (ET) {
   case Triple::Pixel:
     return dxbc::ShaderVisibility::Pixel;
@@ -157,73 +153,80 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
   }
 }
 
-static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
-                                    const mcdxbc::RootSignatureDesc &RSD,
-                                    dxbc::ShaderVisibility Visibility) {
-  for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
-    const auto &[Type, Loc] =
-        RSD.ParametersContainer.getTypeAndLocForParameter(I);
-
-    const auto &Header = RSD.ParametersContainer.getHeader(I);
-    if (Header.ShaderVisibility !=
-            llvm::to_underlying(dxbc::ShaderVisibility::All) &&
-        Header.ShaderVisibility != llvm::to_underlying(Visibility))
-      continue;
+static void validateRootSignature(Module &M,
+                                  const mcdxbc::RootSignatureDesc &RSD,
+                                  dxil::ModuleMetadataInfo &MMI) {
 
-    switch (Type) {
-    case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
+  hlsl::BindingInfoBuilder Builder;
+  dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
+
+  for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) {
+    dxbc::ShaderVisibility ParamVisibility =
+        static_cast<dxbc::ShaderVisibility>(ParamInfo.Header.ShaderVisibility);
+    if (ParamVisibility != dxbc::ShaderVisibility::All &&
+        ParamVisibility != Visibility)
+      continue;
+    dxbc::RootParameterType ParamType =
+        static_cast<dxbc::RootParameterType>(ParamInfo.Header.ParameterType);
+    switch (ParamType) {
+    case dxbc::RootParameterType::Constants32Bit: {
       dxbc::RTS0::v1::RootConstants Const =
-          RSD.ParametersContainer.getConstant(Loc);
+          RSD.ParametersContainer.getConstant(ParamInfo.Location);
       Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
-                           Const.ShaderRegister,
-                           Const.ShaderRegister + Const.Num32BitValues, &Const);
+                           Const.ShaderRegister, Const.ShaderRegister, nullptr);
       break;
     }
 
-    case llvm::to_underlying(dxbc::RootParameterType::SRV):
-    case llvm::to_underlying(dxbc::RootParameterType::UAV):
-    case llvm::to_underlying(dxbc::RootParameterType::CBV): {
+    case dxbc::RootParameterType::SRV:
+    case dxbc::RootParameterType::UAV:
+    case dxbc::RootParameterType::CBV: {
       dxbc::RTS0::v2::RootDescriptor Desc =
-          RSD.ParametersContainer.getRootDescriptor(Loc);
-      Builder.trackBinding(ParameterToResourceClass(Type), Desc.RegisterSpace,
-                           Desc.ShaderRegister, Desc.ShaderRegister, &Desc);
+          RSD.ParametersContainer.getRootDescriptor(ParamInfo.Location);
+      Builder.trackBinding(toResourceClass(static_cast<dxbc::RootParameterType>(
+                               ParamInfo.Header.ParameterType)),
+                           Desc.RegisterSpace, Desc.ShaderRegister,
+                           Desc.ShaderRegister, nullptr);
 
       break;
     }
-    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+    case dxbc::RootParameterType::DescriptorTable: {
       const mcdxbc::DescriptorTable &Table =
-          RSD.ParametersContainer.getDescriptorTable(Loc);
+          RSD.ParametersContainer.getDescriptorTable(ParamInfo.Location);
 
       for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
-        Builder.trackBinding(RangeToResourceClass(Range.RangeType),
-                             Range.RegisterSpace, Range.BaseShaderRegister,
-                             Range.NumDescriptors == ~0U
-                                 ? Range.NumDescriptors
-                                 : Range.BaseShaderRegister +
-                                       Range.NumDescriptors,
-                             &Range);
+        uint32_t UpperBound =
+            Range.NumDescriptors == ~0U
+                ? Range.BaseShaderRegister
+                : Range.BaseShaderRegister + Range.NumDescriptors - 1;
+        Builder.trackBinding(
+            toResourceClass(
+                static_cast<dxbc::DescriptorRangeType>(Range.RangeType)),
+            Range.RegisterSpace, Range.BaseShaderRegister, UpperBound, nullptr);
       }
       break;
     }
     }
   }
 
-  for (auto &S : RSD.StaticSamplers) {
+  for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers)
     Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
-                         S.ShaderRegister, S.ShaderRegister, &S);
-  }
+                         S.ShaderRegister, S.ShaderRegister, nullptr);
+
+  hlsl::BindingInfo Info = Builder.calculateBindingInfo(
+      [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
+           const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
+        const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
+            Builder.findOverlapping(ReportedBinding);
+        reportOverlappingRegisters(M, ReportedBinding, Overlaping);
+      });
 }
 
-std::optional<mcdxbc::RootSignatureDesc>
+static mcdxbc::RootSignatureDesc *
 getRootSignature(RootSignatureBindingInfo &RSBI,
                  dxil::ModuleMetadataInfo &MMI) {
   if (MMI.EntryPropertyVec.size() == 0)
-    return std::nullopt;
-  std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
-      RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
-  if (!RootSigDesc)
-    return std::nullopt;
-  return RootSigDesc;
+    return nullptr;
+  return RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
 }
 
 static void reportErrors(Module &M, DXILResourceMap &DRM,
@@ -239,21 +242,9 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
   assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
                                        "DXILResourceImplicitBinding pass");
 
-  if (auto RSD = getRootSignature(RSBI, MMI)) {
-
-    hlsl::BindingInfoBuilder Builder;
-    dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
-    trackRootSigDescBinding(Builder, *RSD, Visibility);
-    hlsl::BindingInfo Info = Builder.calculateBindingInfo(
-        [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
-             const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
-          const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
-              Builder.findOverlapping(ReportedBinding);
-          reportOverlappingRegisters(M, ReportedBinding, Overlaping);
-        });
-  }
+  if (mcdxbc::RootSignatureDesc *RSD = getRootSignature(RSBI, MMI))
+    validateRootSignature(M, *RSD, MMI);
 }
-} // namespace
 
 PreservedAnalyses
 DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 254b7ff504633..b990b6c7410ac 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -43,13 +43,11 @@ class RootSignatureBindingInfo {
 
   iterator end() { return FuncToRsMap.end(); }
 
-  std::optional<mcdxbc::RootSignatureDesc>
-  getDescForFunction(const Function *F) {
+  mcdxbc::RootSignatureDesc *getDescForFunction(const Function *F) {
     const auto FuncRs = find(F);
     if (FuncRs == end())
-      return std::nullopt;
-
-    return FuncRs->second;
+      return nullptr;
+    return &FuncRs->second;
   }
 };
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
index 9f70cc3f062a9..38674d9ba0c6d 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
@@ -6,10 +6,9 @@ entry:
   ret void
 }
 
-; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), UAV(u3, space=1)
 !dx.rootsignatures = !{!0}
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !4}
 !2 = !{!"RootUAV", i32 0, i32 3, i32 1, i32 4}
 !4 = !{!"DescriptorTable", i32 0, !5}
-!5 = !{!"UAV", i32 3, i32 0, i32 1, i32 -1, i32 2}
+!5 = !{!"UAV", i32 4, i32 0, i32 1, i32 -1, i32 2}

>From 0f0435d6b43a0364c2a0dfc89bd94df57b6a6c99 Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Thu, 7 Aug 2025 15:16:14 -0700
Subject: [PATCH 48/68] clean up

---
 llvm/include/llvm/Analysis/DXILResource.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 557fc513c2a57..93c6bfb057ef5 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -32,6 +32,7 @@ class Value;
 class DXILResourceTypeMap;
 
 namespace dxil {
+
 // Returns the resource name from dx_resource_handlefrombinding or
 // dx_resource_handlefromimplicitbinding call
 LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI);

>From e841a98b1cefbcd92c4f3f9ed050dc33f07b0299 Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Thu, 7 Aug 2025 15:18:21 -0700
Subject: [PATCH 49/68] clean up

---
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 368c8c6b5dbba..80cbc9b6bee57 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -13,13 +13,11 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
-#include <cstdint>
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 

>From ae6d67a18553ab4d2608e46ccc0ca7c9edfba591 Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Thu, 7 Aug 2025 16:34:12 -0700
Subject: [PATCH 50/68] fix build

---
 llvm/lib/Analysis/DXILResource.cpp                         | 1 +
 llvm/lib/Support/CMakeLists.txt                            | 1 +
 llvm/lib/Support/DXILABI.cpp                               | 7 +++++--
 llvm/lib/Target/DirectX/DXContainerGlobals.cpp             | 3 +--
 llvm/lib/Target/DirectX/DXILOpLowering.cpp                 | 2 +-
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 1 +
 6 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index b476026fcc718..5aeee6f681114 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -20,6 +20,7 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/Support/DXILABI.h"
 #include "llvm/Support/FormatVariadic.h"
 #include <cstdint>
 #include <optional>
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 10b6101d73277..b7578dd580072 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -182,6 +182,7 @@ add_llvm_component_library(LLVMSupport
   DivisionByConstantInfo.cpp
   DAGDeltaAlgorithm.cpp
   DJB.cpp
+  DXILABI.cpp
   DynamicAPInt.cpp
   ELFAttributes.cpp
   ELFAttrParserCompact.cpp
diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index 510e15b403ab1..e45e86922cb39 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -3,7 +3,8 @@
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace llvm;
-
+namespace llvm {
+namespace dxil {
 StringRef getResourceClassName(dxil::ResourceClass RC) {
   switch (RC) {
   case dxil::ResourceClass::SRV:
@@ -16,4 +17,6 @@ StringRef getResourceClassName(dxil::ResourceClass RC) {
     return "Sampler";
   }
   llvm_unreachable("Unhandled ResourceClass");
-}
\ No newline at end of file
+}
+} // namespace dxil
+} // namespace llvm
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 26a113d2d5260..a1ef2578f00aa 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -162,8 +162,7 @@ void DXContainerGlobals::addRootSignature(Module &M,
 
   auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
   const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
-  const std::optional<mcdxbc::RootSignatureDesc> &RS =
-      RSA.getDescForFunction(EntryFunction);
+  const mcdxbc::RootSignatureDesc *RS = RSA.getDescForFunction(EntryFunction);
 
   if (!RS)
     return;
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 1cfba523183c8..247ba7d93b3c2 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -919,7 +919,7 @@ PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &MAM) {
   PA.preserve<DXILResourceAnalysis>();
   PA.preserve<DXILMetadataAnalysis>();
   PA.preserve<ShaderFlagsAnalysis>();
-  PA.preserve<RootSignatureAnalysisWrapper>();
+  PA.preserve<RootSignatureAnalysis>();
   return PA;
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 80cbc9b6bee57..cbb4307949f86 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -18,6 +18,7 @@
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/Support/DXILABI.h"
 
 #define DEBUG_TYPE "dxil-post-optimization-validation"
 

>From 41f32bd5ded0e14cfef0f2dd3ec8f5b9594d0f72 Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Fri, 8 Aug 2025 10:44:24 -0700
Subject: [PATCH 51/68] fix tests

---
 .../DirectX/DXILPostOptimizationValidation.cpp      | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index cbb4307949f86..7dc1ac0a5c0f2 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -158,7 +158,7 @@ static void validateRootSignature(Module &M,
 
   hlsl::BindingInfoBuilder Builder;
   dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
-
+  SmallVector<char> IDs;
   for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) {
     dxbc::ShaderVisibility ParamVisibility =
         static_cast<dxbc::ShaderVisibility>(ParamInfo.Header.ShaderVisibility);
@@ -172,7 +172,8 @@ static void validateRootSignature(Module &M,
       dxbc::RTS0::v1::RootConstants Const =
           RSD.ParametersContainer.getConstant(ParamInfo.Location);
       Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
-                           Const.ShaderRegister, Const.ShaderRegister, nullptr);
+                           Const.ShaderRegister, Const.ShaderRegister,
+                           &IDs.emplace_back());
       break;
     }
 
@@ -184,7 +185,7 @@ static void validateRootSignature(Module &M,
       Builder.trackBinding(toResourceClass(static_cast<dxbc::RootParameterType>(
                                ParamInfo.Header.ParameterType)),
                            Desc.RegisterSpace, Desc.ShaderRegister,
-                           Desc.ShaderRegister, nullptr);
+                           Desc.ShaderRegister, &IDs.emplace_back());
 
       break;
     }
@@ -200,7 +201,8 @@ static void validateRootSignature(Module &M,
         Builder.trackBinding(
             toResourceClass(
                 static_cast<dxbc::DescriptorRangeType>(Range.RangeType)),
-            Range.RegisterSpace, Range.BaseShaderRegister, UpperBound, nullptr);
+            Range.RegisterSpace, Range.BaseShaderRegister, UpperBound,
+            &IDs.emplace_back());
       }
       break;
     }
@@ -209,7 +211,8 @@ static void validateRootSignature(Module &M,
 
   for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers)
     Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
-                         S.ShaderRegister, S.ShaderRegister, nullptr);
+                         S.ShaderRegister, S.ShaderRegister,
+                         &IDs.emplace_back());
 
   hlsl::BindingInfo Info = Builder.calculateBindingInfo(
       [&M](const llvm::hlsl::BindingInfoBuilder &Builder,

>From 6da5fb01cf4b92c0a94b0629bdc65cd94c23827e Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Fri, 8 Aug 2025 11:46:50 -0700
Subject: [PATCH 52/68] format

---
 .../DXILPostOptimizationValidation.cpp        | 40 +++++++++----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 44eec17e87fb8..80054f3a516b7 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -228,31 +228,31 @@ static void validateRootSignature(Module &M,
                          &IDs.emplace_back());
   bool HasOverlap = false;
   hlsl::BindingInfo Info = Builder.calculateBindingInfo(
-      [&M, &HasOverlap](const llvm::hlsl::BindingInfoBuilder &Builder,
+      [&M, &HasOverlap](
+          const llvm::hlsl::BindingInfoBuilder &Builder,
           const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
-            HasOverlap = true;
-            const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
+        HasOverlap = true;
+        const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
             Builder.findOverlapping(ReportedBinding);
-            reportOverlappingRegisters(M, ReportedBinding, Overlaping);
+        reportOverlappingRegisters(M, ReportedBinding, Overlaping);
       });
-    // Next checks require that the root signature definition is valid.
-    if (!HasOverlap) {
-      for (const auto &ResList :
-           {std::make_pair(ResourceClass::SRV, DRM.srvs()),
-            std::make_pair(ResourceClass::UAV, DRM.uavs()),
-            std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
-            std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
-        for (auto Res : ResList.second) {
-          llvm::dxil::ResourceInfo::ResourceBinding ResBinding =
-              Res.getBinding();
-          llvm::hlsl::BindingInfo::BindingRange ResRange(
-              ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
-
-          if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
-            reportRegNotBound(M, ResList.first, ResBinding);
-        }
+  // Next checks require that the root signature definition is valid.
+  if (!HasOverlap) {
+    for (const auto &ResList :
+         {std::make_pair(ResourceClass::SRV, DRM.srvs()),
+          std::make_pair(ResourceClass::UAV, DRM.uavs()),
+          std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
+          std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
+      for (auto Res : ResList.second) {
+        llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
+        llvm::hlsl::BindingInfo::BindingRange ResRange(
+            ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
+
+        if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
+          reportRegNotBound(M, ResList.first, ResBinding);
       }
     }
+  }
 }
 
 static mcdxbc::RootSignatureDesc *

>From db73d716287c775686245455884327d734749ec2 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Fri, 8 Aug 2025 13:04:21 -0700
Subject: [PATCH 53/68] update

---
 llvm/lib/Support/DXILABI.cpp                       | 14 +++-----------
 .../rootsignature-validation-fail-cbuffer-range.ll |  2 +-
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index e45e86922cb39..3596a766b4388 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -1,22 +1,14 @@
 
 #include "llvm/Support/DXILABI.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ScopedPrinter.h"
 
 using namespace llvm;
 namespace llvm {
 namespace dxil {
 StringRef getResourceClassName(dxil::ResourceClass RC) {
-  switch (RC) {
-  case dxil::ResourceClass::SRV:
-    return "SRV";
-  case dxil::ResourceClass::UAV:
-    return "UAV";
-  case dxil::ResourceClass::CBuffer:
-    return "CBuffer";
-  case dxil::ResourceClass::Sampler:
-    return "Sampler";
-  }
-  llvm_unreachable("Unhandled ResourceClass");
+  return enumToStringRef(RC, dxbc::getResourceClasses());
 }
 } // namespace dxil
 } // namespace llvm
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
index 47d2a5b8d5aab..2f206702394a1 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CBuffer (space=0, register=2) is overlapping with register CBuffer (space=0, register=0), verify your root signature definition.
+; CHECK: error: register CBV (space=0, register=2) is overlapping with register CBV (space=0, register=0), verify your root signature definition.
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:

>From 3b04c2d0b534502ab876803f3a52fce9e8078497 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 12 Aug 2025 10:34:47 -0700
Subject: [PATCH 54/68] address comment from inbelic

---
 .../DirectX/DXILPostOptimizationValidation.cpp  | 17 ++++++++---------
 ...otsignature-validation-fail-cbuffer-range.ll |  2 +-
 ...re-validation-fail-descriptor-table-range.ll |  2 +-
 ...ure-validation-fail-root-descriptor-range.ll |  2 +-
 ...ture-validation-fail-static-sampler-range.ll |  2 +-
 5 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 7dc1ac0a5c0f2..c3e7c9930ee3a 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -116,17 +116,16 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
 }
 
 static void reportOverlappingRegisters(
-    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &Reported,
-    const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping) {
+    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &R1,
+    const llvm::hlsl::BindingInfoBuilder::Binding &R2) {
   SmallString<128> Message;
-  raw_svector_ostream OS(Message);
-  OS << "register " << getResourceClassName(Reported.RC)
-     << " (space=" << Reported.Space << ", register=" << Reported.LowerBound
-     << ")" << " is overlapping with" << " register "
-     << getResourceClassName(Overlaping.RC) << " (space=" << Overlaping.Space
-     << ", register=" << Overlaping.LowerBound << ")"
-     << ", verify your root signature definition.";
 
+  raw_svector_ostream OS(Message);
+  OS << "resource " << getResourceClassName(R1.RC) << " (space="<< R1.Space
+     << ", registers=[" << R1.LowerBound << ", "
+     << R1.UpperBound << "]) overlaps with resource " << getResourceClassName(R2.RC)
+     << " (space="<< R2.Space << ", registers=[" 
+     << R2.LowerBound << ", " << R2.UpperBound << "])";
   M.getContext().diagnose(DiagnosticInfoGeneric(Message));
 }
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
index 2f206702394a1..3d3f57d136845 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CBV (space=0, register=2) is overlapping with register CBV (space=0, register=0), verify your root signature definition.
+; CHECK: error: resource CBV (space=0, registers=[2, 2]) overlaps with resource CBV (space=0, registers=[0, 2])
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
index dbc75ac86db5f..1093aa3e38611 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register UAV (space=10, register=4294967295) is overlapping with register UAV (space=10, register=4294967295), verify your root signature definition.
+; CHECK: error: resource UAV (space=10, registers=[4294967295, 4294967295]) overlaps with resource UAV (space=10, registers=[4294967295, 4294967295])
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
   ret void
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
index 38674d9ba0c6d..4e6a3e7e49608 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register UAV (space=1, register=3) is overlapping with register UAV (space=1, register=0), verify your root signature definition.
+; CHECK: error: resource UAV (space=1, registers=[3, 3]) overlaps with resource UAV (space=1, registers=[0, 3])
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
index 340b0aed6d16b..66649f7ffc653 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
@@ -1,5 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register Sampler (space=0, register=42) is overlapping with register Sampler (space=0, register=42), verify your root signature definition.
+; CHECK: error: resource Sampler (space=0, registers=[42, 42]) overlaps with resource Sampler (space=0, registers=[42, 42])
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:

>From 1ddffc3c079ed5226ea5b1c3ea56887f108d3cd0 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 12 Aug 2025 10:44:09 -0700
Subject: [PATCH 55/68] address comments 2

---
 .../DirectX/DXILPostOptimizationValidation.cpp  | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index c3e7c9930ee3a..a4ecafd3b7041 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -115,17 +115,18 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
   }
 }
 
-static void reportOverlappingRegisters(
-    Module &M, const llvm::hlsl::BindingInfoBuilder::Binding &R1,
-    const llvm::hlsl::BindingInfoBuilder::Binding &R2) {
+static void
+reportOverlappingRegisters(Module &M,
+                           const llvm::hlsl::BindingInfoBuilder::Binding &R1,
+                           const llvm::hlsl::BindingInfoBuilder::Binding &R2) {
   SmallString<128> Message;
 
   raw_svector_ostream OS(Message);
-  OS << "resource " << getResourceClassName(R1.RC) << " (space="<< R1.Space
-     << ", registers=[" << R1.LowerBound << ", "
-     << R1.UpperBound << "]) overlaps with resource " << getResourceClassName(R2.RC)
-     << " (space="<< R2.Space << ", registers=[" 
-     << R2.LowerBound << ", " << R2.UpperBound << "])";
+  OS << "resource " << getResourceClassName(R1.RC) << " (space=" << R1.Space
+     << ", registers=[" << R1.LowerBound << ", " << R1.UpperBound
+     << "]) overlaps with resource " << getResourceClassName(R2.RC)
+     << " (space=" << R2.Space << ", registers=[" << R2.LowerBound << ", "
+     << R2.UpperBound << "])";
   M.getContext().diagnose(DiagnosticInfoGeneric(Message));
 }
 

>From db0008ec5a49f315bb85f411f189f117abf10eab Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 12 Aug 2025 14:39:47 -0700
Subject: [PATCH 56/68] addressing comments from inbelic

---
 .../DirectX/DXILPostOptimizationValidation.cpp       |  2 +-
 .../DirectX/rootsignature-validation-constants.ll    |  8 --------
 .../test/CodeGen/DirectX/rootsignature-validation.ll | 12 ------------
 3 files changed, 1 insertion(+), 21 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index a4ecafd3b7041..1bd7a438a4575 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -214,7 +214,7 @@ static void validateRootSignature(Module &M,
                          S.ShaderRegister, S.ShaderRegister,
                          &IDs.emplace_back());
 
-  hlsl::BindingInfo Info = Builder.calculateBindingInfo(
+  Builder.calculateBindingInfo(
       [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
            const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
         const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
index 3c33f1dc6bdf0..ab8c51629fa53 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
@@ -2,16 +2,8 @@
 ; expected-no-diagnostics
 ; Root Signature(RootConstants(num32BitConstants=4, b2))
 
-%__cblayout_CB = type <{ float }>
-
- at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
-
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
-; cbuffer CB : register(b2, space0) {
-;  float a;
-; }
-  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
   ret void
 }
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
index 750679bf743c5..67a57d05e65ee 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -8,21 +8,9 @@
 ;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
 ;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
 
-%__cblayout_CB = type <{ float }>
-
- at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
- at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
- at SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
- at RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
-
-  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
-  %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str)
-  %RWB =  tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str)
-
   ret void
 }
 

>From 0c72dcfcfea6b2bf3562fc94108b226ef52437e9 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 12 Aug 2025 15:25:57 -0700
Subject: [PATCH 57/68] addressing inbelic comments

---
 llvm/lib/Frontend/HLSL/HLSLBinding.cpp        | 10 ++++---
 .../DXILPostOptimizationValidation.cpp        | 26 +++++++++----------
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
index 57075ca430d44..f69a7ce37b403 100644
--- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp
@@ -67,9 +67,13 @@ BindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
 }
 
 bool BindingInfo::RegisterSpace::isBound(BindingRange B) {
-  for (BindingRange &R : FreeRanges) {
-    if (B.LowerBound >= R.LowerBound && B.LowerBound < R.UpperBound &&
-        B.UpperBound > R.LowerBound && B.UpperBound <= R.UpperBound)
+  BindingRange *It = llvm::lower_bound(
+      FreeRanges, B.LowerBound,
+      [](const BindingRange &R, uint32_t Val) { return R.UpperBound <= Val; });
+
+  if (It != FreeRanges.end()) {
+    // Check if B is fully contained in the found range
+    if (B.LowerBound >= It->LowerBound && B.UpperBound <= It->UpperBound)
       return false;
   }
   return true;
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 80054f3a516b7..2ad8628251ee6 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -237,20 +237,18 @@ static void validateRootSignature(Module &M,
         reportOverlappingRegisters(M, ReportedBinding, Overlaping);
       });
   // Next checks require that the root signature definition is valid.
-  if (!HasOverlap) {
-    for (const auto &ResList :
-         {std::make_pair(ResourceClass::SRV, DRM.srvs()),
-          std::make_pair(ResourceClass::UAV, DRM.uavs()),
-          std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
-          std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
-      for (auto Res : ResList.second) {
-        llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
-        llvm::hlsl::BindingInfo::BindingRange ResRange(
-            ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
-
-        if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
-          reportRegNotBound(M, ResList.first, ResBinding);
-      }
+  for (const auto &ResList :
+       {std::make_pair(ResourceClass::SRV, DRM.srvs()),
+        std::make_pair(ResourceClass::UAV, DRM.uavs()),
+        std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
+        std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
+    for (auto Res : ResList.second) {
+      llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding();
+      llvm::hlsl::BindingInfo::BindingRange ResRange(
+          ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
+
+      if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
+        reportRegNotBound(M, ResList.first, ResBinding);
     }
   }
 }

>From b4e5fb4e393cb3f4918821596e5186725e5c7205 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Tue, 12 Aug 2025 15:42:18 -0700
Subject: [PATCH 58/68] adding test

---
 .../rootsignature-validation-fail-sampler.ll       | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll

diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
new file mode 100644
index 0000000000000..a29c00fe0f2f4
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -0,0 +1,14 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: resource Sampler (space=0, registers=[42, 42]) overlaps with resource Sampler (space=0, registers=[42, 42])
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2, !3}
+!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
+!3 = !{!"DescriptorTable", i32 0, !4}
+!4 = !{!"Sampler", i32 1, i32 42, i32 0, i32 -1, i32 0}
\ No newline at end of file

>From 4a655a54ed2d6a9503f78e6ca11cd9bbf8e2ccb8 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Wed, 13 Aug 2025 10:50:52 -0700
Subject: [PATCH 59/68] addressing comments from bogner

---
 llvm/lib/Support/DXILABI.cpp                  | 23 ++++++++++++-------
 .../DXILPostOptimizationValidation.cpp        |  3 ++-
 ...-validation-fail-descriptor-table-range.ll |  2 +-
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index 3596a766b4388..8d60e1a1b3ba8 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -1,14 +1,21 @@
+//===-- DXILABI.cpp - ABI Sensitive Values for DXIL ---------------*- C++
+//-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements functions that can be reused accross different stages
+// dxil generation.
+//
+//===----------------------------------------------------------------------===//
 
-#include "llvm/Support/DXILABI.h"
 #include "llvm/BinaryFormat/DXContainer.h"
-#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ScopedPrinter.h"
-
 using namespace llvm;
-namespace llvm {
-namespace dxil {
-StringRef getResourceClassName(dxil::ResourceClass RC) {
+
+StringRef dxil::getResourceClassName(dxil::ResourceClass RC) {
   return enumToStringRef(RC, dxbc::getResourceClasses());
 }
-} // namespace dxil
-} // namespace llvm
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 1bd7a438a4575..3918dfd13e5e3 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -51,9 +51,10 @@ static ResourceClass toResourceClass(dxbc::RootParameterType Type) {
   case RootParameterType::CBV:
     return ResourceClass::CBuffer;
   case dxbc::RootParameterType::DescriptorTable:
+    llvm_unreachable("DescriptorTable is not convertible to ResourceClass");
     break;
   }
-  llvm_unreachable("Unconvertible RootParameterType");
+  llvm_unreachable("Unknown RootParameterType");
 }
 
 static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
index 1093aa3e38611..6ca53f8897225 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
@@ -5,7 +5,7 @@ entry:
   ret void
 }
 
-; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), DescriptorTable(UAV(u2, numDescriptors=4))
+; DescriptorTable(UAV(u0, numDescriptors=unbounded)), DescriptorTable(UAV(u2, numDescriptors=4))
 !dx.rootsignatures = !{!0}
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !4}

>From cc94561c9a98e64fe37c916073037546f718add2 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Wed, 13 Aug 2025 11:36:46 -0700
Subject: [PATCH 60/68] addressing comments

---
 llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 3918dfd13e5e3..095665683ed58 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -37,6 +37,7 @@ static ResourceClass toResourceClass(dxbc::DescriptorRangeType RangeType) {
   case DescriptorRangeType::Sampler:
     return ResourceClass::Sampler;
   }
+  llvm_unreachable("Unknown DescriptorRangeType");
 }
 
 static ResourceClass toResourceClass(dxbc::RootParameterType Type) {

>From 98f48d252fe210bdf1cdc52538ea4511b510d7e2 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Wed, 13 Aug 2025 13:24:35 -0700
Subject: [PATCH 61/68] address comments

---
 llvm/lib/Support/DXILABI.cpp                       |  3 +--
 .../DirectX/rootsignature-validation-constants.ll  | 14 --------------
 .../rootsignature-validation-fail-sampler.ll       |  2 +-
 .../CodeGen/DirectX/rootsignature-validation.ll    |  3 ++-
 4 files changed, 4 insertions(+), 18 deletions(-)
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll

diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index 8d60e1a1b3ba8..c6499b21613fb 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -1,5 +1,4 @@
-//===-- DXILABI.cpp - ABI Sensitive Values for DXIL ---------------*- C++
-//-*-===//
+//===-- DXILABI.cpp - ABI Sensitive Values for DXIL --------------*- C++-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
deleted file mode 100644
index ab8c51629fa53..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-constants.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
-; expected-no-diagnostics
-; Root Signature(RootConstants(num32BitConstants=4, b2))
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2}
-!2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index a29c00fe0f2f4..90f4c6f683e8b 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -11,4 +11,4 @@ entry:
 !1 = !{!2, !3}
 !2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
 !3 = !{!"DescriptorTable", i32 0, !4}
-!4 = !{!"Sampler", i32 1, i32 42, i32 0, i32 -1, i32 0}
\ No newline at end of file
+!4 = !{!"Sampler", i32 1, i32 42, i32 0, i32 -1, i32 0}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
index 67a57d05e65ee..42545886b6312 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -17,8 +17,9 @@ entry:
 !dx.rootsignatures = !{!0}
 
 !0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
+!1 = !{!2, !3, !5, !7, !9}
 !2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4}
+!9 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
 !3 = !{!"DescriptorTable", i32 0, !4}
 !4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0}
 !5 = !{!"DescriptorTable", i32 0, !6}

>From eb334b89ccc63e74244df707c9381924df79e914 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Wed, 13 Aug 2025 13:25:53 -0700
Subject: [PATCH 62/68] refactoring

---
 llvm/include/llvm/BinaryFormat/DXContainer.h     |  2 --
 llvm/include/llvm/Support/DXILABI.h              |  5 ++++-
 llvm/lib/BinaryFormat/DXContainer.cpp            | 11 -----------
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp     |  2 +-
 llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp |  4 ++--
 llvm/lib/Support/DXILABI.cpp                     | 13 ++++++++++++-
 6 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index cc4af3d9be8d7..f74c9775cb3f3 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -158,8 +158,6 @@ enum class FeatureFlags : uint64_t {
 static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
               "Shader flag bits exceed enum size.");
 
-LLVM_ABI ArrayRef<EnumEntry<llvm::dxil::ResourceClass>> getResourceClasses();
-
 #define ROOT_SIGNATURE_FLAG(Num, Val) Val = Num,
 enum class RootFlags : uint32_t {
 #include "DXContainerConstants.def"
diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h
index 397906a3466c5..dcd611eb3b7db 100644
--- a/llvm/include/llvm/Support/DXILABI.h
+++ b/llvm/include/llvm/Support/DXILABI.h
@@ -18,6 +18,7 @@
 #define LLVM_SUPPORT_DXILABI_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ScopedPrinter.h"
 #include <cstdint>
 
 namespace llvm {
@@ -100,7 +101,9 @@ enum class SamplerFeedbackType : uint32_t {
 const unsigned MinWaveSize = 4;
 const unsigned MaxWaveSize = 128;
 
-StringRef getResourceClassName(ResourceClass RC);
+LLVM_ABI ArrayRef<EnumEntry<llvm::dxil::ResourceClass>> getResourceClasses();
+
+LLVM_ABI StringRef getResourceClassName(ResourceClass RC);
 
 } // namespace dxil
 } // namespace llvm
diff --git a/llvm/lib/BinaryFormat/DXContainer.cpp b/llvm/lib/BinaryFormat/DXContainer.cpp
index eb83945c9c42f..36d10d0b63078 100644
--- a/llvm/lib/BinaryFormat/DXContainer.cpp
+++ b/llvm/lib/BinaryFormat/DXContainer.cpp
@@ -60,17 +60,6 @@ ArrayRef<EnumEntry<SigComponentType>> dxbc::getSigComponentTypes() {
   return ArrayRef(SigComponentTypes);
 }
 
-static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = {
-    {"SRV", llvm::dxil::ResourceClass::SRV},
-    {"UAV", llvm::dxil::ResourceClass::UAV},
-    {"CBV", llvm::dxil::ResourceClass::CBuffer},
-    {"Sampler", llvm::dxil::ResourceClass::Sampler},
-};
-
-ArrayRef<EnumEntry<llvm::dxil::ResourceClass>> dxbc::getResourceClasses() {
-  return ArrayRef(ResourceClassNames);
-}
-
 static const EnumEntry<RootFlags> RootFlagNames[] = {
 #define ROOT_SIGNATURE_FLAG(Val, Enum) {#Enum, RootFlags::Enum},
 #include "llvm/BinaryFormat/DXContainerConstants.def"
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 574883e0d7fd7..050cc46e8c9b0 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -94,7 +94,7 @@ static raw_ostream &operator<<(raw_ostream &OS,
 
 static raw_ostream &operator<<(raw_ostream &OS, const ClauseType &Type) {
   OS << enumToStringRef(dxil::ResourceClass(llvm::to_underlying(Type)),
-                        dxbc::getResourceClasses());
+                        dxil::getResourceClasses());
 
   return OS;
 }
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index 1cda3080442b2..157bfc665b207 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -121,7 +121,7 @@ MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) {
   IRBuilder<> Builder(Ctx);
   StringRef ResName =
       enumToStringRef(dxil::ResourceClass(to_underlying(Descriptor.Type)),
-                      dxbc::getResourceClasses());
+                      dxil::getResourceClasses());
   assert(!ResName.empty() && "Provided an invalid Resource Class");
   SmallString<7> Name({"Root", ResName});
   Metadata *Operands[] = {
@@ -163,7 +163,7 @@ MDNode *MetadataBuilder::BuildDescriptorTableClause(
   IRBuilder<> Builder(Ctx);
   StringRef ResName =
       enumToStringRef(dxil::ResourceClass(to_underlying(Clause.Type)),
-                      dxbc::getResourceClasses());
+                      dxil::getResourceClasses());
   assert(!ResName.empty() && "Provided an invalid Resource Class");
   Metadata *Operands[] = {
       MDString::get(Ctx, ResName),
diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index c6499b21613fb..892c910dbe97b 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -15,6 +15,17 @@
 #include "llvm/Support/ScopedPrinter.h"
 using namespace llvm;
 
+static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = {
+    {"SRV", llvm::dxil::ResourceClass::SRV},
+    {"UAV", llvm::dxil::ResourceClass::UAV},
+    {"CBV", llvm::dxil::ResourceClass::CBuffer},
+    {"Sampler", llvm::dxil::ResourceClass::Sampler},
+};
+
+ArrayRef<EnumEntry<llvm::dxil::ResourceClass>> dxil::getResourceClasses() {
+  return ArrayRef(ResourceClassNames);
+}
+
 StringRef dxil::getResourceClassName(dxil::ResourceClass RC) {
-  return enumToStringRef(RC, dxbc::getResourceClasses());
+  return enumToStringRef(RC, getResourceClasses());
 }

>From 06c0da45f95ae06499f2f1a5347737ba0dc9e14e Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 11:00:53 -0700
Subject: [PATCH 63/68] addressing comments

---
 llvm/lib/Support/DXILABI.cpp                         |  9 ++++++---
 .../DirectX/DXILPostOptimizationValidation.cpp       | 12 +++++-------
 .../test/CodeGen/DirectX/rootsignature-validation.ll |  2 +-
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index 892c910dbe97b..ae2f41b3944ce 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -1,4 +1,4 @@
-//===-- DXILABI.cpp - ABI Sensitive Values for DXIL --------------*- C++-*-===//
+//===-- DXILABI.cpp - ABI Sensitive Values for DXIL -----------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements functions that can be reused accross different stages
-// dxil generation.
+// This file contains definitions of various constants and enums that are
+// required to remain stable as per the DXIL format's requirements.
+//
+// Documentation for DXIL can be found in
+// https://github.com/Microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst.
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 095665683ed58..0e9e2253e2ec9 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -53,7 +53,6 @@ static ResourceClass toResourceClass(dxbc::RootParameterType Type) {
     return ResourceClass::CBuffer;
   case dxbc::RootParameterType::DescriptorTable:
     llvm_unreachable("DescriptorTable is not convertible to ResourceClass");
-    break;
   }
   llvm_unreachable("Unknown RootParameterType");
 }
@@ -160,7 +159,7 @@ static void validateRootSignature(Module &M,
 
   hlsl::BindingInfoBuilder Builder;
   dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
-  SmallVector<char> IDs;
+
   for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) {
     dxbc::ShaderVisibility ParamVisibility =
         static_cast<dxbc::ShaderVisibility>(ParamInfo.Header.ShaderVisibility);
@@ -175,7 +174,7 @@ static void validateRootSignature(Module &M,
           RSD.ParametersContainer.getConstant(ParamInfo.Location);
       Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
                            Const.ShaderRegister, Const.ShaderRegister,
-                           &IDs.emplace_back());
+                           &ParamInfo);
       break;
     }
 
@@ -187,7 +186,7 @@ static void validateRootSignature(Module &M,
       Builder.trackBinding(toResourceClass(static_cast<dxbc::RootParameterType>(
                                ParamInfo.Header.ParameterType)),
                            Desc.RegisterSpace, Desc.ShaderRegister,
-                           Desc.ShaderRegister, &IDs.emplace_back());
+                           Desc.ShaderRegister, &ParamInfo);
 
       break;
     }
@@ -204,7 +203,7 @@ static void validateRootSignature(Module &M,
             toResourceClass(
                 static_cast<dxbc::DescriptorRangeType>(Range.RangeType)),
             Range.RegisterSpace, Range.BaseShaderRegister, UpperBound,
-            &IDs.emplace_back());
+            &ParamInfo);
       }
       break;
     }
@@ -213,8 +212,7 @@ static void validateRootSignature(Module &M,
 
   for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers)
     Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
-                         S.ShaderRegister, S.ShaderRegister,
-                         &IDs.emplace_back());
+                         S.ShaderRegister, S.ShaderRegister, &S);
 
   Builder.calculateBindingInfo(
       [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
index 42545886b6312..1b88a56e8aa35 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 
+; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 
 ; expected-no-diagnostics
 
 

>From 74980c89759ebf9076ee3baec1d3e2530b9e5843 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 11:30:27 -0700
Subject: [PATCH 64/68] fix test

---
 llvm/test/Analysis/DXILResource/buffer-frombinding.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index 2623e6f4d44f1..d08b68d3768af 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -146,7 +146,7 @@ define void @test_typedbuffer() {
   ; CHECK:     Space: 1
   ; CHECK:     Lower Bound: 0
   ; CHECK:     Size: 1
-  ; CHECK:   Class: CBuffer
+  ; CHECK:   Class: CBV
   ; CHECK:   Kind: CBuffer
   ; CHECK:   CBuffer size: 4
 
@@ -159,7 +159,7 @@ define void @test_typedbuffer() {
   ; CHECK:     Space: 1
   ; CHECK:     Lower Bound: 8
   ; CHECK:     Size: 1
-  ; CHECK:   Class: CBuffer
+  ; CHECK:   Class: CBV
   ; CHECK:   Kind: CBuffer
   ; CHECK:   CBuffer size: 4
 

>From d376abf1843d07fdd4c7f91c8b5462ad55ca34aa Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 14:38:50 -0700
Subject: [PATCH 65/68] address comments

---
 llvm/include/llvm/Support/DXILABI.h                    |  2 +-
 llvm/lib/Support/DXILABI.cpp                           |  2 +-
 .../rootsignature-validation-fail-cbuffer-range.ll     |  2 +-
 ...signature-validation-fail-descriptor-table-range.ll |  3 ++-
 ...tsignature-validation-fail-root-descriptor-range.ll |  1 +
 .../DirectX/rootsignature-validation-fail-sampler.ll   |  1 +
 ...otsignature-validation-fail-static-sampler-range.ll |  1 +
 llvm/test/CodeGen/DirectX/rootsignature-validation.ll  | 10 +---------
 8 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h
index dcd611eb3b7db..2dcdd73415be2 100644
--- a/llvm/include/llvm/Support/DXILABI.h
+++ b/llvm/include/llvm/Support/DXILABI.h
@@ -101,7 +101,7 @@ enum class SamplerFeedbackType : uint32_t {
 const unsigned MinWaveSize = 4;
 const unsigned MaxWaveSize = 128;
 
-LLVM_ABI ArrayRef<EnumEntry<llvm::dxil::ResourceClass>> getResourceClasses();
+LLVM_ABI ArrayRef<EnumEntry<ResourceClass>> getResourceClasses();
 
 LLVM_ABI StringRef getResourceClassName(ResourceClass RC);
 
diff --git a/llvm/lib/Support/DXILABI.cpp b/llvm/lib/Support/DXILABI.cpp
index ae2f41b3944ce..261fe1ef98278 100644
--- a/llvm/lib/Support/DXILABI.cpp
+++ b/llvm/lib/Support/DXILABI.cpp
@@ -14,7 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Support/DXILABI.h"
 #include "llvm/Support/ScopedPrinter.h"
 using namespace llvm;
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
index 3d3f57d136845..e420225229919 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer-range.ll
@@ -6,8 +6,8 @@ entry:
   ret void
 }
 
-; RootConstants(num32BitConstants=4, b2), DescriptorTable(CBV(b0, numDescriptors=3))
 !dx.rootsignatures = !{!0}
+
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3}
 !2 = !{!"RootConstants", i32 0, i32 2, i32 0, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
index 6ca53f8897225..037f8c71f8ef0 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-descriptor-table-range.ll
@@ -1,12 +1,13 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 ; CHECK: error: resource UAV (space=10, registers=[4294967295, 4294967295]) overlaps with resource UAV (space=10, registers=[4294967295, 4294967295])
+
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
   ret void
 }
 
-; DescriptorTable(UAV(u0, numDescriptors=unbounded)), DescriptorTable(UAV(u2, numDescriptors=4))
 !dx.rootsignatures = !{!0}
+
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !4}
 !2 = !{!"DescriptorTable", i32 0, !3}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
index 4e6a3e7e49608..7098efbb43f6a 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll
@@ -7,6 +7,7 @@ entry:
 }
 
 !dx.rootsignatures = !{!0}
+
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !4}
 !2 = !{!"RootUAV", i32 0, i32 3, i32 1, i32 4}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index 90f4c6f683e8b..c244095520468 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -7,6 +7,7 @@ entry:
 }
 
 !dx.rootsignatures = !{!0}
+
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3}
 !2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
index 66649f7ffc653..9ac02ebbc0965 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll
@@ -7,6 +7,7 @@ entry:
 }
 
 !dx.rootsignatures = !{!0}
+
 !0 = !{ptr @CSMain, !1, i32 2}
 !1 = !{!2, !3}
 !2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 }
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
index 1b88a56e8aa35..0fdba27018cd4 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll
@@ -1,13 +1,5 @@
 ; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 
-; expected-no-diagnostics
-
-
-; Root Signature(
-;   CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
+; We have a valid root signature, this should compile successfully
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:

>From bb44eef7ebf6908997bf507e0a84666bea6af234 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 16:09:55 -0700
Subject: [PATCH 66/68] fix test

---
 .../rootsignature-validation-fail-cbuffer.ll  | 34 -------------------
 ...rootsignature-validation-fail-constants.ll |  6 +---
 2 files changed, 1 insertion(+), 39 deletions(-)
 delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll

diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
deleted file mode 100644
index e5133810c0f32..0000000000000
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbuffer.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
-; CHECK: error: register CBuffer (space=665, register=3) does not have a binding in the Root Signature
-
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
-%__cblayout_CB = type <{ float }>
-
- at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
-
-define void @CSMain() "hlsl.shader"="compute" {
-entry:
-; cbuffer CB : register(b3, space665) {
-;  float a;
-; }
-  %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 665, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
-  ret void
-}
-
-!dx.rootsignatures = !{!0}
-
-!0 = !{ptr @CSMain, !1, i32 2}
-!1 = !{!2, !3, !5, !7}
-!2 = !{!"RootCBV", i32 0, i32 3, i32 666, i32 4}
-!3 = !{!"DescriptorTable", i32 1, !4}
-!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4}
-!5 = !{!"DescriptorTable", i32 0, !6}
-!6 = !{!"Sampler", i32 2, i32 0, i32 0, i32 -1, i32 0}
-!7 = !{!"DescriptorTable", i32 0, !8}
-!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
index dc7657e79ec97..07dbeb9be81d0 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
@@ -1,6 +1,5 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-; CHECK: error: register CBuffer (space=666, register=2) does not have a binding in the Root Signature
-; Root Signature(RootConstants(num32BitConstants=4, b2))
+; CHECK: error: register CBV (space=666, register=2) does not have a binding in the Root Signature
 
 %__cblayout_CB = type <{ float }>
 
@@ -8,9 +7,6 @@
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
-; cbuffer CB : register(b2, space666) {
-;  float a;
-; }
   %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 666, i32 2, i32 1, i32 0, i1 false, ptr nonnull @CB.str)
   ret void
 }

>From 373d871f6a2faab8b724e816b899ece63845464f Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 16:48:57 -0700
Subject: [PATCH 67/68] clean up

---
 .../DirectX/DXILPostOptimizationValidation.cpp |  1 -
 ...otsignature-validation-fail-cbv-binding.ll} |  0
 ...ignature-validation-fail-sampler-binding.ll | 18 ++++++++++++++++++
 .../rootsignature-validation-fail-sampler.ll   |  3 ---
 ...otsignature-validation-fail-srv-binding.ll} |  7 -------
 ...otsignature-validation-fail-uav-binding.ll} |  7 -------
 6 files changed, 18 insertions(+), 18 deletions(-)
 rename llvm/test/CodeGen/DirectX/{rootsignature-validation-fail-constants.ll => rootsignature-validation-fail-cbv-binding.ll} (100%)
 create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler-binding.ll
 rename llvm/test/CodeGen/DirectX/{rootsignature-validation-fail-srv.ll => rootsignature-validation-fail-srv-binding.ll} (74%)
 rename llvm/test/CodeGen/DirectX/{rootsignature-validation-fail-uav.ll => rootsignature-validation-fail-uav-binding.ll} (74%)

diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
index 95918cb035304..bbdf7098222b2 100644
--- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
+++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
@@ -13,7 +13,6 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/DXILMetadataAnalysis.h"
 #include "llvm/Analysis/DXILResource.h"
-#include "llvm/Frontend/HLSL/HLSLBinding.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsDirectX.h"
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbv-binding.ll
similarity index 100%
rename from llvm/test/CodeGen/DirectX/rootsignature-validation-fail-constants.ll
rename to llvm/test/CodeGen/DirectX/rootsignature-validation-fail-cbv-binding.ll
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler-binding.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler-binding.ll
new file mode 100644
index 0000000000000..4dc21448e2796
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler-binding.ll
@@ -0,0 +1,18 @@
+; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
+; CHECK: error: register Sampler (space=2, register=3) does not have a binding in the Root Signature 
+
+ at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
+
+
+define void @CSMain() "hlsl.shader"="compute" {
+entry:
+  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
+  ret void
+}
+
+!dx.rootsignatures = !{!0}
+
+!0 = !{ptr @CSMain, !1, i32 2}
+!1 = !{!2}
+!2 = !{!"DescriptorTable", i32 0, !3}
+!3 = !{!"Sampler", i32 1, i32 42, i32 0, i32 -1, i32 0}
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index a218c55fb5745..968ab1d699574 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -1,12 +1,9 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 ; CHECK: error: resource Sampler (space=0, registers=[42, 42]) overlaps with resource Sampler (space=0, registers=[42, 42])
 
- at Smp.str = private unnamed_addr constant [4 x i8] c"Smp\00", align 1
-
 
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
-  %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str)
   ret void
 }
 
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv-binding.ll
similarity index 74%
rename from llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
rename to llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv-binding.ll
index ebefa7b1a3d85..c851550556024 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-srv-binding.ll
@@ -1,13 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
 ; CHECK: error: register SRV (space=0, register=0) does not have a binding in the Root Signature
 
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
 @SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1
 
 define void @CSMain() "hlsl.shader"="compute" {
diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav-binding.ll
similarity index 74%
rename from llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
rename to llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav-binding.ll
index 9cc5b6744a4a2..523999348ae10 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-uav-binding.ll
@@ -1,13 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
-
 ; CHECK: error: register UAV (space=0, register=4294967294) does not have a binding in the Root Signature
 
-; Root Signature(
-;   CBV(b3, space=666, visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_VERTEX)
-;   DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)
-;   DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL)
-
 @RWB.str = private unnamed_addr constant [4 x i8] c"RWB\00", align 1
 
 define void @CSMain() "hlsl.shader"="compute" {

>From d2750d7b2771ec100893dd27df46d636c503fe98 Mon Sep 17 00:00:00 2001
From: Joao Saffran <{ID}+{username}@users.noreply.github.com>
Date: Thu, 14 Aug 2025 16:50:16 -0700
Subject: [PATCH 68/68] format

---
 .../CodeGen/DirectX/rootsignature-validation-fail-sampler.ll     | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
index 968ab1d699574..c244095520468 100644
--- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
+++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll
@@ -1,7 +1,6 @@
 ; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s
 ; CHECK: error: resource Sampler (space=0, registers=[42, 42]) overlaps with resource Sampler (space=0, registers=[42, 42])
 
-
 define void @CSMain() "hlsl.shader"="compute" {
 entry:
   ret void



More information about the cfe-commits mailing list