[llvm-branch-commits] [clang] [HLSL][DirectX] Add the Qdx-rootsignature-strip driver option (PR #154454)
Finn Plummer via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 19 20:46:09 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/154454
>From 9a418dfebbebd583aca8527eca4f6b0209263b15 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 8 Aug 2025 17:16:06 +0000
Subject: [PATCH 1/4] add BinaryModifyJobClass
---
clang/include/clang/Driver/Action.h | 14 +++++++++++++-
clang/lib/Driver/Action.cpp | 7 +++++++
clang/lib/Driver/ToolChain.cpp | 1 +
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 7aecfd886adb8..6fc515f9e4049 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -76,9 +76,10 @@ class Action {
StaticLibJobClass,
BinaryAnalyzeJobClass,
BinaryTranslatorJobClass,
+ BinaryModifyJobClass,
JobClassFirst = PreprocessJobClass,
- JobClassLast = BinaryTranslatorJobClass
+ JobClassLast = BinaryModifyJobClass
};
// The offloading kind determines if this action is binded to a particular
@@ -687,6 +688,17 @@ class BinaryTranslatorJobAction : public JobAction {
}
};
+class BinaryModifyJobAction : public JobAction {
+ void anchor() override;
+
+public:
+ BinaryModifyJobAction(Action *Input, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == BinaryModifyJobClass;
+ }
+};
+
} // namespace driver
} // namespace clang
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index ec09726044812..fbf80b3c6f124 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -52,6 +52,8 @@ const char *Action::getClassName(ActionClass AC) {
return "binary-analyzer";
case BinaryTranslatorJobClass:
return "binary-translator";
+ case BinaryModifyJobClass:
+ return "binary-modifier";
}
llvm_unreachable("invalid class");
@@ -467,3 +469,8 @@ void BinaryTranslatorJobAction::anchor() {}
BinaryTranslatorJobAction::BinaryTranslatorJobAction(Action *Input,
types::ID Type)
: JobAction(BinaryTranslatorJobClass, Input, Type) {}
+
+void BinaryModifyJobAction::anchor() {}
+
+BinaryModifyJobAction::BinaryModifyJobAction(Action *Input, types::ID Type)
+ : JobAction(BinaryModifyJobClass, Input, Type) {}
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 25c6b5a486fd5..713bda1d7244d 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -652,6 +652,7 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::VerifyDebugInfoJobClass:
case Action::BinaryAnalyzeJobClass:
case Action::BinaryTranslatorJobClass:
+ case Action::BinaryModifyJobClass:
llvm_unreachable("Invalid tool kind.");
case Action::CompileJobClass:
>From 4887c6029deca7048437f3cf58fd70a8463975eb Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 19 Aug 2025 18:35:51 -0700
Subject: [PATCH 2/4] [HLSL] Add the `Qstrip-rootsignature` DXC driver option
---
clang/include/clang/Basic/CodeGenOptions.def | 3 ++
clang/include/clang/Driver/Options.td | 6 +++
clang/lib/Driver/Driver.cpp | 10 +++++
clang/lib/Driver/ToolChains/HLSL.cpp | 41 ++++++++++++++++++-
clang/lib/Driver/ToolChains/HLSL.h | 15 +++++++
.../test/Driver/dxc_strip_rootsignature.hlsl | 22 ++++++++++
6 files changed, 95 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Driver/dxc_strip_rootsignature.hlsl
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 423b696785500..89e9f5b5853bb 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -479,6 +479,9 @@ CODEGENOPT(StaticClosure, 1, 0, Benign)
/// Assume that UAVs/SRVs may alias
CODEGENOPT(ResMayAlias, 1, 0, Benign)
+/// Omit the root signature from produced DXContainer
+CODEGENOPT(HLSLRootSigStrip, 1, 0, Benign)
+
/// Controls how unwind v2 (epilog) information should be generated for x64
/// Windows.
ENUM_CODEGENOPT(WinX64EHUnwindV2, WinX64EHUnwindV2Mode,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6aab43c9ed57f..1bd3f09ae1df1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9381,6 +9381,12 @@ def res_may_alias : Option<["/", "-"], "res-may-alias", KIND_FLAG>,
Visibility<[DXCOption, ClangOption, CC1Option]>,
HelpText<"Assume that UAVs/SRVs may alias">,
MarshallingInfoFlag<CodeGenOpts<"ResMayAlias">>;
+def dxc_strip_rootsignature :
+ Option<["/", "-"], "Qstrip-rootsignature", KIND_FLAG>,
+ Group<dxc_Group>,
+ Visibility<[DXCOption]>,
+ HelpText<"Omit the root signature from produced DXContainer">,
+ MarshallingInfoFlag<CodeGenOpts<"HLSLRootSigStrip">>;
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
HelpText<"Set target profile">,
Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 586f287843f3e..59a4eadcd5d85 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4601,6 +4601,16 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Actions.push_back(C.MakeAction<BinaryTranslatorJobAction>(
LastAction, types::TY_DX_CONTAINER));
}
+ if (TC.requiresObjcopy(Args)) {
+ Action *LastAction = Actions.back();
+ // llvm-objcopy expects a DXIL container, which can either be
+ // validated (in which case they are TY_DX_CONTAINER), or unvalidated
+ // (TY_OBJECT).
+ if (LastAction->getType() == types::TY_DX_CONTAINER ||
+ LastAction->getType() == types::TY_Object)
+ Actions.push_back(C.MakeAction<BinaryModifyJobAction>(
+ LastAction, types::TY_DX_CONTAINER));
+ }
}
// Claim ignored clang-cl options.
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index 38f4643abad98..a554c15f1e7c6 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -247,6 +247,30 @@ void tools::hlsl::MetalConverter::ConstructJob(
Exec, CmdArgs, Inputs, Input));
}
+void tools::hlsl::LLVMObjcopy::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+
+ std::string ObjcopyPath = getToolChain().GetProgramPath("llvm-objcopy");
+ const char *Exec = Args.MakeArgString(ObjcopyPath);
+
+ ArgStringList CmdArgs;
+ assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+ const InputInfo &Input = Inputs[0];
+ CmdArgs.push_back(Input.getFilename());
+ CmdArgs.push_back(Output.getFilename());
+
+ if (Args.hasArg(options::OPT_dxc_strip_rootsignature)) {
+ const char *Frs = Args.MakeArgString("--remove-section=RTS0");
+ CmdArgs.push_back(Frs);
+ }
+
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs, Input));
+}
+
/// DirectX Toolchain
HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
@@ -267,6 +291,10 @@ Tool *clang::driver::toolchains::HLSLToolChain::getTool(
if (!MetalConverter)
MetalConverter.reset(new tools::hlsl::MetalConverter(*this));
return MetalConverter.get();
+ case Action::BinaryModifyJobClass:
+ if (!LLVMObjcopy)
+ LLVMObjcopy.reset(new tools::hlsl::LLVMObjcopy(*this));
+ return LLVMObjcopy.get();
default:
return ToolChain::getTool(AC);
}
@@ -404,16 +432,25 @@ bool HLSLToolChain::requiresBinaryTranslation(DerivedArgList &Args) const {
return Args.hasArg(options::OPT_metal) && Args.hasArg(options::OPT_dxc_Fo);
}
+bool HLSLToolChain::requiresObjcopy(DerivedArgList &Args) const {
+ return Args.hasArg(options::OPT_dxc_Fo) &&
+ Args.hasArg(options::OPT_dxc_strip_rootsignature);
+}
+
bool HLSLToolChain::isLastJob(DerivedArgList &Args,
Action::ActionClass AC) const {
bool HasTranslation = requiresBinaryTranslation(Args);
bool HasValidation = requiresValidation(Args);
+ bool HasObjcopy = requiresObjcopy(Args);
// If translation and validation are not required, we should only have one
// action.
- if (!HasTranslation && !HasValidation)
+ if (!HasTranslation && !HasValidation && !HasObjcopy)
return true;
if ((HasTranslation && AC == Action::BinaryTranslatorJobClass) ||
- (!HasTranslation && HasValidation && AC == Action::BinaryAnalyzeJobClass))
+ (!HasTranslation && HasValidation &&
+ AC == Action::BinaryAnalyzeJobClass) ||
+ (!HasTranslation && !HasValidation && HasObjcopy &&
+ AC == Action::BinaryModifyJobClass))
return true;
return false;
}
diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h
index 3824b4252324b..b81141b26b4e6 100644
--- a/clang/lib/Driver/ToolChains/HLSL.h
+++ b/clang/lib/Driver/ToolChains/HLSL.h
@@ -42,6 +42,19 @@ class LLVM_LIBRARY_VISIBILITY MetalConverter : public Tool {
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY LLVMObjcopy : public Tool {
+public:
+ LLVMObjcopy(const ToolChain &TC)
+ : Tool("hlsl::LLVMObjcopy", "llvm-objcopy", TC) {}
+
+ bool hasIntegratedCPP() const override { return false; }
+
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
} // namespace hlsl
} // namespace tools
@@ -65,6 +78,7 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
static std::optional<std::string> parseTargetProfile(StringRef TargetProfile);
bool requiresValidation(llvm::opt::DerivedArgList &Args) const;
bool requiresBinaryTranslation(llvm::opt::DerivedArgList &Args) const;
+ bool requiresObjcopy(llvm::opt::DerivedArgList &Args) const;
bool isLastJob(llvm::opt::DerivedArgList &Args, Action::ActionClass AC) const;
// Set default DWARF version to 4 for DXIL uses version 4.
@@ -73,6 +87,7 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
private:
mutable std::unique_ptr<tools::hlsl::Validator> Validator;
mutable std::unique_ptr<tools::hlsl::MetalConverter> MetalConverter;
+ mutable std::unique_ptr<tools::hlsl::LLVMObjcopy> LLVMObjcopy;
};
} // end namespace toolchains
diff --git a/clang/test/Driver/dxc_strip_rootsignature.hlsl b/clang/test/Driver/dxc_strip_rootsignature.hlsl
new file mode 100644
index 0000000000000..b4af1f4b1541d
--- /dev/null
+++ b/clang/test/Driver/dxc_strip_rootsignature.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_dxc -Qstrip-rootsignature -T cs_6_0 -HV 202x -Vd /Fo %t %s
+// RUN: obj2yaml %t | FileCheck %s
+// RUN: obj2yaml %t | FileCheck %s --check-prefix=OTHERS
+
+// Test to demonstrate that we specify to the root signature with the
+// -Qstrip-rootsignature option
+
+// CHECK-NOT: RTS0
+
+// OTHERS: FileSize: 1964
+// OTHERS-NEXT: PartCount: 6
+// OTHERS: Parts:
+// OTHERS: Name: DXIL
+// OTHERS: Name: SFI0
+// OTHERS: Name: HASH
+// OTHERS: Name: ISG1
+// OTHERS: Name: OSG1
+// OTHERS: Name: PSV0
+
+[shader("compute"), RootSignature("")]
+[numthreads(1,1,1)]
+void EmptyEntry() {}
>From ebae438ab14f1103fc1642dfa790f60fc0732878 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 19 Aug 2025 18:45:16 -0700
Subject: [PATCH 3/4] fix comment typo
---
clang/test/Driver/dxc_strip_rootsignature.hlsl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Driver/dxc_strip_rootsignature.hlsl b/clang/test/Driver/dxc_strip_rootsignature.hlsl
index b4af1f4b1541d..bd624dc55df82 100644
--- a/clang/test/Driver/dxc_strip_rootsignature.hlsl
+++ b/clang/test/Driver/dxc_strip_rootsignature.hlsl
@@ -2,7 +2,7 @@
// RUN: obj2yaml %t | FileCheck %s
// RUN: obj2yaml %t | FileCheck %s --check-prefix=OTHERS
-// Test to demonstrate that we specify to the root signature with the
+// Test to demonstrate that we specify to strip the root signature with the
// -Qstrip-rootsignature option
// CHECK-NOT: RTS0
>From a6391c8ac0f2994d14f98101b1fddd561cf63568 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 19 Aug 2025 20:45:17 -0700
Subject: [PATCH 4/4] use valid version
---
clang/test/Driver/dxc_strip_rootsignature.hlsl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/Driver/dxc_strip_rootsignature.hlsl b/clang/test/Driver/dxc_strip_rootsignature.hlsl
index bd624dc55df82..b08f182738e6d 100644
--- a/clang/test/Driver/dxc_strip_rootsignature.hlsl
+++ b/clang/test/Driver/dxc_strip_rootsignature.hlsl
@@ -1,4 +1,4 @@
-// RUN: %clang_dxc -Qstrip-rootsignature -T cs_6_0 -HV 202x -Vd /Fo %t %s
+// RUN: %clang_dxc -Qstrip-rootsignature -T cs_6_6 -HV 202x -Vd /Fo %t %s
// RUN: obj2yaml %t | FileCheck %s
// RUN: obj2yaml %t | FileCheck %s --check-prefix=OTHERS
@@ -7,7 +7,7 @@
// CHECK-NOT: RTS0
-// OTHERS: FileSize: 1964
+// OTHERS: FileSize: 1956
// OTHERS-NEXT: PartCount: 6
// OTHERS: Parts:
// OTHERS: Name: DXIL
More information about the llvm-branch-commits
mailing list