[llvm-branch-commits] [llvm] [DirectX] Add DXIL validation of `llvm.loop` metadata (PR #164292)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Oct 20 12:18:15 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-directx
Author: Finn Plummer (inbelic)
<details>
<summary>Changes</summary>
This pr adds the equivalent validation of `llvm.loop` metadata that is [done in DXC](https://github.com/microsoft/DirectXShaderCompiler/blob/8f21027f2ad5dcfa63a275cbd278691f2c8fad33/lib/DxilValidation/DxilValidation.cpp#L3010).
This is done as follows:
- Introduce a `DXILValidateMetadata` pass into the DirectX backend
- Move any validation done in `DXILTranslateMetadata` into this new pass
- Add `llvm.loop` to the metadata whitelist in `DXILTranslateMetadata`
- Add the equivalent checks done for DXC into the new pass
Resolves: https://github.com/llvm/llvm-project/issues/137387
---
Patch is 28.66 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164292.diff
15 Files Affected:
- (modified) llvm/docs/DirectX/DXILArchitecture.rst (+3-1)
- (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1)
- (modified) llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp (+32-76)
- (modified) llvm/lib/Target/DirectX/DXILTranslateMetadata.h (+17)
- (added) llvm/lib/Target/DirectX/DXILValidateMetadata.cpp (+216)
- (added) llvm/lib/Target/DirectX/DXILValidateMetadata.h (+24)
- (modified) llvm/lib/Target/DirectX/DirectX.h (+6)
- (modified) llvm/lib/Target/DirectX/DirectXPassRegistry.def (+1)
- (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+3)
- (added) llvm/test/CodeGen/DirectX/Metadata/loop-md-errs.ll (+135)
- (added) llvm/test/CodeGen/DirectX/Metadata/loop-md-valid.ll (+31)
- (modified) llvm/test/CodeGen/DirectX/Metadata/multiple-entries-cs-error.ll (+1-1)
- (modified) llvm/test/CodeGen/DirectX/Metadata/target-profile-error.ll (+2-2)
- (modified) llvm/test/CodeGen/DirectX/llc-pipeline.ll (+1)
- (modified) llvm/test/CodeGen/DirectX/metadata-stripping.ll (+3-4)
``````````diff
diff --git a/llvm/docs/DirectX/DXILArchitecture.rst b/llvm/docs/DirectX/DXILArchitecture.rst
index bce7fdaa386ed..de72697fc4505 100644
--- a/llvm/docs/DirectX/DXILArchitecture.rst
+++ b/llvm/docs/DirectX/DXILArchitecture.rst
@@ -113,7 +113,7 @@ are grouped into two flows:
The passes to generate DXIL IR follow the flow:
- DXILOpLowering -> DXILPrepare -> DXILTranslateMetadata
+ DXILOpLowering -> DXILPrepare -> DXILTranslateMetadata -> DXILValidateMetadata
Each of these passes has a defined responsibility:
@@ -122,6 +122,8 @@ Each of these passes has a defined responsibility:
namely removing attributes, and inserting bitcasts to allow typed pointers
to be inserted.
#. DXILTranslateMetadata transforms and emits all recognized DXIL Metadata.
+#. DXILValidateMetadata validates all emitted DXIL metadata structures
+ conform to DXIL validation.
The passes to encode DXIL to binary in the DX Container follow the flow:
diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index 6c079517e22d6..f9900370660dd 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -35,6 +35,7 @@ add_llvm_target(DirectXCodeGen
DXILResourceImplicitBinding.cpp
DXILShaderFlags.cpp
DXILTranslateMetadata.cpp
+ DXILValidateMetadata.cpp
DXILRootSignature.cpp
DXILLegalizePass.cpp
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 77334a47dfdbc..abc61d34facc9 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -36,26 +36,6 @@ using namespace llvm;
using namespace llvm::dxil;
namespace {
-/// A simple Wrapper DiagnosticInfo that generates Module-level diagnostic
-/// for TranslateMetadata pass
-class DiagnosticInfoTranslateMD : public DiagnosticInfo {
-private:
- const Twine &Msg;
- const Module &Mod;
-
-public:
- /// \p M is the module for which the diagnostic is being emitted. \p Msg is
- /// the message to show. Note that this class does not copy this message, so
- /// this reference must be valid for the whole life time of the diagnostic.
- DiagnosticInfoTranslateMD(const Module &M,
- const Twine &Msg LLVM_LIFETIME_BOUND,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {}
-
- void print(DiagnosticPrinter &DP) const override {
- DP << Mod.getName() << ": " << Msg << '\n';
- }
-};
enum class EntryPropsTag {
ShaderFlags = 0,
@@ -316,16 +296,17 @@ static void translateBranchMetadata(Module &M, Instruction *BBTerminatorInst) {
BBTerminatorInst->setMetadata("hlsl.controlflow.hint", nullptr);
}
-static std::array<unsigned, 6> getCompatibleInstructionMDs(llvm::Module &M) {
+static std::array<unsigned, 7> getCompatibleInstructionMDs(llvm::Module &M) {
return {
M.getMDKindID("dx.nonuniform"), M.getMDKindID("dx.controlflow.hints"),
M.getMDKindID("dx.precise"), llvm::LLVMContext::MD_range,
- llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_noalias};
+ llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_noalias,
+ M.getMDKindID("llvm.loop")};
}
static void translateInstructionMetadata(Module &M) {
// construct allowlist of valid metadata node kinds
- std::array<unsigned, 6> DXILCompatibleMDs = getCompatibleInstructionMDs(M);
+ std::array<unsigned, 7> DXILCompatibleMDs = getCompatibleInstructionMDs(M);
for (Function &F : M) {
for (BasicBlock &BB : F) {
@@ -391,9 +372,6 @@ static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
uint64_t CombinedMask = ShaderFlags.getCombinedFlags();
EntryFnMDNodes.emplace_back(
emitTopLevelLibraryNode(M, ResourceMD, CombinedMask));
- } else if (MMDI.EntryPropertyVec.size() > 1) {
- M.getContext().diagnose(DiagnosticInfoTranslateMD(
- M, "Non-library shader: One and only one entry expected"));
}
for (const EntryProperties &EntryProp : MMDI.EntryPropertyVec) {
@@ -402,20 +380,9 @@ static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
// If ShaderProfile is Library, mask is already consolidated in the
// top-level library node. Hence it is not emitted.
- uint64_t EntryShaderFlags = 0;
- if (MMDI.ShaderProfile != Triple::EnvironmentType::Library) {
- EntryShaderFlags = EntrySFMask;
- if (EntryProp.ShaderStage != MMDI.ShaderProfile) {
- M.getContext().diagnose(DiagnosticInfoTranslateMD(
- M,
- "Shader stage '" +
- Twine(getShortShaderStage(EntryProp.ShaderStage) +
- "' for entry '" + Twine(EntryProp.Entry->getName()) +
- "' different from specified target profile '" +
- Twine(Triple::getEnvironmentTypeName(MMDI.ShaderProfile) +
- "'"))));
- }
- }
+ uint64_t EntryShaderFlags =
+ MMDI.ShaderProfile == Triple::EnvironmentType::Library ? 0
+ : EntrySFMask;
EntryFnMDNodes.emplace_back(emitEntryMD(EntryProp, Signatures, ResourceMD,
EntryShaderFlags,
MMDI.ShaderProfile));
@@ -448,44 +415,33 @@ PreservedAnalyses DXILTranslateMetadata::run(Module &M,
return PreservedAnalyses::all();
}
-namespace {
-class DXILTranslateMetadataLegacy : public ModulePass {
-public:
- static char ID; // Pass identification, replacement for typeid
- explicit DXILTranslateMetadataLegacy() : ModulePass(ID) {}
-
- StringRef getPassName() const override { return "DXIL Translate Metadata"; }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<DXILResourceTypeWrapperPass>();
- AU.addRequired<DXILResourceWrapperPass>();
- AU.addRequired<ShaderFlagsAnalysisWrapper>();
- AU.addRequired<DXILMetadataAnalysisWrapperPass>();
- AU.addRequired<RootSignatureAnalysisWrapper>();
- AU.addPreserved<RootSignatureAnalysisWrapper>();
- AU.addPreserved<DXILResourceWrapperPass>();
- AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
- AU.addPreserved<ShaderFlagsAnalysisWrapper>();
- AU.addPreserved<DXILResourceBindingWrapperPass>();
- }
+void DXILTranslateMetadataLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<DXILResourceTypeWrapperPass>();
+ AU.addRequired<DXILResourceWrapperPass>();
+ AU.addRequired<ShaderFlagsAnalysisWrapper>();
+ AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+ AU.addRequired<RootSignatureAnalysisWrapper>();
+ AU.addPreserved<RootSignatureAnalysisWrapper>();
+ AU.addPreserved<DXILResourceWrapperPass>();
+ AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
+ AU.addPreserved<ShaderFlagsAnalysisWrapper>();
+ AU.addPreserved<DXILResourceBindingWrapperPass>();
+}
- bool runOnModule(Module &M) override {
- DXILResourceMap &DRM =
- getAnalysis<DXILResourceWrapperPass>().getResourceMap();
- DXILResourceTypeMap &DRTM =
- getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
- const ModuleShaderFlags &ShaderFlags =
- getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags();
- dxil::ModuleMetadataInfo MMDI =
- getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
-
- translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI);
- translateInstructionMetadata(M);
- return true;
- }
-};
+bool DXILTranslateMetadataLegacy::runOnModule(Module &M) {
+ DXILResourceMap &DRM =
+ getAnalysis<DXILResourceWrapperPass>().getResourceMap();
+ DXILResourceTypeMap &DRTM =
+ getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
+ const ModuleShaderFlags &ShaderFlags =
+ getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags();
+ dxil::ModuleMetadataInfo MMDI =
+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
-} // namespace
+ translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI);
+ translateInstructionMetadata(M);
+ return true;
+}
char DXILTranslateMetadataLegacy::ID = 0;
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.h b/llvm/lib/Target/DirectX/DXILTranslateMetadata.h
index 4c1ffac1781e6..cfb8aaa8f98b5 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.h
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.h
@@ -10,6 +10,7 @@
#define LLVM_TARGET_DIRECTX_DXILTRANSLATEMETADATA_H
#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
namespace llvm {
@@ -20,6 +21,22 @@ class DXILTranslateMetadata : public PassInfoMixin<DXILTranslateMetadata> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};
+/// Wrapper pass for the legacy pass manager.
+///
+/// This is required because the passes that will depend on this are codegen
+/// passes which run through the legacy pass manager.
+class DXILTranslateMetadataLegacy : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ explicit DXILTranslateMetadataLegacy() : ModulePass(ID) {}
+
+ StringRef getPassName() const override { return "DXIL Translate Metadata"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ bool runOnModule(Module &M) override;
+};
+
} // namespace llvm
#endif // LLVM_TARGET_DIRECTX_DXILTRANSLATEMETADATA_H
diff --git a/llvm/lib/Target/DirectX/DXILValidateMetadata.cpp b/llvm/lib/Target/DirectX/DXILValidateMetadata.cpp
new file mode 100644
index 0000000000000..275d3686dd7e9
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILValidateMetadata.cpp
@@ -0,0 +1,216 @@
+//===- DXILValidateMetadata.cpp - Pass to validate DXIL metadata ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DXILValidateMetadata.h"
+#include "DXILTranslateMetadata.h"
+#include "DirectX.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Analysis/DXILMetadataAnalysis.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+namespace {
+
+/// A simple Wrapper DiagnosticInfo that generates Module-level diagnostic
+/// for the ValidateMetadata pass
+class DiagnosticInfoValidateMD : public DiagnosticInfo {
+private:
+ const Twine &Msg;
+ const Module &Mod;
+
+public:
+ /// \p M is the module for which the diagnostic is being emitted. \p Msg is
+ /// the message to show. Note that this class does not copy this message, so
+ /// this reference must be valid for the whole life time of the diagnostic.
+ DiagnosticInfoValidateMD(const Module &M,
+ const Twine &Msg LLVM_LIFETIME_BOUND,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {}
+
+ void print(DiagnosticPrinter &DP) const override {
+ DP << Mod.getName() << ": " << Msg << '\n';
+ }
+};
+
+static bool reportError(Module &M, Twine Message,
+ DiagnosticSeverity Severity = DS_Error) {
+ M.getContext().diagnose(DiagnosticInfoValidateMD(M, Message, Severity));
+ return true;
+}
+
+static bool reportLoopError(Module &M, Twine Message,
+ DiagnosticSeverity Severity = DS_Error) {
+ return reportError(M, Twine("Invalid \"llvm.loop\" metadata: ") + Message,
+ Severity);
+}
+
+} // namespace
+
+static void validateLoopMetadata(Module &M, MDNode *LoopMD) {
+ // DXIL only accepts the following loop hints:
+ // llvm.loop.unroll.disable, llvm.loop.unroll.full, llvm.loop.unroll.count
+ std::array<StringLiteral, 3> ValidHintNames = {"llvm.loop.unroll.count",
+ "llvm.loop.unroll.disable",
+ "llvm.loop.unroll.full"};
+
+ // llvm.loop metadata must have it's first operand be a self-reference, so we
+ // require at least 1 operand.
+ //
+ // It only makes sense to specify up to 1 of the hints on a branch, so we can
+ // have at most 2 operands.
+
+ if (LoopMD->getNumOperands() != 1 && LoopMD->getNumOperands() != 2) {
+ reportLoopError(M, "Requires exactly 1 or 2 operands");
+ return;
+ }
+
+ if (LoopMD != LoopMD->getOperand(0)) {
+ reportLoopError(M, "First operand must be a self-reference");
+ return;
+ }
+
+ // A node only containing a self-reference is a valid use to denote a loop
+ if (LoopMD->getNumOperands() == 1)
+ return;
+
+ LoopMD = dyn_cast<MDNode>(LoopMD->getOperand(1));
+ if (!LoopMD) {
+ reportLoopError(M, "Second operand must be a metadata node");
+ return;
+ }
+
+ if (LoopMD->getNumOperands() != 1 && LoopMD->getNumOperands() != 2) {
+ reportLoopError(M, "Requires exactly 1 or 2 operands");
+ return;
+ }
+
+ // It is valid to have a chain of self-referential loop metadata nodes so if
+ // we have another self-reference, recurse.
+ //
+ // Eg:
+ // !0 = !{!0, !1}
+ // !1 = !{!1, !2}
+ // !2 = !{"llvm.loop.unroll.disable"}
+ if (LoopMD == LoopMD->getOperand(0))
+ return validateLoopMetadata(M, LoopMD);
+
+ // Otherwise, we are at our base hint metadata node
+ auto *HintStr = dyn_cast<MDString>(LoopMD->getOperand(0));
+ if (!HintStr || !llvm::is_contained(ValidHintNames, HintStr->getString())) {
+ reportLoopError(M,
+ "First operand must be a valid \"llvm.loop.unroll\" hint");
+ return;
+ }
+
+ // Ensure count node is a constant integer value
+ auto ValidCountNode = [](MDNode *HintMD) -> bool {
+ if (HintMD->getNumOperands() == 2)
+ if (auto *CountMD = dyn_cast<ConstantAsMetadata>(HintMD->getOperand(1)))
+ if (isa<ConstantInt>(CountMD->getValue()))
+ return true;
+ return false;
+ };
+
+ if (HintStr->getString() == "llvm.loop.unroll.count" &&
+ !ValidCountNode(LoopMD)) {
+ reportLoopError(M, "Second operand of \"llvm.loop.unroll.count\" "
+ "must be a constant integer");
+ return;
+ }
+}
+
+static void validateInstructionMetadata(Module &M) {
+ unsigned char MDLoopKind = M.getContext().getMDKindID("llvm.loop");
+
+ for (Function &F : M)
+ for (BasicBlock &BB : F)
+ for (Instruction &I : BB) {
+ if (MDNode *LoopMD = I.getMetadata(MDLoopKind))
+ validateLoopMetadata(M, LoopMD);
+ }
+}
+
+static void validateGlobalMetadata(Module &M,
+ const dxil::ModuleMetadataInfo &MMDI) {
+ if (MMDI.ShaderProfile != Triple::EnvironmentType::Library) {
+ if (1 < MMDI.EntryPropertyVec.size())
+ reportError(M, "Non-library shader: One and only one entry expected");
+
+ for (const dxil::EntryProperties &EntryProp : MMDI.EntryPropertyVec)
+ if (EntryProp.ShaderStage != MMDI.ShaderProfile)
+ reportError(
+ M,
+ "Shader stage '" +
+ Twine(Twine(Triple::getEnvironmentTypeName(
+ EntryProp.ShaderStage)) +
+ "' for entry '" + Twine(EntryProp.Entry->getName()) +
+ "' different from specified target profile '" +
+ Twine(Triple::getEnvironmentTypeName(MMDI.ShaderProfile) +
+ "'")));
+ }
+}
+
+PreservedAnalyses DXILValidateMetadata::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+
+ const dxil::ModuleMetadataInfo MMDI = MAM.getResult<DXILMetadataAnalysis>(M);
+ validateGlobalMetadata(M, MMDI);
+ validateInstructionMetadata(M);
+
+ return PreservedAnalyses::all();
+}
+
+namespace {
+class DXILValidateMetadataLegacy : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ explicit DXILValidateMetadataLegacy() : ModulePass(ID) {}
+
+ StringRef getPassName() const override { return "DXIL Validate Metadata"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<DXILMetadataAnalysisWrapperPass>();
+ AU.addRequired<DXILTranslateMetadataLegacy>();
+ AU.setPreservesAll();
+ }
+
+ bool runOnModule(Module &M) override {
+ dxil::ModuleMetadataInfo MMDI =
+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
+ validateGlobalMetadata(M, MMDI);
+ validateInstructionMetadata(M);
+ return true;
+ }
+};
+
+} // namespace
+
+char DXILValidateMetadataLegacy::ID = 0;
+
+ModulePass *llvm::createDXILValidateMetadataLegacyPass() {
+ return new DXILValidateMetadataLegacy();
+}
+
+INITIALIZE_PASS_BEGIN(DXILValidateMetadataLegacy, "dxil-validate-metadata",
+ "DXIL Validate Metadata", false, false)
+INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DXILTranslateMetadataLegacy)
+INITIALIZE_PASS_END(DXILValidateMetadataLegacy, "dxil-validate-metadata",
+ "DXIL validate Metadata", false, false)
diff --git a/llvm/lib/Target/DirectX/DXILValidateMetadata.h b/llvm/lib/Target/DirectX/DXILValidateMetadata.h
new file mode 100644
index 0000000000000..3188afafc8e22
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILValidateMetadata.h
@@ -0,0 +1,24 @@
+//===- DXILValidateMetadata.h - Pass to emit DXIL metadata -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_DIRECTX_DXILVALIDATEMETADATA_H
+#define LLVM_TARGET_DIRECTX_DXILVALIDATEMETADATA_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// A pass that transforms DXIL Intrinsics that don't have DXIL opCodes
+class DXILValidateMetadata : public PassInfoMixin<DXILValidateMetadata> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TARGET_DIRECTX_DXILVALIDATEMETADATA_H
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index e31c2ffa4f761..90546f133c9d2 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -90,6 +90,12 @@ void initializeDXILTranslateMetadataLegacyPass(PassRegistry &);
/// Pass to emit metadata for DXIL.
ModulePass *createDXILTranslateMetadataLegacyPass();
+/// Initializer for DXILValidateMetadata.
+void initializeDXILValidateMetadataLegacyPass(PassRegistry &);
+
+/// Pass to validate metadata for DXIL.
+ModulePass *createDXILValidateMetadataLegacyPass();
+
/// Pass to pretty print DXIL metadata.
ModulePass *createDXILPrettyPrinterLegacyPass(raw_ostream &OS);
diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
index b4b48a166800e..a69f9764b932b 100644
--- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def
+++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
@@ -31,6 +31,7 @@ MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion())
MODULE_PASS("dxil-op-lower", DXILOpLowering())
MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs()))
MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata())
+MODULE_PASS("dxil-validate-metadata", DXILValidateMetadata())
MODULE_PASS("dxil-resource-implicit-binding", DXILResourceImplicitBinding())
MODULE_PASS("dxil-post-optimization-validation", DXILPostOptimizationValidation())
// TODO: rename to print<foo> after NPM switch
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index bcf84403b2c0d..09cbf031ddefe 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -27,6 +27,7 @@
#include "DXILRootSignature.h"
#include "DXILShaderFlags.h"
#include "DXILT...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/164292
More information about the llvm-branch-commits
mailing list