[llvm-branch-commits] [clang] [llvm] [DirectX] Validate registers are bound to root signature (PR #146785)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 5 19:54:58 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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 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 38/40] 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 39/40] 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 40/40] 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);
More information about the llvm-branch-commits
mailing list