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 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
