[llvm-branch-commits] [llvm] [HLSL] Adding support for Root Constants in LLVM Metadata (PR #135085)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Apr 9 14:23:14 PDT 2025
https://github.com/joaosaffran created https://github.com/llvm/llvm-project/pull/135085
- Closes [#126637](https://github.com/llvm/llvm-project/issues/126637)
>From 9b59d0108f6b23c039e2c417247216862073cd4b Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 9 Apr 2025 21:05:58 +0000
Subject: [PATCH 1/2] adding support for root constants in metadata generation
---
llvm/lib/Target/DirectX/DXILRootSignature.cpp | 120 +++++++++++++++++-
llvm/lib/Target/DirectX/DXILRootSignature.h | 6 +-
.../RootSignature-Flags-Validation-Error.ll | 7 +-
.../RootSignature-RootConstants.ll | 34 +++++
...ature-ShaderVisibility-Validation-Error.ll | 20 +++
5 files changed, 182 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootConstants.ll
create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-ShaderVisibility-Validation-Error.ll
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 412ab7765a7ae..7686918b0fc75 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -40,6 +40,13 @@ static bool reportError(LLVMContext *Ctx, Twine Message,
return true;
}
+static bool reportValueError(LLVMContext *Ctx, Twine ParamName, uint32_t Value,
+ DiagnosticSeverity Severity = DS_Error) {
+ Ctx->diagnose(DiagnosticInfoGeneric(
+ "Invalid value for " + ParamName + ": " + Twine(Value), Severity));
+ return true;
+}
+
static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
MDNode *RootFlagNode) {
@@ -52,6 +59,45 @@ static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
return false;
}
+static bool extractMdValue(uint32_t &Value, MDNode *Node, unsigned int OpId) {
+
+ auto *CI = mdconst::extract<ConstantInt>(Node->getOperand(OpId));
+ if (CI == nullptr)
+ return true;
+
+ Value = CI->getZExtValue();
+ return false;
+}
+
+static bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
+ MDNode *RootFlagNode) {
+
+ if (RootFlagNode->getNumOperands() != 5)
+ return reportError(Ctx, "Invalid format for RootConstants Element");
+
+ mcdxbc::RootParameter NewParameter;
+ NewParameter.Header.ParameterType = dxbc::RootParameterType::Constants32Bit;
+
+ uint32_t SV;
+ if (extractMdValue(SV, RootFlagNode, 1))
+ return reportError(Ctx, "Invalid value for ShaderVisibility");
+
+ NewParameter.Header.ShaderVisibility = (dxbc::ShaderVisibility)SV;
+
+ if (extractMdValue(NewParameter.Constants.ShaderRegister, RootFlagNode, 2))
+ return reportError(Ctx, "Invalid value for ShaderRegister");
+
+ if (extractMdValue(NewParameter.Constants.RegisterSpace, RootFlagNode, 3))
+ return reportError(Ctx, "Invalid value for RegisterSpace");
+
+ if (extractMdValue(NewParameter.Constants.Num32BitValues, RootFlagNode, 4))
+ return reportError(Ctx, "Invalid value for Num32BitValues");
+
+ RSD.Parameters.push_back(NewParameter);
+
+ return false;
+}
+
static bool parseRootSignatureElement(LLVMContext *Ctx,
mcdxbc::RootSignatureDesc &RSD,
MDNode *Element) {
@@ -62,12 +108,16 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
RootSignatureElementKind ElementKind =
StringSwitch<RootSignatureElementKind>(ElementText->getString())
.Case("RootFlags", RootSignatureElementKind::RootFlags)
+ .Case("RootConstants", RootSignatureElementKind::RootConstants)
.Default(RootSignatureElementKind::Error);
switch (ElementKind) {
case RootSignatureElementKind::RootFlags:
return parseRootFlags(Ctx, RSD, Element);
+ case RootSignatureElementKind::RootConstants:
+ return parseRootConstants(Ctx, RSD, Element);
+ break;
case RootSignatureElementKind::Error:
return reportError(Ctx, "Invalid Root Signature Element: " +
ElementText->getString());
@@ -94,10 +144,56 @@ static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
static bool verifyRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; }
+static bool verifyShaderVisibility(dxbc::ShaderVisibility Flags) {
+ switch (Flags) {
+
+ case dxbc::ShaderVisibility::All:
+ case dxbc::ShaderVisibility::Vertex:
+ case dxbc::ShaderVisibility::Hull:
+ case dxbc::ShaderVisibility::Domain:
+ case dxbc::ShaderVisibility::Geometry:
+ case dxbc::ShaderVisibility::Pixel:
+ case dxbc::ShaderVisibility::Amplification:
+ case dxbc::ShaderVisibility::Mesh:
+ return true;
+ }
+
+ return false;
+}
+
+static bool verifyParameterType(dxbc::RootParameterType Flags) {
+ switch (Flags) {
+ case dxbc::RootParameterType::Constants32Bit:
+ return true;
+ }
+
+ return false;
+}
+
+static bool verifyVersion(uint32_t Version) {
+ return (Version == 1 || Version == 2);
+}
+
static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
+
+ if (!verifyVersion(RSD.Header.Version)) {
+ return reportValueError(Ctx, "Version", RSD.Header.Version);
+ }
+
if (!verifyRootFlag(RSD.Header.Flags)) {
- return reportError(Ctx, "Invalid Root Signature flag value");
+ return reportValueError(Ctx, "RootFlags", RSD.Header.Flags);
+ }
+
+ for (const auto &P : RSD.Parameters) {
+ if (!verifyShaderVisibility(P.Header.ShaderVisibility))
+ return reportValueError(Ctx, "ShaderVisibility",
+ (uint32_t)P.Header.ShaderVisibility);
+
+ if (!verifyParameterType(P.Header.ParameterType))
+ return reportValueError(Ctx, "ParameterType",
+ (uint32_t)P.Header.ParameterType);
}
+
return false;
}
@@ -211,6 +307,28 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
OS << indent(Space) << "NumStaticSamplers: " << 0 << ":\n";
OS << indent(Space) << "StaticSamplersOffset: "
<< sizeof(RS.Header) + RS.Parameters.size_in_bytes() << ":\n";
+
+ Space++;
+ for (auto const &P : RS.Parameters) {
+ OS << indent(Space) << "Parameter Type: " << &P.Header.ParameterType
+ << ":\n";
+ OS << indent(Space) << "Shader Visibility: " << &P.Header.ShaderVisibility
+ << ":\n";
+ OS << indent(Space) << "Parameter Offset: " << &P.Header.ParameterOffset
+ << ":\n";
+ switch (P.Header.ParameterType) {
+ case dxbc::RootParameterType::Constants32Bit:
+ OS << indent(Space) << "Register Space: " << &P.Constants.RegisterSpace
+ << ":\n";
+ OS << indent(Space)
+ << "Shader Register: " << &P.Constants.ShaderRegister << ":\n";
+ OS << indent(Space)
+ << "Num 32 Bit Values: " << &P.Constants.Num32BitValues << ":\n";
+ break;
+ }
+ }
+ Space--;
+
Space--;
// end root signature header
}
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 8c25b2eb3fadf..93ec614f1ab85 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -24,7 +24,11 @@
namespace llvm {
namespace dxil {
-enum class RootSignatureElementKind { Error = 0, RootFlags = 1 };
+enum class RootSignatureElementKind {
+ Error = 0,
+ RootFlags = 1,
+ RootConstants = 2
+};
class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
friend AnalysisInfoMixin<RootSignatureAnalysis>;
static AnalysisKey Key;
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll
index fe93c9993c1c3..3af9a524e77f4 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags-Validation-Error.ll
@@ -1,6 +1,6 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
-; CHECK: error: Invalid Root Signature flag value
+; CHECK: error: Invalid value for ShaderVisibility: 255
; CHECK-NOT: Root Signature Definitions
target triple = "dxil-unknown-shadermodel6.0-compute"
@@ -16,5 +16,6 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
-!3 = !{ !4 } ; list of root signature elements
-!4 = !{ !"RootFlags", i32 2147487744 } ; 1 = allow_input_assembler_input_layout
+!3 = !{ !4, !5 } ; list of root signature elements
+!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout
+!5 = !{ !"RootConstants", i32 255, i32 1, i32 2, i32 3 }
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootConstants.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootConstants.ll
new file mode 100644
index 0000000000000..d0520632df2a2
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootConstants.ll
@@ -0,0 +1,34 @@
+; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+; CHECK: @dx.rts0 = private constant [48 x i8] c"{{.*}}", section "RTS0", align 4
+
+define void @main() #0 {
+entry:
+ ret void
+}
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+
+!dx.rootsignatures = !{!2} ; list of function/root signature pairs
+!2 = !{ ptr @main, !3 } ; function, root signature
+!3 = !{ !4, !5 } ; list of root signature elements
+!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout
+!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, i32 3 }
+
+; DXC: - Name: RTS0
+; DXC-NEXT: Size: 48
+; DXC-NEXT: RootSignature:
+; DXC-NEXT: Version: 2
+; DXC-NEXT: NumStaticSamplers: 0
+; DXC-NEXT: StaticSamplersOffset: 0
+; DXC-NEXT: Parameters:
+; DXC-NEXT: - ParameterType: Constants32Bit
+; DXC-NEXT: ShaderVisibility: All
+; DXC-NEXT: Constants:
+; DXC-NEXT: Num32BitValues: 3
+; DXC-NEXT: RegisterSpace: 2
+; DXC-NEXT: ShaderRegister: 1
+; DXC-NEXT: AllowInputAssemblerInputLayout: true
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-ShaderVisibility-Validation-Error.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-ShaderVisibility-Validation-Error.ll
new file mode 100644
index 0000000000000..4b8e6abacd7ad
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-ShaderVisibility-Validation-Error.ll
@@ -0,0 +1,20 @@
+; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
+
+; CHECK: error: Invalid value for RootFlags: 2147487744
+; CHECK-NOT: Root Signature Definitions
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+
+define void @main() #0 {
+entry:
+ ret void
+}
+
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+
+!dx.rootsignatures = !{!2} ; list of function/root signature pairs
+!2 = !{ ptr @main, !3 } ; function, root signature
+!3 = !{ !4 } ; list of root signature elements
+!4 = !{ !"RootFlags", i32 2147487744 } ; 1 = allow_input_assembler_input_layout
>From efc5e52bb8843a025f49e41b322682753c061c3f Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 9 Apr 2025 21:19:25 +0000
Subject: [PATCH 2/2] add test
---
llvm/lib/Target/DirectX/DXILRootSignature.cpp | 33 +++++++++----------
.../ContainerData/RootSignature-Parameters.ll | 30 +++++++++++++++++
2 files changed, 46 insertions(+), 17 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 7686918b0fc75..7f30cef239696 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -299,31 +299,30 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
// start root signature header
Space++;
- OS << indent(Space) << "Flags: " << format_hex(RS.Header.Flags, 8) << ":\n";
- OS << indent(Space) << "Version: " << RS.Header.Version << ":\n";
- OS << indent(Space) << "NumParameters: " << RS.Parameters.size() << ":\n";
+ OS << indent(Space) << "Flags: " << format_hex(RS.Header.Flags, 8) << "\n";
+ OS << indent(Space) << "Version: " << RS.Header.Version << "\n";
+ OS << indent(Space) << "NumParameters: " << RS.Parameters.size() << "\n";
OS << indent(Space) << "RootParametersOffset: " << sizeof(RS.Header)
- << ":\n";
- OS << indent(Space) << "NumStaticSamplers: " << 0 << ":\n";
+ << "\n";
+ OS << indent(Space) << "NumStaticSamplers: " << 0 << "\n";
OS << indent(Space) << "StaticSamplersOffset: "
- << sizeof(RS.Header) + RS.Parameters.size_in_bytes() << ":\n";
+ << sizeof(RS.Header) + RS.Parameters.size_in_bytes() << "\n";
Space++;
for (auto const &P : RS.Parameters) {
- OS << indent(Space) << "Parameter Type: " << &P.Header.ParameterType
- << ":\n";
- OS << indent(Space) << "Shader Visibility: " << &P.Header.ShaderVisibility
- << ":\n";
- OS << indent(Space) << "Parameter Offset: " << &P.Header.ParameterOffset
- << ":\n";
+ OS << indent(Space)
+ << "Parameter Type: " << (uint32_t)P.Header.ParameterType << "\n";
+ OS << indent(Space)
+ << "Shader Visibility: " << (uint32_t)P.Header.ShaderVisibility
+ << "\n";
switch (P.Header.ParameterType) {
case dxbc::RootParameterType::Constants32Bit:
- OS << indent(Space) << "Register Space: " << &P.Constants.RegisterSpace
- << ":\n";
+ OS << indent(Space) << "Register Space: " << P.Constants.RegisterSpace
+ << "\n";
+ OS << indent(Space) << "Shader Register: " << P.Constants.ShaderRegister
+ << "\n";
OS << indent(Space)
- << "Shader Register: " << &P.Constants.ShaderRegister << ":\n";
- OS << indent(Space)
- << "Num 32 Bit Values: " << &P.Constants.Num32BitValues << ":\n";
+ << "Num 32 Bit Values: " << P.Constants.Num32BitValues << "\n";
break;
}
}
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
new file mode 100644
index 0000000000000..9a2f7d840a236
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
@@ -0,0 +1,30 @@
+; RUN: opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+
+define void @main() #0 {
+entry:
+ ret void
+}
+
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+!dx.rootsignatures = !{!2} ; list of function/root signature pairs
+!2 = !{ ptr @main, !3 } ; function, root signature
+!3 = !{ !4, !5 } ; list of root signature elements
+!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout
+!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, i32 3 }
+
+; CHECK-LABEL: Definition for 'main':
+; CHECK-NEXT: Flags: 0x000001
+; CHECK-NEXT: Version: 2
+; CHECK-NEXT: NumParameters: 1
+; CHECK-NEXT: RootParametersOffset: 24
+; CHECK-NEXT: NumStaticSamplers: 0
+; CHECK-NEXT: StaticSamplersOffset: 48
+; CHECK-NEXT: Parameter Type: 1
+; CHECK-NEXT: Shader Visibility: 0
+; CHECK-NEXT: Register Space: 2
+; CHECK-NEXT: Shader Register: 1
+; CHECK-NEXT: Num 32 Bit Values: 3
More information about the llvm-branch-commits
mailing list