[Mlir-commits] [clang] [flang] [llvm] [mlir] [IR] Use persistent metadata IDs for pass snapshots (PR #216838)
Yaxun Liu
llvmlistbot at llvm.org
Thu Aug 20 19:27:37 PDT 2026
https://github.com/yxsamliu updated https://github.com/llvm/llvm-project/pull/216838
>From 2f6ec89222a4714fde00ddcbbac4e9682f8c7b2a Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Wed, 19 Aug 2026 13:27:59 -0400
Subject: [PATCH 1/6] [IR] Use persistent metadata IDs for pass snapshots
Pass snapshots repeatedly renumber metadata, which makes output harder
to compare and spends time rescanning module metadata.
Assign a persistent ID when a metadata node becomes permanent and use it
for module, function, loop, and SCC pass snapshots. Normal module
printing keeps compact numbering for canonical output.
The ID fits in existing MDNode header padding on 64-bit hosts. It adds
four bytes to the header on 32-bit hosts.
---
llvm/include/llvm/IR/IRPrintingPasses.h | 5 +
llvm/include/llvm/IR/Metadata.h | 2 +-
llvm/include/llvm/IR/Module.h | 7 +
.../include/llvm/IRPrinter/IRPrintingPasses.h | 5 +
llvm/lib/Analysis/CallGraphSCCPass.cpp | 4 +-
llvm/lib/Analysis/LoopInfo.cpp | 2 +-
llvm/lib/IR/AsmWriter.cpp | 144 ++++++++++++++----
llvm/lib/IR/IRPrintingPasses.cpp | 36 +++--
llvm/lib/IR/LLVMContextImpl.h | 12 ++
llvm/lib/IR/LegacyPassManager.cpp | 12 +-
llvm/lib/IR/Metadata.cpp | 9 ++
llvm/lib/IR/Pass.cpp | 4 +-
llvm/lib/IRPrinter/IRPrintingPasses.cpp | 26 +++-
llvm/lib/Passes/PassRegistry.def | 5 +-
llvm/lib/Passes/StandardInstrumentations.cpp | 2 +-
.../legacy-callgraph-scc-pass-printer.ll | 13 +-
.../print-changed-persistent-metadata-ids.ll | 77 ++++++++++
.../Other/print-persistent-metadata-ids.ll | 94 ++++++++++++
llvm/unittests/IR/AsmWriterTest.cpp | 83 ++++++++++
19 files changed, 488 insertions(+), 54 deletions(-)
create mode 100644 llvm/test/Other/print-changed-persistent-metadata-ids.ll
create mode 100644 llvm/test/Other/print-persistent-metadata-ids.ll
diff --git a/llvm/include/llvm/IR/IRPrintingPasses.h b/llvm/include/llvm/IR/IRPrintingPasses.h
index 1b2d38d6190e9..a7803e39d3b89 100644
--- a/llvm/include/llvm/IR/IRPrintingPasses.h
+++ b/llvm/include/llvm/IR/IRPrintingPasses.h
@@ -31,6 +31,11 @@ LLVM_ABI ModulePass *
createPrintModulePass(raw_ostream &OS, const std::string &Banner = "",
bool ShouldPreserveUseListOrder = false);
+LLVM_ABI ModulePass *createPrintModulePass(raw_ostream &OS,
+ const std::string &Banner,
+ bool ShouldPreserveUseListOrder,
+ bool UsePersistentMetadataIDs);
+
/// Create and return a pass that prints functions to the specified
/// \c raw_ostream as they are processed.
LLVM_ABI FunctionPass *createPrintFunctionPass(raw_ostream &OS,
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 5b458fa14f0b1..b108e42e06ce0 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1083,7 +1083,7 @@ class MDNode : public Metadata {
size_t IsLarge : 1;
size_t SmallSize : 4;
size_t SmallNumOps : 4;
- size_t : sizeof(size_t) * CHAR_BIT - 10;
+ uint32_t MetadataPrintID = 0;
unsigned NumUnresolved = 0;
using LargeStorageVector = SmallVector<MDOperand, 0>;
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 53927e96a232e..93393bbef2704 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -987,6 +987,13 @@ class LLVM_ABI Module {
bool ShouldPreserveUseListOrder = false,
bool IsForDebug = false) const;
+ /// Print the module using metadata IDs that stay stable across pass-debug
+ /// snapshots. Unlike canonical module output, these IDs may contain gaps.
+ void printWithPersistentMetadataIDs(raw_ostream &OS,
+ AssemblyAnnotationWriter *AAW = nullptr,
+ bool ShouldPreserveUseListOrder = false,
+ bool IsForDebug = false) const;
+
/// Dump the module to stderr (for debugging).
void dump() const;
diff --git a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
index e574d94ca2f22..175cecdfa3cd5 100644
--- a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
+++ b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
@@ -35,12 +35,17 @@ class PrintModulePass : public RequiredPassInfoMixin<PrintModulePass> {
std::string Banner;
bool ShouldPreserveUseListOrder;
bool EmitSummaryIndex;
+ bool UsePersistentMetadataIDs;
public:
LLVM_ABI PrintModulePass();
LLVM_ABI PrintModulePass(raw_ostream &OS, const std::string &Banner = "",
bool ShouldPreserveUseListOrder = false,
bool EmitSummaryIndex = false);
+ LLVM_ABI PrintModulePass(raw_ostream &OS, const std::string &Banner,
+ bool ShouldPreserveUseListOrder,
+ bool EmitSummaryIndex,
+ bool UsePersistentMetadataIDs);
LLVM_ABI PreservedAnalyses run(Module &M, AnalysisManager<Module> &);
};
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp
index 3fd2fe02f6688..dd6f7212f038f 100644
--- a/llvm/lib/Analysis/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp
@@ -686,7 +686,7 @@ namespace {
if (isFunctionInPrintList("*") && NeedModule) {
PrintBannerOnce();
OS << "\n";
- SCC.getCallGraph().getModule().print(OS, nullptr);
+ SCC.getCallGraph().getModule().printWithPersistentMetadataIDs(OS);
return false;
}
bool FoundFunction = false;
@@ -707,7 +707,7 @@ namespace {
if (NeedModule && FoundFunction) {
PrintBannerOnce();
OS << "\n";
- SCC.getCallGraph().getModule().print(OS, nullptr);
+ SCC.getCallGraph().getModule().printWithPersistentMetadataIDs(OS);
}
return false;
}
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 16a7690092ff5..43dc25ec0efcb 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -1035,7 +1035,7 @@ void llvm::printLoop(const Loop &L, raw_ostream &OS,
OS << ")\n";
// printing whole module
- OS << *L.getHeader()->getModule();
+ L.getHeader()->getModule()->printWithPersistentMetadataIDs(OS);
return;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index c3202eea12c28..5373eeb4373ce 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//
+#include "LLVMContextImpl.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
@@ -800,6 +801,8 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
const Function* TheFunction = nullptr;
bool FunctionProcessed = false;
bool ShouldInitializeAllMetadata;
+ bool UsePersistentMetadataIDs;
+ bool TrackPersistentMetadataDefinitions;
std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
ProcessModuleHookFn;
@@ -849,15 +852,19 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// functions, giving correct numbering for metadata referenced only from
/// within a function (even if no functions have been initialized).
explicit SlotTracker(const Module *M,
- bool ShouldInitializeAllMetadata = false);
+ bool ShouldInitializeAllMetadata = false,
+ bool UsePersistentMetadataIDs = false);
/// Construct from a function, starting out in incorp state.
///
/// If \c ShouldInitializeAllMetadata, initializes all metadata in all
/// functions, giving correct numbering for metadata referenced only from
/// within a function (even if no functions have been initialized).
+ /// If \c UsePersistentMetadataIDs, skips metadata enumeration and uses IDs
+ /// stored in the LLVM context.
explicit SlotTracker(const Function *F,
- bool ShouldInitializeAllMetadata = false);
+ bool ShouldInitializeAllMetadata = false,
+ bool UsePersistentMetadataIDs = false);
/// Construct from a module summary index.
explicit SlotTracker(const ModuleSummaryIndex *Index);
@@ -908,6 +915,7 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
mdn_iterator mdn_end() { return mdnMap.end(); }
unsigned mdn_size() const { return mdnMap.size(); }
bool mdn_empty() const { return mdnMap.empty(); }
+ bool usePersistentMetadataIDs() const { return UsePersistentMetadataIDs; }
/// AttributeSet map iterators.
using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;
@@ -932,6 +940,9 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
void CreateMetadataSlot(const MDNode *N);
+ /// Record a persistent slot and the metadata nodes referenced by it.
+ void CreatePersistentMetadataSlot(const MDNode *N);
+
/// CreateFunctionSlot - Insert the specified Value* into the slot table.
void CreateFunctionSlot(const Value *V);
@@ -1056,17 +1067,31 @@ static SlotTracker *createSlotTracker(const Value *V) {
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
-SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata)
- : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
+SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata,
+ bool UsePersistentMetadataIDs)
+ : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
+ UsePersistentMetadataIDs(UsePersistentMetadataIDs),
+ TrackPersistentMetadataDefinitions(UsePersistentMetadataIDs) {
+ assert((!ShouldInitializeAllMetadata || !UsePersistentMetadataIDs) &&
+ "cannot initialize compact metadata slots with persistent IDs");
+}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
-SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata)
+SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata,
+ bool UsePersistentMetadataIDs)
: TheModule(F ? F->getParent() : nullptr), TheFunction(F),
- ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
+ ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
+ UsePersistentMetadataIDs(UsePersistentMetadataIDs),
+ TrackPersistentMetadataDefinitions(false) {
+ assert((!ShouldInitializeAllMetadata || !UsePersistentMetadataIDs) &&
+ "cannot initialize compact metadata slots with persistent IDs");
+}
SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
- : TheModule(nullptr), ShouldInitializeAllMetadata(false), TheIndex(Index) {}
+ : TheModule(nullptr), ShouldInitializeAllMetadata(false),
+ UsePersistentMetadataIDs(false),
+ TrackPersistentMetadataDefinitions(false), TheIndex(Index) {}
inline void SlotTracker::initializeIfNeeded() {
if (TheModule) {
@@ -1095,7 +1120,8 @@ void SlotTracker::processModule() {
for (const GlobalVariable &Var : TheModule->globals()) {
if (!Var.hasName())
CreateModuleSlot(&Var);
- processGlobalObjectMetadata(Var);
+ if (!UsePersistentMetadataIDs)
+ processGlobalObjectMetadata(Var);
auto Attrs = Var.getAttributes();
if (Attrs.hasAttributes())
CreateAttributeSetSlot(Attrs);
@@ -1109,21 +1135,22 @@ void SlotTracker::processModule() {
for (const GlobalIFunc &I : TheModule->ifuncs()) {
if (!I.hasName())
CreateModuleSlot(&I);
- processGlobalObjectMetadata(I);
+ if (!UsePersistentMetadataIDs)
+ processGlobalObjectMetadata(I);
}
// Add metadata used by named metadata.
- for (const NamedMDNode &NMD : TheModule->named_metadata()) {
- for (const MDNode *N : NMD.operands())
- CreateMetadataSlot(N);
- }
+ if (!UsePersistentMetadataIDs)
+ for (const NamedMDNode &NMD : TheModule->named_metadata())
+ for (const MDNode *N : NMD.operands())
+ CreateMetadataSlot(N);
for (const Function &F : *TheModule) {
if (!F.hasName())
// Add all the unnamed functions to the table.
CreateModuleSlot(&F);
- if (ShouldInitializeAllMetadata)
+ if (ShouldInitializeAllMetadata && !UsePersistentMetadataIDs)
processFunctionMetadata(F);
// Add all the function attributes to the table.
@@ -1145,7 +1172,7 @@ void SlotTracker::processFunction() {
fNext = 0;
// Process function metadata if it wasn't hit at the module-level.
- if (!ShouldInitializeAllMetadata)
+ if (!ShouldInitializeAllMetadata && !UsePersistentMetadataIDs)
processFunctionMetadata(*TheFunction);
// Add all the function arguments with no names.
@@ -1318,13 +1345,26 @@ void SlotTracker::setProcessHook(
}
/// getMetadataSlot - Get the slot number of a MDNode.
-void SlotTracker::createMetadataSlot(const MDNode *N) { CreateMetadataSlot(N); }
+void SlotTracker::createMetadataSlot(const MDNode *N) {
+ if (UsePersistentMetadataIDs)
+ CreatePersistentMetadataSlot(N);
+ else
+ CreateMetadataSlot(N);
+}
/// getMetadataSlot - Get the slot number of a MDNode.
int SlotTracker::getMetadataSlot(const MDNode *N) {
// Check for uninitialized state and do lazy initialization.
initializeIfNeeded();
+ if (UsePersistentMetadataIDs) {
+ if (isa<DIExpression>(N))
+ return -1;
+ if (TrackPersistentMetadataDefinitions)
+ CreatePersistentMetadataSlot(N);
+ return N->getContext().pImpl->getMetadataPrintID(N);
+ }
+
// Find the MDNode in the module map
mdn_iterator MI = mdnMap.find(N);
return MI == mdnMap.end() ? -1 : (int)MI->second;
@@ -1435,6 +1475,22 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) {
CreateMetadataSlot(Op);
}
+void SlotTracker::CreatePersistentMetadataSlot(const MDNode *N) {
+ assert(N && "Can't insert a null Value into SlotTracker!");
+
+ if (isa<DIExpression>(N))
+ return;
+
+ unsigned ID = N->getContext().pImpl->getMetadataPrintID(N);
+ if (!mdnMap.try_emplace(N, ID).second)
+ return;
+ mdnNext = std::max(mdnNext, ID + 1);
+
+ for (const MDOperand &Op : N->operands())
+ if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
+ CreatePersistentMetadataSlot(OpNode);
+}
+
void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
assert(AS.hasAttributes() && "Doesn't need a slot!");
@@ -5021,14 +5077,25 @@ void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
}
void AssemblyWriter::writeAllMDNodes() {
- SmallVector<const MDNode *, 16> Nodes;
- Nodes.resize(Machine.mdn_size());
+ if (!Machine.usePersistentMetadataIDs()) {
+ SmallVector<const MDNode *, 16> Nodes;
+ Nodes.resize(Machine.mdn_size());
+ for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
+ Nodes[I.second] = cast<MDNode>(I.first);
+
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
+ writeMDNode(i, Nodes[i]);
+ return;
+ }
+
+ SmallVector<std::pair<unsigned, const MDNode *>, 16> Nodes;
+ Nodes.reserve(Machine.mdn_size());
for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
- Nodes[I.second] = cast<MDNode>(I.first);
+ Nodes.emplace_back(I.second, cast<MDNode>(I.first));
+ llvm::sort(Nodes);
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
- writeMDNode(i, Nodes[i]);
- }
+ for (auto [Slot, Node] : Nodes)
+ writeMDNode(Slot, Node);
}
void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
@@ -5099,7 +5166,8 @@ void AssemblyWriter::printUseLists(const Function *F) {
void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
- SlotTracker SlotTable(this->getParent());
+ SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
+ /*UsePersistentMetadataIDs=*/true);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5109,10 +5177,11 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder,
bool IsForDebug) const {
- SlotTracker SlotTable(this->getParent());
+ SlotTracker SlotTable(this->getParent(),
+ /*ShouldInitializeAllMetadata=*/false,
+ /*UsePersistentMetadataIDs=*/true);
formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
- IsForDebug,
+ AssemblyWriter W(OS, SlotTable, this->getModule(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
W.printBasicBlock(this);
}
@@ -5126,6 +5195,18 @@ void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
W.printModule(this);
}
+void Module::printWithPersistentMetadataIDs(raw_ostream &ROS,
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder,
+ bool IsForDebug) const {
+ SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
+ /*UsePersistentMetadataIDs=*/true);
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
+ ShouldPreserveUseListOrder);
+ W.printModule(this);
+}
+
void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
SlotTracker SlotTable(getParent());
formatted_raw_ostream OS(ROS);
@@ -5262,10 +5343,19 @@ void DbgLabelRecord::print(raw_ostream &ROS, ModuleSlotTracker &MST,
}
void Value::print(raw_ostream &ROS, bool IsForDebug) const {
+ if (const auto *F = dyn_cast<Function>(this)) {
+ F->print(ROS, nullptr, /*ShouldPreserveUseListOrder=*/false, IsForDebug);
+ return;
+ }
+ if (const auto *BB = dyn_cast<BasicBlock>(this)) {
+ BB->print(ROS, nullptr, /*ShouldPreserveUseListOrder=*/false, IsForDebug);
+ return;
+ }
+
bool ShouldInitializeAllMetadata = false;
if (auto *I = dyn_cast<Instruction>(this))
ShouldInitializeAllMetadata = isReferencingMDNode(*I);
- else if (isa<Function>(this) || isa<MetadataAsValue>(this))
+ else if (isa<MetadataAsValue>(this))
ShouldInitializeAllMetadata = true;
ModuleSlotTracker MST(getModuleFromVal(this), ShouldInitializeAllMetadata);
diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp
index 43671b0b9a1a3..61696bdbe24f7 100644
--- a/llvm/lib/IR/IRPrintingPasses.cpp
+++ b/llvm/lib/IR/IRPrintingPasses.cpp
@@ -30,20 +30,29 @@ class PrintModulePassWrapper : public ModulePass {
raw_ostream &OS;
std::string Banner;
bool ShouldPreserveUseListOrder;
+ bool UsePersistentMetadataIDs;
public:
static char ID;
- PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {}
+ PrintModulePassWrapper()
+ : ModulePass(ID), OS(dbgs()), ShouldPreserveUseListOrder(false),
+ UsePersistentMetadataIDs(true) {}
PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
- bool ShouldPreserveUseListOrder)
+ bool ShouldPreserveUseListOrder,
+ bool UsePersistentMetadataIDs)
: ModulePass(ID), OS(OS), Banner(Banner),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
+ UsePersistentMetadataIDs(UsePersistentMetadataIDs) {}
bool runOnModule(Module &M) override {
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
OS << Banner << "\n";
- M.print(OS, nullptr, ShouldPreserveUseListOrder);
+ if (UsePersistentMetadataIDs)
+ M.printWithPersistentMetadataIDs(OS, nullptr,
+ ShouldPreserveUseListOrder);
+ else
+ M.print(OS, nullptr, ShouldPreserveUseListOrder);
} else {
bool BannerPrinted = false;
for (const auto &F : M.functions()) {
@@ -80,10 +89,10 @@ class PrintFunctionPassWrapper : public FunctionPass {
// This pass just prints a banner followed by the function as it's processed.
bool runOnFunction(Function &F) override {
if (isFunctionInPrintList(F.getName())) {
- if (forcePrintModuleIR())
- OS << Banner << " (function: " << F.getName() << ")\n"
- << *F.getParent();
- else
+ if (forcePrintModuleIR()) {
+ OS << Banner << " (function: " << F.getName() << ")\n";
+ F.getParent()->printWithPersistentMetadataIDs(OS);
+ } else
OS << Banner << '\n' << static_cast<Value &>(F);
}
@@ -109,7 +118,16 @@ INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
const std::string &Banner,
bool ShouldPreserveUseListOrder) {
- return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
+ return createPrintModulePass(OS, Banner, ShouldPreserveUseListOrder,
+ /*UsePersistentMetadataIDs=*/false);
+}
+
+ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
+ const std::string &Banner,
+ bool ShouldPreserveUseListOrder,
+ bool UsePersistentMetadataIDs) {
+ return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder,
+ UsePersistentMetadataIDs);
}
FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 41c8a92c56eda..f357d62d71c66 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1611,6 +1611,18 @@ class LLVMContextImpl {
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
DenseSet<DIArgList *, DIArgListInfo> DIArgLists;
+ uint32_t NextMetadataPrintID = 0;
+
+ uint32_t allocateMetadataPrintID() {
+ assert(NextMetadataPrintID != UINT32_MAX && "too many metadata nodes");
+ return NextMetadataPrintID++;
+ }
+
+ uint32_t getMetadataPrintID(const MDNode *N) const {
+ assert(!N->isTemporary() && "temporary metadata has no print ID");
+ return N->getHeader().MetadataPrintID;
+ }
+
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index bbe75ab275092..c100f86397dca 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -393,7 +393,9 @@ class MPPassManager : public Pass, public PMDataManager {
/// createPrinterPass - Get a module printer pass.
Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const override {
- return createPrintModulePass(O, Banner);
+ return createPrintModulePass(O, Banner,
+ /*ShouldPreserveUseListOrder=*/false,
+ /*UsePersistentMetadataIDs=*/true);
}
/// run - Execute all of the passes scheduled for execution. Keep track of
@@ -481,7 +483,9 @@ class PassManagerImpl : public Pass,
/// createPrinterPass - Get a module printer pass.
Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const override {
- return createPrintModulePass(O, Banner);
+ return createPrintModulePass(O, Banner,
+ /*ShouldPreserveUseListOrder=*/false,
+ /*UsePersistentMetadataIDs=*/true);
}
/// run - Execute all of the passes scheduled for execution. Keep track of
@@ -1547,7 +1551,7 @@ MPPassManager::runOnModule(Module &M) {
BeforeStr.clear();
AfterStr.clear();
raw_svector_ostream OS(BeforeStr);
- M.print(OS, /*AAW=*/nullptr);
+ M.printWithPersistentMetadataIDs(OS);
}
{
@@ -1580,7 +1584,7 @@ MPPassManager::runOnModule(Module &M) {
if (ShouldPrintChanged) {
raw_svector_ostream OS(AfterStr);
- M.print(OS, /*AAW=*/nullptr);
+ M.printWithPersistentMetadataIDs(OS);
}
if (ReportChanged)
reportChangedIR(BeforeStr, AfterStr, MP->getPassName(), PassID,
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 0a4141ee2362e..c093fe66d27a5 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -650,6 +650,8 @@ StringRef MDString::getString() const {
void *MDNode::operator new(size_t Size, size_t NumOps, StorageType Storage) {
// uint64_t is the most aligned type we need support (ensured by static_assert
// above)
+ static_assert(sizeof(Header) == sizeof(size_t) + 2 * sizeof(uint32_t),
+ "MDNode header fields poorly packed");
size_t AllocSize =
alignTo(Header::getAllocSize(Storage, NumOps), alignof(uint64_t));
char *Mem = reinterpret_cast<char *>(::operator new(AllocSize + Size));
@@ -667,6 +669,9 @@ void MDNode::operator delete(void *N) {
MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2)
: Metadata(ID, Storage), Context(Context) {
+ if (!isTemporary())
+ getHeader().MetadataPrintID = Context.pImpl->allocateMetadataPrintID();
+
unsigned Op = 0;
for (Metadata *MD : Ops1)
setOperand(Op++, MD);
@@ -788,6 +793,7 @@ void MDNode::makeUniqued() {
// Make this 'uniqued'.
Storage = Uniqued;
+ getHeader().MetadataPrintID = getContext().pImpl->allocateMetadataPrintID();
countUnresolvedOperands();
if (!getNumUnresolved()) {
dropReplaceableUses();
@@ -1066,7 +1072,10 @@ void MDNode::deleteTemporary(MDNode *N) {
void MDNode::storeDistinctInContext() {
assert(!Context.hasReplaceableUses() && "Unexpected replaceable uses");
assert(!getNumUnresolved() && "Unexpected unresolved nodes");
+ const bool WasTemporary = isTemporary();
Storage = Distinct;
+ if (WasTemporary)
+ getHeader().MetadataPrintID = getContext().pImpl->allocateMetadataPrintID();
assert(isResolved() && "Expected this to be resolved");
// Reset the hash.
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index 08d58379b7e69..9b13f42ab0dc7 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -49,7 +49,9 @@ ModulePass::~ModulePass() = default;
Pass *ModulePass::createPrinterPass(raw_ostream &OS,
const std::string &Banner) const {
- return createPrintModulePass(OS, Banner);
+ return createPrintModulePass(OS, Banner,
+ /*ShouldPreserveUseListOrder=*/false,
+ /*UsePersistentMetadataIDs=*/true);
}
PassManagerType ModulePass::getPotentialPassManagerType() const {
diff --git a/llvm/lib/IRPrinter/IRPrintingPasses.cpp b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
index adb192ac4a916..73194c706c2ab 100644
--- a/llvm/lib/IRPrinter/IRPrintingPasses.cpp
+++ b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
@@ -23,19 +23,32 @@
using namespace llvm;
-PrintModulePass::PrintModulePass() : OS(dbgs()) {}
+PrintModulePass::PrintModulePass()
+ : OS(dbgs()), ShouldPreserveUseListOrder(false), EmitSummaryIndex(false),
+ UsePersistentMetadataIDs(true) {}
PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
bool ShouldPreserveUseListOrder,
bool EmitSummaryIndex)
+ : PrintModulePass(OS, Banner, ShouldPreserveUseListOrder, EmitSummaryIndex,
+ /*UsePersistentMetadataIDs=*/false) {}
+
+PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
+ bool ShouldPreserveUseListOrder,
+ bool EmitSummaryIndex,
+ bool UsePersistentMetadataIDs)
: OS(OS), Banner(Banner),
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
- EmitSummaryIndex(EmitSummaryIndex) {}
+ EmitSummaryIndex(EmitSummaryIndex),
+ UsePersistentMetadataIDs(UsePersistentMetadataIDs) {}
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
OS << Banner << "\n";
- M.print(OS, nullptr, ShouldPreserveUseListOrder);
+ if (UsePersistentMetadataIDs)
+ M.printWithPersistentMetadataIDs(OS, nullptr, ShouldPreserveUseListOrder);
+ else
+ M.print(OS, nullptr, ShouldPreserveUseListOrder);
} else {
bool BannerPrinted = false;
for (const auto &F : M.functions()) {
@@ -68,9 +81,10 @@ PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
PreservedAnalyses PrintFunctionPass::run(Function &F,
FunctionAnalysisManager &) {
if (isFunctionInPrintList(F.getName())) {
- if (forcePrintModuleIR())
- OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent();
- else
+ if (forcePrintModuleIR()) {
+ OS << Banner << " (function: " << F.getName() << ")\n";
+ F.getParent()->printWithPersistentMetadataIDs(OS);
+ } else
OS << Banner << '\n' << static_cast<Value &>(F);
}
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 177d8ecd3508d..7d8c830ea04f3 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -139,7 +139,10 @@ MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass(TM))
-MODULE_PASS("print", PrintModulePass(errs()))
+MODULE_PASS("print", PrintModulePass(errs(), /*Banner=*/"",
+ /*ShouldPreserveUseListOrder=*/false,
+ /*EmitSummaryIndex=*/false,
+ /*UsePersistentMetadataIDs=*/true))
MODULE_PASS("print-callgraph", CallGraphPrinterPass(errs()))
MODULE_PASS("print-callgraph-sccs", CallGraphSCCsPrinterPass(errs()))
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(errs()))
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 6f79f1b17a98d..aab9e83c11570 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -201,7 +201,7 @@ void printIR(raw_ostream &OS, const Function *F) {
void printIR(raw_ostream &OS, const Module *M) {
if (isFunctionInPrintList("*") || forcePrintModuleIR()) {
- M->print(OS, nullptr);
+ M->printWithPersistentMetadataIDs(OS);
} else {
for (const auto &F : M->functions()) {
printIR(OS, &F);
diff --git a/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll b/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
index fda04f6740575..d382e093932a4 100644
--- a/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
+++ b/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
@@ -1,11 +1,22 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-ipra \
; RUN: -print-after=DummyCGSCCPass -o - %s 2>&1 | FileCheck %s
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-ipra \
+; RUN: -print-after=DummyCGSCCPass -print-module-scope -o - %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=PERSISTENT
; REQUIRES: x86-registered-target
; The legacy CallGraphSCCPass printer should emit the banner as its own line.
; CHECK-LABEL: *** IR Dump After DummyCGSCCPass (DummyCGSCCPass) ***
; CHECK-NEXT: define void @bar() {
+; PERSISTENT-LABEL: *** IR Dump After DummyCGSCCPass (DummyCGSCCPass) ***
+; PERSISTENT: define void @bar() {
+; PERSISTENT: ret void, !annotation !1
+; PERSISTENT: !1 = !{!"used"}
+
define void @bar() {
- ret void
+ ret void, !annotation !1
}
+
+!0 = !{!"unused"}
+!1 = !{!"used"}
diff --git a/llvm/test/Other/print-changed-persistent-metadata-ids.ll b/llvm/test/Other/print-changed-persistent-metadata-ids.ll
new file mode 100644
index 0000000000000..bf755b01095c4
--- /dev/null
+++ b/llvm/test/Other/print-changed-persistent-metadata-ids.ll
@@ -0,0 +1,77 @@
+; RUN: opt -passes=instsimplify -filter-print-funcs=second \
+; RUN: -print-changed=quiet -disable-output < %s 2>&1 | FileCheck %s --check-prefix=CHANGED
+; RUN: opt -passes=instsimplify -filter-print-funcs=second \
+; RUN: -print-before=instsimplify -print-after=instsimplify \
+; RUN: -disable-output < %s 2>&1 | FileCheck %s --check-prefix=STABLE
+; RUN: opt -passes='function(instsimplify),globaldce' -filter-print-funcs=second \
+; RUN: -print-changed=quiet -print-module-scope -disable-output < %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CROSS-KIND
+; RUN: opt -passes='function(instsimplify),print' -disable-output < %s 2> %t
+; RUN: FileCheck %s --check-prefix=SPARSE < %t
+; RUN: opt -disable-output < %t
+; RUN: opt -S -passes='function(instsimplify)' < %s \
+; RUN: | FileCheck %s --check-prefix=COMPACT
+
+declare i32 @opaque(i32)
+
+ at dead = internal global i32 0
+
+define i32 @first(i32 %arg) #0 {
+ %keep = call i32 @opaque(i32 %arg)
+ ret i32 %keep
+}
+
+define i32 @second(i32 %arg) #1 {
+ %constant = add i32 2, 3, !annotation !0
+ %keep = call i32 @opaque(i32 %arg), !annotation !1, !other !3
+ %result = add i32 %keep, %constant
+ ret i32 %result
+}
+
+!0 = !{!"removed metadata"}
+!1 = !{!2}
+!2 = !{!"second metadata"}
+!3 = !{!"other metadata"}
+
+attributes #0 = { nounwind }
+attributes #1 = { noinline }
+
+; CHANGED: *** IR Dump After InstSimplifyPass on second ***
+; CHANGED: define i32 @second(i32 %arg) #1 {
+; CHANGED: %keep = call i32 @opaque(i32 %arg)
+; CHANGED-SAME: !annotation ![[ANNOTATION:[0-9]+]], !other ![[OTHER:[0-9]+]]
+
+; STABLE: *** IR Dump Before InstSimplifyPass on second ***
+; STABLE: %constant = add i32 2, 3, !annotation !{{[0-9]+}}
+; STABLE: %keep = call i32 @opaque(i32 %arg)
+; STABLE-SAME: !annotation ![[STABLE_ANNOTATION:[0-9]+]], !other ![[STABLE_OTHER:[0-9]+]]
+; STABLE: *** IR Dump After InstSimplifyPass on second ***
+; STABLE-NOT: %constant
+; STABLE: %keep = call i32 @opaque(i32 %arg)
+; STABLE-SAME: !annotation ![[STABLE_ANNOTATION]], !other ![[STABLE_OTHER]]
+
+; CROSS-KIND: *** IR Dump After InstSimplifyPass on second ***
+; CROSS-KIND: @dead = internal global i32 0
+; CROSS-KIND: define i32 @second(i32 %arg) #1 {
+; CROSS-KIND: %keep = call i32 @opaque(i32 %arg)
+; CROSS-KIND-SAME: !annotation ![[CROSS_ANNOTATION:[0-9]+]], !other ![[CROSS_OTHER:[0-9]+]]
+; CROSS-KIND: *** IR Dump After GlobalDCEPass on [module] ***
+; CROSS-KIND-NOT: @dead
+; CROSS-KIND: define i32 @second(i32 %arg) #1 {
+; CROSS-KIND: %keep = call i32 @opaque(i32 %arg)
+; CROSS-KIND-SAME: !annotation ![[CROSS_ANNOTATION]], !other ![[CROSS_OTHER]]
+
+; SPARSE: define i32 @second(i32 %arg) #1 {
+; SPARSE: %keep = call i32 @opaque(i32 %arg)
+; SPARSE-SAME: !annotation !1, !other !3
+; SPARSE-NOT: !0 =
+; SPARSE: !1 = !{!2}
+; SPARSE: !2 = !{!"second metadata"}
+; SPARSE: !3 = !{!"other metadata"}
+
+; COMPACT: define i32 @second(i32 %arg) #1 {
+; COMPACT: %keep = call i32 @opaque(i32 %arg)
+; COMPACT-SAME: !annotation !0, !other !2
+; COMPACT: !0 = !{!1}
+; COMPACT: !1 = !{!"second metadata"}
+; COMPACT: !2 = !{!"other metadata"}
diff --git a/llvm/test/Other/print-persistent-metadata-ids.ll b/llvm/test/Other/print-persistent-metadata-ids.ll
new file mode 100644
index 0000000000000..0fa89a6744fd1
--- /dev/null
+++ b/llvm/test/Other/print-persistent-metadata-ids.ll
@@ -0,0 +1,94 @@
+; RUN: opt -S -passes=no-op-module < %s | FileCheck %s --check-prefix=COMPACT
+; RUN: opt -disable-output -passes=print < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-MODULE
+; RUN: opt -disable-output -passes=print < %s 2> %t
+; RUN: opt -disable-output < %t
+; RUN: opt -disable-output -passes='function(print)' -filter-print-funcs=second \
+; RUN: < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-FUNCTION
+; RUN: opt -disable-output -passes='function(no-op-function)' \
+; RUN: -print-before=no-op-function -filter-print-funcs=second \
+; RUN: < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-FUNCTION
+; RUN: opt -disable-output -passes='function(no-op-function)' -print-after-all \
+; RUN: -filter-print-funcs=second < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-FUNCTION
+; RUN: opt -disable-output -passes=no-op-module -print-before=no-op-module \
+; RUN: -filter-print-funcs=first,second < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-MULTI
+; RUN: opt -disable-output -passes='loop(no-op-loop)' -print-before=no-op-loop \
+; RUN: -filter-print-funcs=loop < %s 2>&1 | FileCheck %s --check-prefix=PERSISTENT-LOOP
+; RUN: opt -disable-output -passes='print,function(print)' < %s 2>&1 | FileCheck %s --check-prefix=SAME-ID
+$group = comdat any
+
+ at named = global ptr @0, comdat($group), !annotation !5
+ at 0 = global i32 0
+ at 1 = global i32 1
+
+declare void @callee(ptr)
+
+define void @first() #0 {
+ call void @callee(ptr @0) #1
+ call void @callee(ptr @1) #1
+ ret void, !annotation !1
+}
+
+define void @second() {
+ call void @callee(ptr @1) #1, !annotation !3
+ ret void, !annotation !3
+}
+
+define void @loop() {
+entry:
+ call void @callee(ptr @0) #1
+ call void @callee(ptr @1) #1
+ br label %loop
+
+loop:
+ call void @callee(ptr @1) #1
+ br i1 false, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+attributes #0 = { noinline }
+attributes #1 = { nounwind }
+
+!named = !{!0}
+!0 = !{!"named metadata"}
+!1 = !{!2}
+!2 = !{!"first metadata"}
+!3 = !{!4}
+!4 = !{!"second metadata"}
+!5 = !{!6}
+!6 = !{!"global metadata"}
+
+; COMPACT: @named = global ptr @0, comdat($group), !annotation !0
+; COMPACT: ret void, !annotation !3
+; COMPACT: call void @callee(ptr @1) #1, !annotation !5
+; COMPACT: ret void, !annotation !5
+; COMPACT: !named = !{!2}
+
+; PERSISTENT-MODULE: @named = global ptr @0, comdat($group), !annotation !5
+; PERSISTENT-MODULE: ret void, !annotation !1
+; PERSISTENT-MODULE: call void @callee(ptr @1) #1, !annotation !3
+; PERSISTENT-MODULE: ret void, !annotation !3
+; PERSISTENT-MODULE: !named = !{!0}
+
+; PERSISTENT-FUNCTION: define void @second() {
+; PERSISTENT-FUNCTION: call void @callee(ptr @1) #1, !annotation ![[SECOND:[0-9]+]]
+; PERSISTENT-FUNCTION: ret void, !annotation ![[SECOND]]
+
+; PERSISTENT-MULTI: define void @first() #0 {
+; PERSISTENT-MULTI: call void @callee(ptr @0) #1
+; PERSISTENT-MULTI: call void @callee(ptr @1) #1
+; PERSISTENT-MULTI: define void @second() {
+; PERSISTENT-MULTI: call void @callee(ptr @1) #1
+
+; PERSISTENT-LOOP: ; Preheader:
+; PERSISTENT-LOOP: call void @callee(ptr @0) #1
+; PERSISTENT-LOOP: call void @callee(ptr @1) #1
+; PERSISTENT-LOOP: ; Loop:
+; PERSISTENT-LOOP: call void @callee(ptr @1) #1
+
+; SAME-ID: define void @second() {
+; SAME-ID: call void @callee(ptr @1) #1, !annotation ![[SAME_SECOND:[0-9]+]]
+; SAME-ID: ![[SAME_SECOND]] = !{!{{[0-9]+}}}
+; SAME-ID: define void @second() {
+; SAME-ID: call void @callee(ptr @1) #1, !annotation ![[SAME_SECOND]]
diff --git a/llvm/unittests/IR/AsmWriterTest.cpp b/llvm/unittests/IR/AsmWriterTest.cpp
index 75305f4e2dea4..e1e74c723664e 100644
--- a/llvm/unittests/IR/AsmWriterTest.cpp
+++ b/llvm/unittests/IR/AsmWriterTest.cpp
@@ -5,6 +5,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+#include "llvm/AsmParser/Parser.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
@@ -12,6 +13,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -62,6 +64,87 @@ TEST(AsmWriterTest, DumpDIExpression) {
EXPECT_EQ("!DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_deref)", S);
}
+TEST(AsmWriterTest, PersistentBasicBlockPrint) {
+ LLVMContext Ctx;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(R"(
+ @0 = global i32 0
+
+ declare void @use(ptr)
+
+ define void @f() !dbg !6 {
+ call void @use(ptr @0), !annotation !12
+ #dbg_value(i32 0, !9, !DIExpression(DW_OP_constu, 4), !11)
+ ret void, !annotation !12
+ }
+
+ define void @g() {
+ ret void
+ }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!5}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "test", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "t.ll", directory: "/")
+ !2 = !{}
+ !5 = !{i32 2, !"Debug Info Version", i32 3}
+ !6 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
+ !7 = !DISubroutineType(types: !2)
+ !8 = !{!9}
+ !9 = !DILocalVariable(name: "x", scope: !6, file: !1, line: 1, type: !10)
+ !10 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_unsigned)
+ !11 = !DILocation(line: 1, column: 1, scope: !6)
+ !12 = !{!"annotation"}
+ )",
+ Err, Ctx);
+ ASSERT_NE(M, nullptr);
+
+ std::string First;
+ raw_string_ostream FirstOS(First);
+ M->getFunction("f")->getEntryBlock().print(FirstOS);
+
+ std::string Second;
+ raw_string_ostream SecondOS(Second);
+ M->getFunction("f")->getEntryBlock().print(SecondOS);
+
+ EXPECT_EQ(First, Second);
+ EXPECT_THAT(First, HasSubstr("call void @use(ptr @0), !annotation !"));
+ EXPECT_THAT(First, HasSubstr("#dbg_value(i32 0, !"));
+ EXPECT_THAT(First, HasSubstr("!DIExpression(DW_OP_constu, 4)"));
+ EXPECT_THAT(First, HasSubstr("ret void, !annotation !"));
+
+ MDNode *Earlier = MDNode::getDistinct(Ctx, MDString::get(Ctx, "earlier"));
+ M->getFunction("f")->getEntryBlock().getTerminator()->setMetadata("order",
+ Earlier);
+ MDNode *Later = MDNode::getDistinct(Ctx, MDString::get(Ctx, "later"));
+ M->getFunction("g")->getEntryBlock().getTerminator()->setMetadata("order",
+ Later);
+
+ std::string LaterOutput;
+ raw_string_ostream LaterOS(LaterOutput);
+ M->getFunction("g")->getEntryBlock().print(LaterOS);
+
+ std::string EarlierOutput;
+ raw_string_ostream EarlierOS(EarlierOutput);
+ M->getFunction("f")->getEntryBlock().print(EarlierOS);
+
+ StringRef MetadataPrefix = "!order !";
+ size_t EarlierPos = EarlierOutput.find(MetadataPrefix);
+ size_t LaterPos = LaterOutput.find(MetadataPrefix);
+ ASSERT_NE(EarlierPos, StringRef::npos);
+ ASSERT_NE(LaterPos, StringRef::npos);
+ StringRef EarlierIDText =
+ StringRef(EarlierOutput).drop_front(EarlierPos + MetadataPrefix.size());
+ StringRef LaterIDText =
+ StringRef(LaterOutput).drop_front(LaterPos + MetadataPrefix.size());
+ unsigned EarlierID;
+ unsigned LaterID;
+ ASSERT_FALSE(EarlierIDText.consumeInteger(10, EarlierID));
+ ASSERT_FALSE(LaterIDText.consumeInteger(10, LaterID));
+ EXPECT_LT(EarlierID, LaterID);
+}
+
TEST(AsmWriterTest, PrintAddrspaceWithNullOperand) {
LLVMContext Ctx;
Module M("test module", Ctx);
>From 6d8821fa47791370cdc0bf09c66188c6de5f0906 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Wed, 19 Aug 2026 14:13:03 -0400
Subject: [PATCH 2/6] [IR] Handle temporary metadata in persistent printing
Temporary metadata has no persistent ID, so persistent printing could
assert or reuse ID zero.
Assign temporary nodes print-local slots after permanent IDs. Use one
enum for compact, persistent-reference, and persistent-definition modes.
---
llvm/lib/IR/AsmWriter.cpp | 89 ++++++++++++++++++-----------
llvm/lib/IR/LLVMContextImpl.h | 2 +
llvm/unittests/IR/AsmWriterTest.cpp | 41 +++++++++++++
3 files changed, 98 insertions(+), 34 deletions(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 5373eeb4373ce..7a1cefb468072 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -786,6 +786,14 @@ AbstractSlotTrackerStorage::~AbstractSlotTrackerStorage() = default;
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
+namespace {
+enum class MetadataPrintMode {
+ Compact,
+ PersistentReferences,
+ PersistentDefinitions,
+};
+} // end anonymous namespace
+
/// This class provides computation of slot numbers for LLVM Assembly writing.
///
class llvm::SlotTracker : public AbstractSlotTrackerStorage {
@@ -801,8 +809,7 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
const Function* TheFunction = nullptr;
bool FunctionProcessed = false;
bool ShouldInitializeAllMetadata;
- bool UsePersistentMetadataIDs;
- bool TrackPersistentMetadataDefinitions;
+ MetadataPrintMode MetadataMode;
std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
ProcessModuleHookFn;
@@ -851,20 +858,20 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// If \c ShouldInitializeAllMetadata, initializes all metadata in all
/// functions, giving correct numbering for metadata referenced only from
/// within a function (even if no functions have been initialized).
- explicit SlotTracker(const Module *M,
- bool ShouldInitializeAllMetadata = false,
- bool UsePersistentMetadataIDs = false);
+ explicit SlotTracker(
+ const Module *M, bool ShouldInitializeAllMetadata = false,
+ MetadataPrintMode MetadataMode = MetadataPrintMode::Compact);
/// Construct from a function, starting out in incorp state.
///
/// If \c ShouldInitializeAllMetadata, initializes all metadata in all
/// functions, giving correct numbering for metadata referenced only from
/// within a function (even if no functions have been initialized).
- /// If \c UsePersistentMetadataIDs, skips metadata enumeration and uses IDs
- /// stored in the LLVM context.
- explicit SlotTracker(const Function *F,
- bool ShouldInitializeAllMetadata = false,
- bool UsePersistentMetadataIDs = false);
+ /// Persistent modes skip metadata enumeration and use IDs stored in the
+ /// LLVM context.
+ explicit SlotTracker(
+ const Function *F, bool ShouldInitializeAllMetadata = false,
+ MetadataPrintMode MetadataMode = MetadataPrintMode::Compact);
/// Construct from a module summary index.
explicit SlotTracker(const ModuleSummaryIndex *Index);
@@ -915,7 +922,12 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
mdn_iterator mdn_end() { return mdnMap.end(); }
unsigned mdn_size() const { return mdnMap.size(); }
bool mdn_empty() const { return mdnMap.empty(); }
- bool usePersistentMetadataIDs() const { return UsePersistentMetadataIDs; }
+ bool usePersistentMetadataIDs() const {
+ return MetadataMode != MetadataPrintMode::Compact;
+ }
+ bool trackPersistentMetadataDefinitions() const {
+ return MetadataMode == MetadataPrintMode::PersistentDefinitions;
+ }
/// AttributeSet map iterators.
using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;
@@ -1068,30 +1080,35 @@ static SlotTracker *createSlotTracker(const Value *V) {
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata,
- bool UsePersistentMetadataIDs)
+ MetadataPrintMode MetadataMode)
: TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
- UsePersistentMetadataIDs(UsePersistentMetadataIDs),
- TrackPersistentMetadataDefinitions(UsePersistentMetadataIDs) {
- assert((!ShouldInitializeAllMetadata || !UsePersistentMetadataIDs) &&
+ MetadataMode(MetadataMode) {
+ assert((!ShouldInitializeAllMetadata || !usePersistentMetadataIDs()) &&
"cannot initialize compact metadata slots with persistent IDs");
+ if (usePersistentMetadataIDs()) {
+ assert(M && "persistent metadata IDs require a module");
+ mdnNext = M->getContext().pImpl->getNextMetadataPrintID();
+ }
}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata,
- bool UsePersistentMetadataIDs)
+ MetadataPrintMode MetadataMode)
: TheModule(F ? F->getParent() : nullptr), TheFunction(F),
ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
- UsePersistentMetadataIDs(UsePersistentMetadataIDs),
- TrackPersistentMetadataDefinitions(false) {
- assert((!ShouldInitializeAllMetadata || !UsePersistentMetadataIDs) &&
+ MetadataMode(MetadataMode) {
+ assert((!ShouldInitializeAllMetadata || !usePersistentMetadataIDs()) &&
"cannot initialize compact metadata slots with persistent IDs");
+ if (usePersistentMetadataIDs()) {
+ assert(F && "persistent metadata IDs require a function");
+ mdnNext = F->getContext().pImpl->getNextMetadataPrintID();
+ }
}
SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
: TheModule(nullptr), ShouldInitializeAllMetadata(false),
- UsePersistentMetadataIDs(false),
- TrackPersistentMetadataDefinitions(false), TheIndex(Index) {}
+ MetadataMode(MetadataPrintMode::Compact), TheIndex(Index) {}
inline void SlotTracker::initializeIfNeeded() {
if (TheModule) {
@@ -1120,7 +1137,7 @@ void SlotTracker::processModule() {
for (const GlobalVariable &Var : TheModule->globals()) {
if (!Var.hasName())
CreateModuleSlot(&Var);
- if (!UsePersistentMetadataIDs)
+ if (!usePersistentMetadataIDs())
processGlobalObjectMetadata(Var);
auto Attrs = Var.getAttributes();
if (Attrs.hasAttributes())
@@ -1135,12 +1152,12 @@ void SlotTracker::processModule() {
for (const GlobalIFunc &I : TheModule->ifuncs()) {
if (!I.hasName())
CreateModuleSlot(&I);
- if (!UsePersistentMetadataIDs)
+ if (!usePersistentMetadataIDs())
processGlobalObjectMetadata(I);
}
// Add metadata used by named metadata.
- if (!UsePersistentMetadataIDs)
+ if (!usePersistentMetadataIDs())
for (const NamedMDNode &NMD : TheModule->named_metadata())
for (const MDNode *N : NMD.operands())
CreateMetadataSlot(N);
@@ -1150,7 +1167,7 @@ void SlotTracker::processModule() {
// Add all the unnamed functions to the table.
CreateModuleSlot(&F);
- if (ShouldInitializeAllMetadata && !UsePersistentMetadataIDs)
+ if (ShouldInitializeAllMetadata && !usePersistentMetadataIDs())
processFunctionMetadata(F);
// Add all the function attributes to the table.
@@ -1172,7 +1189,7 @@ void SlotTracker::processFunction() {
fNext = 0;
// Process function metadata if it wasn't hit at the module-level.
- if (!ShouldInitializeAllMetadata && !UsePersistentMetadataIDs)
+ if (!ShouldInitializeAllMetadata && !usePersistentMetadataIDs())
processFunctionMetadata(*TheFunction);
// Add all the function arguments with no names.
@@ -1346,7 +1363,7 @@ void SlotTracker::setProcessHook(
/// getMetadataSlot - Get the slot number of a MDNode.
void SlotTracker::createMetadataSlot(const MDNode *N) {
- if (UsePersistentMetadataIDs)
+ if (usePersistentMetadataIDs())
CreatePersistentMetadataSlot(N);
else
CreateMetadataSlot(N);
@@ -1357,11 +1374,13 @@ int SlotTracker::getMetadataSlot(const MDNode *N) {
// Check for uninitialized state and do lazy initialization.
initializeIfNeeded();
- if (UsePersistentMetadataIDs) {
+ if (usePersistentMetadataIDs()) {
if (isa<DIExpression>(N))
return -1;
- if (TrackPersistentMetadataDefinitions)
+ if (trackPersistentMetadataDefinitions() || N->isTemporary())
CreatePersistentMetadataSlot(N);
+ if (N->isTemporary())
+ return mdnMap.lookup(N);
return N->getContext().pImpl->getMetadataPrintID(N);
}
@@ -1481,10 +1500,12 @@ void SlotTracker::CreatePersistentMetadataSlot(const MDNode *N) {
if (isa<DIExpression>(N))
return;
- unsigned ID = N->getContext().pImpl->getMetadataPrintID(N);
+ unsigned ID =
+ N->isTemporary() ? mdnNext : N->getContext().pImpl->getMetadataPrintID(N);
if (!mdnMap.try_emplace(N, ID).second)
return;
- mdnNext = std::max(mdnNext, ID + 1);
+ if (N->isTemporary())
+ ++mdnNext;
for (const MDOperand &Op : N->operands())
if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
@@ -5167,7 +5188,7 @@ void AssemblyWriter::printUseLists(const Function *F) {
void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ MetadataPrintMode::PersistentReferences);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5179,7 +5200,7 @@ void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool IsForDebug) const {
SlotTracker SlotTable(this->getParent(),
/*ShouldInitializeAllMetadata=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ MetadataPrintMode::PersistentReferences);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getModule(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5200,7 +5221,7 @@ void Module::printWithPersistentMetadataIDs(raw_ostream &ROS,
bool ShouldPreserveUseListOrder,
bool IsForDebug) const {
SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ MetadataPrintMode::PersistentDefinitions);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
ShouldPreserveUseListOrder);
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index f357d62d71c66..30be08c32afba 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1618,6 +1618,8 @@ class LLVMContextImpl {
return NextMetadataPrintID++;
}
+ uint32_t getNextMetadataPrintID() const { return NextMetadataPrintID; }
+
uint32_t getMetadataPrintID(const MDNode *N) const {
assert(!N->isTemporary() && "temporary metadata has no print ID");
return N->getHeader().MetadataPrintID;
diff --git a/llvm/unittests/IR/AsmWriterTest.cpp b/llvm/unittests/IR/AsmWriterTest.cpp
index e1e74c723664e..5a4421d5daef0 100644
--- a/llvm/unittests/IR/AsmWriterTest.cpp
+++ b/llvm/unittests/IR/AsmWriterTest.cpp
@@ -145,6 +145,47 @@ TEST(AsmWriterTest, PersistentBasicBlockPrint) {
EXPECT_LT(EarlierID, LaterID);
}
+TEST(AsmWriterTest, PersistentPrintTemporaryMetadata) {
+ LLVMContext Ctx;
+ Module M("test", Ctx);
+ Function *F = Function::Create(
+ FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false),
+ Function::ExternalLinkage, "f", M);
+ BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F);
+ ReturnInst *Ret = ReturnInst::Create(Ctx, BB);
+
+ MDNode *Permanent = MDNode::getDistinct(Ctx, MDString::get(Ctx, "permanent"));
+ TempMDNode Temporary = MDNode::getTemporary(Ctx, Permanent);
+ Ret->setMetadata("permanent", Permanent);
+ Ret->setMetadata("temporary", Temporary.get());
+
+ std::string FunctionText;
+ raw_string_ostream FunctionOS(FunctionText);
+ F->print(FunctionOS);
+ EXPECT_THAT(FunctionText, HasSubstr("!permanent !0"));
+ EXPECT_THAT(FunctionText, HasSubstr("!temporary !1"));
+
+ std::string BasicBlockText;
+ raw_string_ostream BasicBlockOS(BasicBlockText);
+ BB->print(BasicBlockOS);
+ EXPECT_THAT(BasicBlockText, HasSubstr("!permanent !0"));
+ EXPECT_THAT(BasicBlockText, HasSubstr("!temporary !1"));
+
+ std::string ModuleText;
+ raw_string_ostream ModuleOS(ModuleText);
+ M.printWithPersistentMetadataIDs(ModuleOS);
+ EXPECT_THAT(ModuleText, HasSubstr("!0 = distinct !{!\"permanent\"}"));
+ EXPECT_THAT(ModuleText, HasSubstr("!1 = <temporary!> !{!0}"));
+
+ MDNode *Later = MDNode::getDistinct(Ctx, MDString::get(Ctx, "later"));
+ Ret->setMetadata("later", Later);
+ std::string LaterText;
+ raw_string_ostream LaterOS(LaterText);
+ F->print(LaterOS);
+ EXPECT_THAT(LaterText, HasSubstr("!later !1"));
+ EXPECT_THAT(LaterText, HasSubstr("!temporary !2"));
+}
+
TEST(AsmWriterTest, PrintAddrspaceWithNullOperand) {
LLVMContext Ctx;
Module M("test module", Ctx);
>From 283d69e54b80bad19296ba863ff9625d177e5aba Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Wed, 19 Aug 2026 14:34:01 -0400
Subject: [PATCH 3/6] [IR] Use fixed-width MDNode header bitfields
Use uint32_t for the existing MDNode header bitfields so the metadata
print ID remains a separate uint32_t field on all hosts.
---
llvm/include/llvm/IR/Metadata.h | 8 ++++----
llvm/lib/IR/LLVMContextImpl.h | 5 +----
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index b108e42e06ce0..6739400e548aa 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1079,10 +1079,10 @@ class MDNode : public Metadata {
/// Explicity set alignment because bitfields by default have an
/// alignment of 1 on z/OS.
struct alignas(alignof(size_t)) Header {
- size_t IsResizable : 1;
- size_t IsLarge : 1;
- size_t SmallSize : 4;
- size_t SmallNumOps : 4;
+ uint32_t IsResizable : 1;
+ uint32_t IsLarge : 1;
+ uint32_t SmallSize : 4;
+ uint32_t SmallNumOps : 4;
uint32_t MetadataPrintID = 0;
unsigned NumUnresolved = 0;
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 30be08c32afba..d6915bd4439db 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1613,10 +1613,7 @@ class LLVMContextImpl {
uint32_t NextMetadataPrintID = 0;
- uint32_t allocateMetadataPrintID() {
- assert(NextMetadataPrintID != UINT32_MAX && "too many metadata nodes");
- return NextMetadataPrintID++;
- }
+ uint32_t allocateMetadataPrintID() { return NextMetadataPrintID++; }
uint32_t getNextMetadataPrintID() const { return NextMetadataPrintID; }
>From 68111c7db3fa148022a022de5b342570fc444da6 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Wed, 19 Aug 2026 17:51:34 -0400
Subject: [PATCH 4/6] [IR] Update tests for persistent metadata IDs
Persistent metadata IDs can change metadata definition order and the IDs shown by generated analysis output. Update the affected checks to match the new stable numbering.
---
llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll | 4 ++--
.../Inputs/loop-distribute.ll.expected | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
index c207ed5100408..1007404411d8f 100644
--- a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
@@ -14,9 +14,9 @@
; CHECK-IR: %math = extractvalue { i32, i1 } %[[R1]], 0
; CHECK-IR: %ov = extractvalue { i32, i1 } %[[R1]], 1
; Type/Name attributes of the value.
-; CHECK-IR: ![[#MD1]] = !{{[{]}}![[#MD2:]], !""{{[}]}}
+; CHECK-IR-DAG: ![[#MD1]] = !{{[{]}}![[#MD2:]], !""{{[}]}}
; Origin data type of the value.
-; CHECK-IR: ![[#MD2]] = !{{[{]}}{{[{]}} i32, i1 {{[}]}} poison{{[}]}}
+; CHECK-IR-DAG: ![[#MD2]] = !{{[{]}}{{[{]}} i32, i1 {{[}]}} poison{{[}]}}
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=irtranslator 2>&1 | FileCheck %s --check-prefix=CHECK-GMIR
; Required info succeeded to get through IRTranslator.
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
index b2cd7cc79a70c..e3e62c44f6ce4 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
@@ -72,12 +72,12 @@ define void @ldist(i1 %cond, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body.ldist1: ; preds = %if.end.ldist1, %for.body.ph.ldist1
; CHECK-NEXT: %iv.ldist1 = phi i16 [ 0, %for.body.ph.ldist1 ], [ %iv.next.ldist1, %if.end.ldist1 ]
-; CHECK-NEXT: %lv.ldist1 = load i16, ptr %A, align 1, !alias.scope !2, !noalias !5
-; CHECK-NEXT: store i16 %lv.ldist1, ptr %A, align 1, !alias.scope !2, !noalias !5
+; CHECK-NEXT: %lv.ldist1 = load i16, ptr %A, align 1, !alias.scope !5, !noalias !4
+; CHECK-NEXT: store i16 %lv.ldist1, ptr %A, align 1, !alias.scope !5, !noalias !4
; CHECK-NEXT: br i1 %cond, label %if.then.ldist1, label %if.end.ldist1
; CHECK-EMPTY:
; CHECK-NEXT: if.then.ldist1: ; preds = %for.body.ldist1
-; CHECK-NEXT: %lv2.ldist1 = load i16, ptr %A, align 1, !alias.scope !2, !noalias !5
+; CHECK-NEXT: %lv2.ldist1 = load i16, ptr %A, align 1, !alias.scope !5, !noalias !4
; CHECK-NEXT: br label %if.end.ldist1
; CHECK-EMPTY:
; CHECK-NEXT: if.end.ldist1: ; preds = %if.then.ldist1, %for.body.ldist1
>From 68a6c992ef39716f99aa486999f6b8c7abecaad7 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Thu, 20 Aug 2026 17:40:56 -0400
Subject: [PATCH 5/6] [IR] Preserve canonical metadata numbering in final
output
Persistent metadata IDs make pass snapshots stable, but they should not
change normal textual output.
Renumber metadata at canonical printing boundaries while retaining stored
IDs for diagnostic snapshots. Extend MIR and standalone metadata parsing
so their IDs remain consistent.
---
clang/lib/CodeGen/BackendUtil.cpp | 10 +-
clang/tools/cir-translate/cir-translate.cpp | 1 +
.../clang-fuzzer/handle-llvm/handle_llvm.cpp | 2 +-
.../clang-import-test/clang-import-test.cpp | 4 +-
.../include/flang/Optimizer/CodeGen/CodeGen.h | 8 +-
flang/lib/Frontend/FrontendActions.cpp | 6 +-
llvm/include/llvm/AsmParser/LLParser.h | 2 +
llvm/include/llvm/AsmParser/Parser.h | 6 +
.../llvm/CodeGen/MachineModuleSlotTracker.h | 17 +-
llvm/include/llvm/IR/IRPrintingPasses.h | 8 +-
llvm/include/llvm/IR/Metadata.h | 2 +-
llvm/include/llvm/IR/Module.h | 10 +-
llvm/include/llvm/IR/ModuleSlotTracker.h | 40 +-
.../include/llvm/IRPrinter/IRPrintingPasses.h | 22 +-
llvm/lib/Analysis/CallGraphSCCPass.cpp | 4 +-
llvm/lib/Analysis/LoopInfo.cpp | 2 +-
llvm/lib/AsmParser/LLParser.cpp | 26 ++
llvm/lib/AsmParser/Parser.cpp | 10 +
llvm/lib/CodeGen/MIRParser/MIParser.cpp | 4 +-
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 45 +-
llvm/lib/CodeGen/MIRPrinter.cpp | 5 +-
llvm/lib/CodeGen/MachineBasicBlock.cpp | 2 +-
llvm/lib/CodeGen/MachineModuleSlotTracker.cpp | 84 ++--
llvm/lib/CodeGen/MachineOperand.cpp | 2 +-
llvm/lib/IR/AsmWriter.cpp | 417 +++++++-----------
llvm/lib/IR/Core.cpp | 2 +
llvm/lib/IR/IRPrintingPasses.cpp | 98 ++--
llvm/lib/IR/LLVMContextImpl.h | 7 +-
llvm/lib/IR/LegacyPassManager.cpp | 12 +-
llvm/lib/IR/Metadata.cpp | 7 +-
llvm/lib/IR/Pass.cpp | 4 +-
llvm/lib/IR/SSAContext.cpp | 2 +-
llvm/lib/IRPrinter/IRPrintingPasses.cpp | 31 +-
llvm/lib/Passes/PassRegistry.def | 5 +-
llvm/lib/Passes/StandardInstrumentations.cpp | 14 +-
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 28 +-
.../Analysis/BasicAA/noalias-scope-decl.ll | 8 +-
.../Analysis/CostModel/X86/free-intrinsics.ll | 4 +-
.../CostModel/free-intrinsics-datalayout.ll | 4 +-
.../CostModel/free-intrinsics-no_info.ll | 4 +-
llvm/test/Analysis/DependenceAnalysis/AA.ll | 18 +-
.../loops-with-indirect-reads-and-writes.ll | 14 +-
.../LoopAccessAnalysis/noalias-scope-decl.ll | 8 +-
.../underlying-object-loop-varying-phi.ll | 4 +-
.../Analysis/MemorySSA/invariant-groups.ll | 6 +-
.../MemorySSA/invariant-load-intrinsic.ll | 8 +-
.../Analysis/ScalarEvolution/cycled_phis.ll | 8 +-
.../Analysis/ScalarEvolution/unknown_phis.ll | 8 +-
.../Analysis/ScopedNoAliasAA/basic-domains.ll | 25 +-
llvm/test/Analysis/ScopedNoAliasAA/basic.ll | 8 +-
llvm/test/Analysis/ScopedNoAliasAA/basic2.ll | 25 +-
.../TypeBasedAliasAnalysis/placement-tbaa.ll | 2 +-
.../TypeBasedAliasAnalysis/tbaa-path.ll | 24 +-
.../ValueTracking/memory-dereferenceable.ll | 4 +-
.../GlobalISel/irtranslator-metadata.ll | 2 +-
.../AMDGPU/dbg-value-ends-sched-region.mir | 2 +-
.../AMDGPU/rewrite-partial-reg-uses-dbg.mir | 26 +-
...ip-processing-stack-arg-dbg-value-list.mir | 6 +-
...ip-processing-stack-arg-dbg-value-list.mir | 6 +-
.../DirectX/DebugInfo/di-globalvariable.ll | 6 +
.../MIRDebugify/locations-and-values.mir | 12 +-
.../dont-strip-real-debug-info.mir | 4 +-
.../MIR/X86/instructions-debug-location.mir | 17 +-
.../MIR/X86/machine-metadata-specialized.mir | 30 ++
.../test/CodeGen/X86/machine-sink-dbg-loc.mir | 6 +-
.../X86/win64-eh-unwindv2-too-many-instr.mir | 10 +-
llvm/test/DebugInfo/Generic/debug-label-mi.ll | 4 +-
.../test/DebugInfo/Generic/debug-label-opt.ll | 4 +-
llvm/test/DebugInfo/Generic/invalid.ll | 4 +-
.../DebugInfo/KeyInstructions/X86/parse.mir | 4 +-
.../InstrRef/undef-phi-through-regalloc.mir | 2 +-
.../DebugInfo/MIR/X86/merge-inline-loc1.mir | 5 +-
.../DebugInfo/MIR/X86/merge-inline-loc2.mir | 5 +-
.../DebugInfo/MIR/X86/merge-inline-loc3.mir | 4 +-
.../DebugInfo/MIR/X86/merge-inline-loc4.mir | 4 +-
.../X86/branch-folder-dbg-after-end.mir | 4 +-
llvm/test/DebugInfo/X86/branch-folder-dbg.mir | 4 +-
.../X86/machinecse-wrongdebug-hoist.ll | 4 +-
.../legacy-callgraph-scc-pass-printer.ll | 4 +-
.../print-changed-persistent-metadata-ids.ll | 8 +-
.../Other/print-persistent-metadata-ids.ll | 10 +-
.../unrecorded-live-at-sp.ll | 2 +-
llvm/test/Transforms/IRCE/only-lower-check.ll | 2 +-
llvm/test/Transforms/IRCE/only-upper-check.ll | 2 +-
.../VPlan/vplan-printing-metadata.ll | 36 +-
.../LoopVectorize/VPlan/vplan-printing.ll | 8 +-
.../MemProfContextDisambiguation/inlined2.ll | 2 +-
.../Passes/Other/print_region_pass.ll | 14 +-
.../RemoveDI/di-subroutine-localvar.ll | 4 +-
llvm/test/Verifier/absolute_symbol.ll | 13 +-
llvm/test/Verifier/associated-metadata.ll | 14 +-
llvm/test/Verifier/commandline-meta1.ll | 2 +-
.../test/Verifier/dbg-orphaned-compileunit.ll | 2 +-
llvm/test/Verifier/di-subroutine-localvar.ll | 4 +-
llvm/test/Verifier/function-metadata-bad.ll | 8 +-
llvm/test/Verifier/ident-meta1.ll | 3 +-
.../llvm.loop.estimated_trip_count.ll | 6 +-
.../mdcompositetype-templateparams-tuple.ll | 6 +-
.../mdcompositetype-templateparams.ll | 8 +-
llvm/test/Verifier/module-flags-cgprofile.ll | 4 +-
llvm/test/Verifier/noalias-addrspace.ll | 9 +-
llvm/test/Verifier/noalias_scope_decl.ll | 6 +-
llvm/test/Verifier/ref.ll | 8 +-
llvm/test/Verifier/reloc-none.ll | 2 +-
llvm/test/tools/llubi/metadata.ll | 20 +-
llvm/test/tools/llubi/metadata_noundef_ub.ll | 2 +-
llvm/test/tools/llubi/noalias_scope.ll | 2 +-
.../IR/01-ir-print-basic-details.test | 22 +-
.../IR/01-ir-select-logical-elements.test | 16 +-
.../IR/02-ir-logical-lines.test | 4 +-
.../IR/06-ir-full-logical-view.test | 22 +-
llvm/tools/llvm-dis/llvm-dis.cpp | 1 +
llvm/tools/llvm-extract/llvm-extract.cpp | 4 +-
llvm/tools/llvm-link/llvm-link.cpp | 1 +
llvm/tools/llvm-reduce/ReducerWorkItem.cpp | 1 +
llvm/tools/llvm-split/llvm-split.cpp | 7 +-
llvm/tools/llvm-stress/llvm-stress.cpp | 1 +
llvm/tools/opt/NewPMDriver.cpp | 2 +-
llvm/tools/opt/optdriver.cpp | 6 +-
.../verify-uselistorder.cpp | 9 +-
llvm/unittests/IR/AsmWriterTest.cpp | 6 +-
llvm/unittests/IR/MetadataTest.cpp | 18 +-
llvm/unittests/IR/ModuleTest.cpp | 1 +
llvm/unittests/MIR/MachineMetadata.cpp | 80 ++--
mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp | 1 +
125 files changed, 898 insertions(+), 821 deletions(-)
create mode 100644 llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index e55d242cde68a..a22fb58fddc4e 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1175,8 +1175,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
MPM.addPass(ThinLTOBitcodeWriterPass(
*OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
} else if (Action == Backend_EmitLL) {
- MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
- /*EmitLTOSummary=*/true));
+ MPM.addPass(PrintCanonicalModulePass(*OS, "",
+ CodeGenOpts.EmitLLVMUseLists,
+ /*EmitLTOSummary=*/true));
}
} else {
// Emit a module summary by default for Regular LTO except for ld64
@@ -1193,8 +1194,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
EmitLTOSummary));
} else if (Action == Backend_EmitLL) {
- MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ MPM.addPass(PrintCanonicalModulePass(
+ *OS, "", CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
}
}
@@ -1466,6 +1467,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
break;
case Backend_EmitLL:
Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
+ M->renumberMetadataForAssembly();
M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
return false;
};
diff --git a/clang/tools/cir-translate/cir-translate.cpp b/clang/tools/cir-translate/cir-translate.cpp
index 4452741d7433e..a58512e3fca22 100644
--- a/clang/tools/cir-translate/cir-translate.cpp
+++ b/clang/tools/cir-translate/cir-translate.cpp
@@ -165,6 +165,7 @@ void registerToLLVMTranslation() {
enableOpenMP);
if (!llvmModule)
return mlir::failure();
+ llvmModule->renumberMetadataForAssembly();
llvmModule->print(output, nullptr);
return mlir::success();
},
diff --git a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
index 942e35c30e19f..8d03b51c809cd 100644
--- a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -103,7 +103,7 @@ static void RunOptimizationPasses(raw_ostream &OS, Module &M,
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
ModulePassManager MPM = PB.buildPerModuleDefaultPipeline(OL);
- MPM.addPass(PrintModulePass(OS));
+ MPM.addPass(PrintCanonicalModulePass(OS));
MPM.run(M, MAM);
}
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 8e83687d3e96a..bcb5d2bdb8952 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -338,8 +338,10 @@ llvm::Expected<CIAndOrigins> Parse(const std::string &Path,
if (llvm::Error PE = ParseSource(Path, CI.getCompilerInstance(), Consumers))
return std::move(PE);
CI.getDiagnosticClient().EndSourceFile();
- if (ShouldDumpIR)
+ if (ShouldDumpIR) {
+ CG.GetModule()->renumberMetadataForAssembly();
CG.GetModule()->print(llvm::outs(), nullptr);
+ }
if (CI.getDiagnosticClient().getNumErrors())
return llvm::make_error<llvm::StringError>(
"Errors occurred while parsing the expression.", std::error_code());
diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
index b7a9397edfe6d..a7adc20b953c2 100644
--- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h
+++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
@@ -78,9 +78,11 @@ using LLVMIRLoweringPrinter =
/// Convert the LLVM IR dialect to LLVM-IR proper
std::unique_ptr<mlir::Pass> createLLVMDialectToLLVMPass(
- llvm::raw_ostream &output,
- LLVMIRLoweringPrinter printer =
- [](llvm::Module &m, llvm::raw_ostream &out) { m.print(out, nullptr); });
+ llvm::raw_ostream &output, LLVMIRLoweringPrinter printer =
+ [](llvm::Module &m, llvm::raw_ostream &out) {
+ m.renumberMetadataForAssembly();
+ m.print(out, nullptr);
+ });
/// Populate the given list with patterns that convert from FIR to LLVM.
void populateFIRToLLVMConversionPatterns(
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index e21590cc9fa7f..a0a6056d7215e 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1092,9 +1092,9 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
os, /*ShouldPreserveUseListOrder=*/false, emitSummary));
}
} else if (action == BackendActionTy::Backend_EmitLL) {
- mpm.addPass(llvm::PrintModulePass(os, /*Banner=*/"",
- /*ShouldPreserveUseListOrder=*/false,
- emitSummary));
+ mpm.addPass(llvm::PrintCanonicalModulePass(
+ os, /*Banner=*/"", /*ShouldPreserveUseListOrder=*/false,
+ emitSummary));
}
}
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 788b56cb78f08..586016508e044 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -235,6 +235,8 @@ namespace llvm {
unsigned &Read,
const SlotMapping *Slots);
+ LLVM_ABI bool parseMetadataDefinitions(SlotMapping &Slots);
+
LLVMContext &getContext() { return Context; }
private:
diff --git a/llvm/include/llvm/AsmParser/Parser.h b/llvm/include/llvm/AsmParser/Parser.h
index 22b0881d92b53..2908323336e1d 100644
--- a/llvm/include/llvm/AsmParser/Parser.h
+++ b/llvm/include/llvm/AsmParser/Parser.h
@@ -211,6 +211,12 @@ parseDIExpressionBodyAtBeginning(StringRef Asm, unsigned &Read,
SMDiagnostic &Err, const Module &M,
const SlotMapping *Slots);
+/// Parse a sequence of standalone metadata definitions using and updating the
+/// supplied slot mapping.
+/// \return true on error.
+LLVM_ABI bool parseMetadataDefinitions(StringRef Asm, SMDiagnostic &Err,
+ const Module &M, SlotMapping &Slots);
+
} // End llvm namespace
#endif
diff --git a/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h b/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
index 666b3caf67e27..6cfcf579abc11 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
@@ -10,6 +10,7 @@
#define LLVM_CODEGEN_MACHINEMODULESLOTTRACKER_H
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/Support/Compiler.h"
@@ -24,23 +25,19 @@ class Module;
using MFGetterFnT = function_ref<MachineFunction *(const Function &)>;
class LLVM_ABI MachineModuleSlotTracker : public ModuleSlotTracker {
- const Function &TheFunction;
const MachineFunction *TheMF;
- unsigned MDNStartSlot = 0, MDNEndSlot = 0;
+ MachineMDNodeListType MachineMDNodes;
+ void collectMachineFunctionMetadata(SmallVectorImpl<const MDNode *> &Metadata,
+ const MachineFunction &MF) const;
void processMachineFunctionMetadata(AbstractSlotTrackerStorage *AST,
- const MachineFunction &MF);
- void processMachineModule(AbstractSlotTrackerStorage *AST, const Module *M,
- bool ShouldInitializeAllMetadata);
- void processMachineFunction(AbstractSlotTrackerStorage *AST,
- const Function *F,
- bool ShouldInitializeAllMetadata);
+ const MachineFunction &MF) const;
public:
- MachineModuleSlotTracker(MFGetterFnT Fn, const MachineFunction *MF,
- bool ShouldInitializeAllMetadata = true);
+ MachineModuleSlotTracker(MFGetterFnT Fn, const MachineFunction *MF);
~MachineModuleSlotTracker() override;
+ void renumberMetadataForAssembly();
void collectMachineMDNodes(MachineMDNodeListType &L) const;
};
diff --git a/llvm/include/llvm/IR/IRPrintingPasses.h b/llvm/include/llvm/IR/IRPrintingPasses.h
index a7803e39d3b89..9e146b2d5eb5d 100644
--- a/llvm/include/llvm/IR/IRPrintingPasses.h
+++ b/llvm/include/llvm/IR/IRPrintingPasses.h
@@ -31,10 +31,10 @@ LLVM_ABI ModulePass *
createPrintModulePass(raw_ostream &OS, const std::string &Banner = "",
bool ShouldPreserveUseListOrder = false);
-LLVM_ABI ModulePass *createPrintModulePass(raw_ostream &OS,
- const std::string &Banner,
- bool ShouldPreserveUseListOrder,
- bool UsePersistentMetadataIDs);
+/// Create and return a pass that writes canonical module assembly.
+LLVM_ABI ModulePass *
+createPrintCanonicalModulePass(raw_ostream &OS, const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false);
/// Create and return a pass that prints functions to the specified
/// \c raw_ostream as they are processed.
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 6739400e548aa..a53cb63ed59cf 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1083,7 +1083,7 @@ class MDNode : public Metadata {
uint32_t IsLarge : 1;
uint32_t SmallSize : 4;
uint32_t SmallNumOps : 4;
- uint32_t MetadataPrintID = 0;
+ uint32_t MetadataPrintID;
unsigned NumUnresolved = 0;
using LargeStorageVector = SmallVector<MDOperand, 0>;
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 93393bbef2704..d6250e44648a0 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -987,12 +987,10 @@ class LLVM_ABI Module {
bool ShouldPreserveUseListOrder = false,
bool IsForDebug = false) const;
- /// Print the module using metadata IDs that stay stable across pass-debug
- /// snapshots. Unlike canonical module output, these IDs may contain gaps.
- void printWithPersistentMetadataIDs(raw_ostream &OS,
- AssemblyAnnotationWriter *AAW = nullptr,
- bool ShouldPreserveUseListOrder = false,
- bool IsForDebug = false) const;
+ /// Renumber the IDs stored in metadata nodes into canonical assembly order.
+ /// This mutates the IDs and should only be used immediately before final
+ /// assembly output.
+ void renumberMetadataForAssembly();
/// Dump the module to stderr (for debugging).
void dump() const;
diff --git a/llvm/include/llvm/IR/ModuleSlotTracker.h b/llvm/include/llvm/IR/ModuleSlotTracker.h
index a3882a81e1177..daae70c91d75b 100644
--- a/llvm/include/llvm/IR/ModuleSlotTracker.h
+++ b/llvm/include/llvm/IR/ModuleSlotTracker.h
@@ -9,6 +9,7 @@
#ifndef LLVM_IR_MODULESLOTTRACKER_H
#define LLVM_IR_MODULESLOTTRACKER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
#include <functional>
#include <memory>
@@ -28,8 +29,6 @@ class LLVM_ABI AbstractSlotTrackerStorage {
public:
virtual ~AbstractSlotTrackerStorage();
- virtual unsigned getNextMetadataSlot() = 0;
-
virtual void createMetadataSlot(const MDNode *) = 0;
virtual int getMetadataSlot(const MDNode *) = 0;
};
@@ -43,20 +42,31 @@ class LLVM_ABI AbstractSlotTrackerStorage {
/// If the IR changes from underneath \a ModuleSlotTracker, strings like
/// "<badref>" will be printed, or, worse, the wrong slots entirely.
class LLVM_ABI ModuleSlotTracker {
+public:
+ using MachineMDNodeListType =
+ std::vector<std::pair<unsigned, const MDNode *>>;
+
+private:
/// Storage for a slot tracker.
std::unique_ptr<SlotTracker> MachineStorage;
bool ShouldCreateStorage = false;
- bool ShouldInitializeAllMetadata = false;
const Module *M = nullptr;
const Function *F = nullptr;
SlotTracker *Machine = nullptr;
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)>
ProcessModuleHookFn;
- std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)>
ProcessFunctionHookFn;
+protected:
+ /// Renumber module metadata and then additional metadata for canonical
+ /// assembly output.
+ void renumberMetadataForAssembly(
+ ArrayRef<const MDNode *> AdditionalMetadata,
+ MachineMDNodeListType *AdditionalMetadataNodes = nullptr) const;
+
public:
/// Wrap a preinitialized SlotTracker.
ModuleSlotTracker(SlotTracker &Machine, const Module *M,
@@ -64,13 +74,8 @@ class LLVM_ABI ModuleSlotTracker {
/// Construct a slot tracker from a module.
///
- /// If \a M is \c nullptr, uses a null slot tracker. Otherwise, initializes
- /// a slot tracker, and initializes all metadata slots. \c
- /// ShouldInitializeAllMetadata defaults to true because this is expected to
- /// be shared between multiple callers, and otherwise MDNode references will
- /// not match up.
- explicit ModuleSlotTracker(const Module *M,
- bool ShouldInitializeAllMetadata = true);
+ /// If \a M is \c nullptr, uses a null slot tracker.
+ explicit ModuleSlotTracker(const Module *M);
/// Destructor to clean up storage.
virtual ~ModuleSlotTracker();
@@ -95,14 +100,11 @@ class LLVM_ABI ModuleSlotTracker {
int getLocalSlot(const Value *V);
void setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>);
- void setProcessHook(std::function<void(AbstractSlotTrackerStorage *,
- const Function *, bool)>);
-
- using MachineMDNodeListType =
- std::vector<std::pair<unsigned, const MDNode *>>;
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)>);
+ void setProcessHook(
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)>);
- void collectMDNodes(MachineMDNodeListType &L, unsigned LB, unsigned UB) const;
+ void collectMDNodes(MachineMDNodeListType &L) const;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
index 175cecdfa3cd5..a1ad5c254e038 100644
--- a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
+++ b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
@@ -35,21 +35,31 @@ class PrintModulePass : public RequiredPassInfoMixin<PrintModulePass> {
std::string Banner;
bool ShouldPreserveUseListOrder;
bool EmitSummaryIndex;
- bool UsePersistentMetadataIDs;
public:
LLVM_ABI PrintModulePass();
LLVM_ABI PrintModulePass(raw_ostream &OS, const std::string &Banner = "",
bool ShouldPreserveUseListOrder = false,
bool EmitSummaryIndex = false);
- LLVM_ABI PrintModulePass(raw_ostream &OS, const std::string &Banner,
- bool ShouldPreserveUseListOrder,
- bool EmitSummaryIndex,
- bool UsePersistentMetadataIDs);
-
LLVM_ABI PreservedAnalyses run(Module &M, AnalysisManager<Module> &);
};
+/// Print a Module after renumbering metadata for canonical assembly output.
+class PrintCanonicalModulePass
+ : public RequiredPassInfoMixin<PrintCanonicalModulePass> {
+ PrintModulePass Printer;
+
+public:
+ static StringRef name() { return "PrintModulePass"; }
+
+ LLVM_ABI PrintCanonicalModulePass(raw_ostream &OS,
+ const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false,
+ bool EmitSummaryIndex = false);
+
+ LLVM_ABI PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
+};
+
/// Pass (for the new pass manager) for printing a Function as
/// LLVM's text IR assembly.
class PrintFunctionPass : public RequiredPassInfoMixin<PrintFunctionPass> {
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp
index dd6f7212f038f..3fd2fe02f6688 100644
--- a/llvm/lib/Analysis/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp
@@ -686,7 +686,7 @@ namespace {
if (isFunctionInPrintList("*") && NeedModule) {
PrintBannerOnce();
OS << "\n";
- SCC.getCallGraph().getModule().printWithPersistentMetadataIDs(OS);
+ SCC.getCallGraph().getModule().print(OS, nullptr);
return false;
}
bool FoundFunction = false;
@@ -707,7 +707,7 @@ namespace {
if (NeedModule && FoundFunction) {
PrintBannerOnce();
OS << "\n";
- SCC.getCallGraph().getModule().printWithPersistentMetadataIDs(OS);
+ SCC.getCallGraph().getModule().print(OS, nullptr);
}
return false;
}
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 43dc25ec0efcb..16a7690092ff5 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -1035,7 +1035,7 @@ void llvm::printLoop(const Loop &L, raw_ostream &OS,
OS << ")\n";
// printing whole module
- L.getHeader()->getModule()->printWithPersistentMetadataIDs(OS);
+ OS << *L.getHeader()->getModule();
return;
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 93a79a7035e6f..d4ebb8798d243 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -136,6 +136,32 @@ bool LLParser::parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read,
return Status;
}
+bool LLParser::parseMetadataDefinitions(SlotMapping &Slots) {
+ restoreParsingState(&Slots);
+ Lex.Lex();
+
+ while (Lex.getKind() != lltok::Eof) {
+ if (Lex.getKind() != lltok::exclaim)
+ return tokError("expected a metadata definition");
+ if (parseStandaloneMetadata())
+ return true;
+ }
+
+ if (!ForwardRefMDNodes.empty())
+ return error(ForwardRefMDNodes.begin()->second.second,
+ "use of undefined metadata '!" +
+ Twine(ForwardRefMDNodes.begin()->first) + "'");
+
+ for (auto &[_, MD] : NumberedMetadata)
+ if (MD && !MD->isResolved())
+ MD->resolveCycles();
+ DISubprogram::cleanupRetainedNodes(NewDistinctSPs);
+ NewDistinctSPs.clear();
+
+ Slots.MetadataNodes = std::move(NumberedMetadata);
+ return false;
+}
+
void LLParser::restoreParsingState(const SlotMapping *Slots) {
if (!Slots)
return;
diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp
index f33a9dad2bb06..a0209b164ef1b 100644
--- a/llvm/lib/AsmParser/Parser.cpp
+++ b/llvm/lib/AsmParser/Parser.cpp
@@ -247,3 +247,13 @@ DIExpression *llvm::parseDIExpressionBodyAtBeginning(StringRef Asm,
return nullptr;
return dyn_cast<DIExpression>(MD);
}
+
+bool llvm::parseMetadataDefinitions(StringRef Asm, SMDiagnostic &Err,
+ const Module &M, SlotMapping &Slots) {
+ SourceMgr SM;
+ std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
+ SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
+ return LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr,
+ M.getContext())
+ .parseMetadataDefinitions(Slots);
+}
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index bb0b87cc042d0..d38869c4b497f 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -360,7 +360,7 @@ static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
/// Creates the mapping from slot numbers to function's unnamed IR values.
static void initSlots2Values(const Function &F,
DenseMap<unsigned, const Value *> &Slots2Values) {
- ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
+ ModuleSlotTracker MST(F.getParent());
MST.incorporateFunction(F);
for (const auto &Arg : F.args())
mapValueToSlot(&Arg, MST, Slots2Values);
@@ -3961,7 +3961,7 @@ bool MIParser::parseMMRA(MDNode *&Node) {
static void initSlots2BasicBlocks(
const Function &F,
DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
- ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
+ ModuleSlotTracker MST(F.getParent());
MST.incorporateFunction(F);
for (const auto &BB : F) {
if (BB.hasName())
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 6f1e7594f34da..fee9f3e676391 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -13,6 +13,7 @@
#include "llvm/CodeGen/MIRParser/MIRParser.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
@@ -1237,15 +1238,45 @@ bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
bool MIRParserImpl::parseMachineMetadataNodes(
PerFunctionMIParsingState &PFS, MachineFunction &MF,
const yaml::MachineFunction &YMF) {
+ bool HasSpecializedNode =
+ llvm::any_of(YMF.MachineMetadataNodes, [](const yaml::StringValue &MDS) {
+ StringRef RHS = StringRef(MDS.Value).split('=').second.ltrim();
+ if (RHS.consume_front("distinct"))
+ RHS = RHS.ltrim();
+ return RHS.starts_with("!DI") || RHS.starts_with("!GenericDI");
+ });
+ if (!HasSpecializedNode) {
+ for (const auto &MDS : YMF.MachineMetadataNodes) {
+ if (parseMachineMetadata(PFS, MDS))
+ return true;
+ }
+ if (!PFS.MachineForwardRefMDNodes.empty())
+ return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
+ "use of undefined metadata '!" +
+ Twine(PFS.MachineForwardRefMDNodes.begin()->first) +
+ "'");
+ return false;
+ }
+
+ std::string Definitions;
for (const auto &MDS : YMF.MachineMetadataNodes) {
- if (parseMachineMetadata(PFS, MDS))
- return true;
+ Definitions.append(MDS.Value);
+ Definitions.push_back('\n');
}
- // Report missing definitions from forward referenced nodes.
- if (!PFS.MachineForwardRefMDNodes.empty())
- return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
- "use of undefined metadata '!" +
- Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
+
+ SlotMapping Slots = PFS.IRSlots;
+ SMDiagnostic Error;
+ if (parseMetadataDefinitions(Definitions, Error,
+ *MF.getFunction().getParent(), Slots)) {
+ unsigned Line = std::max(Error.getLineNo(), 1);
+ unsigned Index =
+ std::min<unsigned>(Line - 1, YMF.MachineMetadataNodes.size() - 1);
+ return error(Error, YMF.MachineMetadataNodes[Index].SourceRange);
+ }
+
+ for (auto &[ID, MD] : Slots.MetadataNodes)
+ if (PFS.IRSlots.MetadataNodes.find(ID) == PFS.IRSlots.MetadataNodes.end())
+ PFS.MachineMetadataNodes.try_emplace(ID, MD);
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 8acd6f14ebc2e..fbe71c175e0e8 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -107,7 +107,9 @@ struct MFPrintState {
SmallVector<StringRef, 8> SSNs;
MFPrintState(MFGetterFnT Fn, const MachineFunction &MF)
- : MST(std::move(Fn), &MF) {}
+ : MST(std::move(Fn), &MF) {
+ MST.renumberMetadataForAssembly();
+ }
};
} // end anonymous namespace
@@ -1080,6 +1082,7 @@ void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
}
void llvm::printMIR(raw_ostream &OS, const Module &M) {
+ const_cast<Module &>(M).renumberMetadataForAssembly();
yaml::Output Out(OS);
Out << const_cast<Module &>(M);
}
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 08a67935b52f5..b58a11efd103c 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -503,7 +503,7 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
if (moduleSlotTracker) {
slot = moduleSlotTracker->getLocalSlot(bb);
} else if (bb->getParent()) {
- ModuleSlotTracker tmpTracker(bb->getModule(), false);
+ ModuleSlotTracker tmpTracker(bb->getModule());
tmpTracker.incorporateFunction(*bb->getParent());
slot = tmpTracker.getLocalSlot(bb);
}
diff --git a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
index 5250330e170c2..1c43f7be85129 100644
--- a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
+++ b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
@@ -8,73 +8,69 @@
#include "llvm/CodeGen/MachineModuleSlotTracker.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Module.h"
using namespace llvm;
-void MachineModuleSlotTracker::processMachineFunctionMetadata(
- AbstractSlotTrackerStorage *AST, const MachineFunction &MF) {
- // Create metadata created within the backend.
+void MachineModuleSlotTracker::collectMachineFunctionMetadata(
+ SmallVectorImpl<const MDNode *> &Metadata,
+ const MachineFunction &MF) const {
for (const MachineBasicBlock &MBB : MF)
- for (const MachineInstr &MI : MBB.instrs())
+ for (const MachineInstr &MI : MBB.instrs()) {
+ if (DebugLoc DL = MI.getDebugLoc())
+ Metadata.push_back(DL.getAsMDNode());
+
+ for (const MachineOperand &MO : MI.operands())
+ if (MO.isMetadata())
+ Metadata.push_back(MO.getMetadata());
+
for (const MachineMemOperand *MMO : MI.memoperands()) {
AAMDNodes AAInfo = MMO->getAAInfo();
if (AAInfo.TBAA)
- AST->createMetadataSlot(AAInfo.TBAA);
+ Metadata.push_back(AAInfo.TBAA);
if (AAInfo.TBAAStruct)
- AST->createMetadataSlot(AAInfo.TBAAStruct);
+ Metadata.push_back(AAInfo.TBAAStruct);
if (AAInfo.Scope)
- AST->createMetadataSlot(AAInfo.Scope);
+ Metadata.push_back(AAInfo.Scope);
if (AAInfo.NoAlias)
- AST->createMetadataSlot(AAInfo.NoAlias);
+ Metadata.push_back(AAInfo.NoAlias);
}
+ }
}
-void MachineModuleSlotTracker::processMachineModule(
- AbstractSlotTrackerStorage *AST, const Module *M,
- bool ShouldInitializeAllMetadata) {
- if (ShouldInitializeAllMetadata) {
- for (const Function &F : *M) {
- if (&F != &TheFunction)
- continue;
- MDNStartSlot = AST->getNextMetadataSlot();
- if (TheMF)
- processMachineFunctionMetadata(AST, *TheMF);
- MDNEndSlot = AST->getNextMetadataSlot();
- break;
- }
- }
+void MachineModuleSlotTracker::processMachineFunctionMetadata(
+ AbstractSlotTrackerStorage *AST, const MachineFunction &MF) const {
+ SmallVector<const MDNode *, 16> Metadata;
+ collectMachineFunctionMetadata(Metadata, MF);
+ for (const MDNode *N : Metadata)
+ AST->createMetadataSlot(N);
}
-void MachineModuleSlotTracker::processMachineFunction(
- AbstractSlotTrackerStorage *AST, const Function *F,
- bool ShouldInitializeAllMetadata) {
- if (!ShouldInitializeAllMetadata && F == &TheFunction) {
- MDNStartSlot = AST->getNextMetadataSlot();
- if (TheMF)
- processMachineFunctionMetadata(AST, *TheMF);
- MDNEndSlot = AST->getNextMetadataSlot();
- }
+void MachineModuleSlotTracker::renumberMetadataForAssembly() {
+ if (!TheMF)
+ return;
+
+ SmallVector<const MDNode *, 16> Metadata;
+ collectMachineFunctionMetadata(Metadata, *TheMF);
+ MachineMDNodes.clear();
+ ModuleSlotTracker::renumberMetadataForAssembly(Metadata, &MachineMDNodes);
}
void MachineModuleSlotTracker::collectMachineMDNodes(
MachineMDNodeListType &L) const {
- collectMDNodes(L, MDNStartSlot, MDNEndSlot);
+ L.insert(L.end(), MachineMDNodes.begin(), MachineMDNodes.end());
}
-MachineModuleSlotTracker::MachineModuleSlotTracker(
- MFGetterFnT Fn, const MachineFunction *MF, bool ShouldInitializeAllMetadata)
- : ModuleSlotTracker(MF->getFunction().getParent(),
- ShouldInitializeAllMetadata),
- TheFunction(MF->getFunction()), TheMF(Fn(MF->getFunction())) {
- setProcessHook([this](AbstractSlotTrackerStorage *AST, const Module *M,
- bool ShouldInitializeAllMetadata) {
- this->processMachineModule(AST, M, ShouldInitializeAllMetadata);
- });
- setProcessHook([this](AbstractSlotTrackerStorage *AST, const Function *F,
- bool ShouldInitializeAllMetadata) {
- this->processMachineFunction(AST, F, ShouldInitializeAllMetadata);
+MachineModuleSlotTracker::MachineModuleSlotTracker(MFGetterFnT Fn,
+ const MachineFunction *MF)
+ : ModuleSlotTracker(MF->getFunction().getParent()),
+ TheMF(Fn(MF->getFunction())) {
+ setProcessHook([this](AbstractSlotTrackerStorage *AST, const Module *) {
+ if (TheMF)
+ processMachineFunctionMetadata(AST, *TheMF);
});
}
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index 3067f6e636130..af1487038de59 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -529,7 +529,7 @@ static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
if (F == MST.getCurrentFunction()) {
Slot = MST.getLocalSlot(&BB);
} else if (const Module *M = F->getParent()) {
- ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
+ ModuleSlotTracker CustomMST(M);
CustomMST.incorporateFunction(*F);
Slot = CustomMST.getLocalSlot(&BB);
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 7a1cefb468072..4fc6b4dadd908 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -786,14 +786,6 @@ AbstractSlotTrackerStorage::~AbstractSlotTrackerStorage() = default;
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
-namespace {
-enum class MetadataPrintMode {
- Compact,
- PersistentReferences,
- PersistentDefinitions,
-};
-} // end anonymous namespace
-
/// This class provides computation of slot numbers for LLVM Assembly writing.
///
class llvm::SlotTracker : public AbstractSlotTrackerStorage {
@@ -808,12 +800,11 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// TheFunction - The function for which we are holding slot numbers.
const Function* TheFunction = nullptr;
bool FunctionProcessed = false;
- bool ShouldInitializeAllMetadata;
- MetadataPrintMode MetadataMode;
+ bool ShouldTrackMetadataDefinitions;
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)>
ProcessModuleHookFn;
- std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)>
ProcessFunctionHookFn;
/// The summary index for which we are holding slot numbers.
@@ -828,9 +819,7 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
unsigned fNext = 0;
/// mdnMap - Map for MDNodes.
- DenseMap<const MDNode*, unsigned> mdnMap;
- unsigned mdnNext = 0;
-
+ DenseMap<const MDNode *, unsigned> mdnMap;
/// asMap - The slot map for attribute sets.
DenseMap<AttributeSet, unsigned> asMap;
unsigned asNext = 0;
@@ -855,23 +844,12 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
public:
/// Construct from a module.
///
- /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
- /// functions, giving correct numbering for metadata referenced only from
- /// within a function (even if no functions have been initialized).
- explicit SlotTracker(
- const Module *M, bool ShouldInitializeAllMetadata = false,
- MetadataPrintMode MetadataMode = MetadataPrintMode::Compact);
+ explicit SlotTracker(const Module *M,
+ bool ShouldTrackMetadataDefinitions = false);
/// Construct from a function, starting out in incorp state.
///
- /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
- /// functions, giving correct numbering for metadata referenced only from
- /// within a function (even if no functions have been initialized).
- /// Persistent modes skip metadata enumeration and use IDs stored in the
- /// LLVM context.
- explicit SlotTracker(
- const Function *F, bool ShouldInitializeAllMetadata = false,
- MetadataPrintMode MetadataMode = MetadataPrintMode::Compact);
+ explicit SlotTracker(const Function *F);
/// Construct from a module summary index.
explicit SlotTracker(const ModuleSummaryIndex *Index);
@@ -882,11 +860,9 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
~SlotTracker() override = default;
void setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>);
- void setProcessHook(std::function<void(AbstractSlotTrackerStorage *,
- const Function *, bool)>);
-
- unsigned getNextMetadataSlot() override { return mdnNext; }
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)>);
+ void setProcessHook(
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)>);
void createMetadataSlot(const MDNode *N) override;
@@ -922,12 +898,6 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
mdn_iterator mdn_end() { return mdnMap.end(); }
unsigned mdn_size() const { return mdnMap.size(); }
bool mdn_empty() const { return mdnMap.empty(); }
- bool usePersistentMetadataIDs() const {
- return MetadataMode != MetadataPrintMode::Compact;
- }
- bool trackPersistentMetadataDefinitions() const {
- return MetadataMode == MetadataPrintMode::PersistentDefinitions;
- }
/// AttributeSet map iterators.
using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;
@@ -949,12 +919,9 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void CreateModuleSlot(const GlobalValue *V);
- /// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
+ /// Record a metadata definition and the metadata nodes referenced by it.
void CreateMetadataSlot(const MDNode *N);
- /// Record a persistent slot and the metadata nodes referenced by it.
- void CreatePersistentMetadataSlot(const MDNode *N);
-
/// CreateFunctionSlot - Insert the specified Value* into the slot table.
void CreateFunctionSlot(const Value *V);
@@ -974,28 +941,14 @@ class llvm::SlotTracker : public AbstractSlotTrackerStorage {
/// Add all of the functions arguments, basic blocks, and instructions.
void processFunction();
-
- /// Add the metadata directly attached to a GlobalObject.
- void processGlobalObjectMetadata(const GlobalObject &GO);
-
- /// Add all of the metadata from a function.
- void processFunctionMetadata(const Function &F);
-
- /// Add all of the metadata from an instruction.
- void processInstructionMetadata(const Instruction &I);
-
- /// Add all of the metadata from a DbgRecord.
- void processDbgRecordMetadata(const DbgRecord &DVR);
};
ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M,
const Function *F)
: M(M), F(F), Machine(&Machine) {}
-ModuleSlotTracker::ModuleSlotTracker(const Module *M,
- bool ShouldInitializeAllMetadata)
- : ShouldCreateStorage(M),
- ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}
+ModuleSlotTracker::ModuleSlotTracker(const Module *M)
+ : ShouldCreateStorage(M), M(M) {}
ModuleSlotTracker::~ModuleSlotTracker() = default;
@@ -1004,8 +957,7 @@ SlotTracker *ModuleSlotTracker::getMachine() {
return Machine;
ShouldCreateStorage = false;
- MachineStorage =
- std::make_unique<SlotTracker>(M, ShouldInitializeAllMetadata);
+ MachineStorage = std::make_unique<SlotTracker>(M);
Machine = MachineStorage.get();
if (ProcessModuleHookFn)
Machine->setProcessHook(ProcessModuleHookFn);
@@ -1034,14 +986,12 @@ int ModuleSlotTracker::getLocalSlot(const Value *V) {
}
void ModuleSlotTracker::setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
- Fn) {
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)> Fn) {
ProcessModuleHookFn = std::move(Fn);
}
void ModuleSlotTracker::setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
- Fn) {
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)> Fn) {
ProcessFunctionHookFn = std::move(Fn);
}
@@ -1079,36 +1029,19 @@ static SlotTracker *createSlotTracker(const Value *V) {
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
-SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata,
- MetadataPrintMode MetadataMode)
- : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
- MetadataMode(MetadataMode) {
- assert((!ShouldInitializeAllMetadata || !usePersistentMetadataIDs()) &&
- "cannot initialize compact metadata slots with persistent IDs");
- if (usePersistentMetadataIDs()) {
- assert(M && "persistent metadata IDs require a module");
- mdnNext = M->getContext().pImpl->getNextMetadataPrintID();
- }
-}
+SlotTracker::SlotTracker(const Module *M, bool ShouldTrackMetadataDefinitions)
+ : TheModule(M),
+ ShouldTrackMetadataDefinitions(ShouldTrackMetadataDefinitions) {}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
-SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata,
- MetadataPrintMode MetadataMode)
+SlotTracker::SlotTracker(const Function *F)
: TheModule(F ? F->getParent() : nullptr), TheFunction(F),
- ShouldInitializeAllMetadata(ShouldInitializeAllMetadata),
- MetadataMode(MetadataMode) {
- assert((!ShouldInitializeAllMetadata || !usePersistentMetadataIDs()) &&
- "cannot initialize compact metadata slots with persistent IDs");
- if (usePersistentMetadataIDs()) {
- assert(F && "persistent metadata IDs require a function");
- mdnNext = F->getContext().pImpl->getNextMetadataPrintID();
- }
-}
+ ShouldTrackMetadataDefinitions(false) {}
SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
- : TheModule(nullptr), ShouldInitializeAllMetadata(false),
- MetadataMode(MetadataPrintMode::Compact), TheIndex(Index) {}
+ : TheModule(nullptr), ShouldTrackMetadataDefinitions(false),
+ TheIndex(Index) {}
inline void SlotTracker::initializeIfNeeded() {
if (TheModule) {
@@ -1137,8 +1070,6 @@ void SlotTracker::processModule() {
for (const GlobalVariable &Var : TheModule->globals()) {
if (!Var.hasName())
CreateModuleSlot(&Var);
- if (!usePersistentMetadataIDs())
- processGlobalObjectMetadata(Var);
auto Attrs = Var.getAttributes();
if (Attrs.hasAttributes())
CreateAttributeSetSlot(Attrs);
@@ -1152,24 +1083,13 @@ void SlotTracker::processModule() {
for (const GlobalIFunc &I : TheModule->ifuncs()) {
if (!I.hasName())
CreateModuleSlot(&I);
- if (!usePersistentMetadataIDs())
- processGlobalObjectMetadata(I);
}
- // Add metadata used by named metadata.
- if (!usePersistentMetadataIDs())
- for (const NamedMDNode &NMD : TheModule->named_metadata())
- for (const MDNode *N : NMD.operands())
- CreateMetadataSlot(N);
-
for (const Function &F : *TheModule) {
if (!F.hasName())
// Add all the unnamed functions to the table.
CreateModuleSlot(&F);
- if (ShouldInitializeAllMetadata && !usePersistentMetadataIDs())
- processFunctionMetadata(F);
-
// Add all the function attributes to the table.
// FIXME: Add attributes of other objects?
AttributeSet FnAttrs = F.getAttributes().getFnAttrs();
@@ -1178,7 +1098,7 @@ void SlotTracker::processModule() {
}
if (ProcessModuleHookFn)
- ProcessModuleHookFn(this, TheModule, ShouldInitializeAllMetadata);
+ ProcessModuleHookFn(this, TheModule);
ST_DEBUG("end processModule!\n");
}
@@ -1188,10 +1108,6 @@ void SlotTracker::processFunction() {
ST_DEBUG("begin processFunction!\n");
fNext = 0;
- // Process function metadata if it wasn't hit at the module-level.
- if (!ShouldInitializeAllMetadata && !usePersistentMetadataIDs())
- processFunctionMetadata(*TheFunction);
-
// Add all the function arguments with no names.
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
@@ -1221,7 +1137,7 @@ void SlotTracker::processFunction() {
}
if (ProcessFunctionHookFn)
- ProcessFunctionHookFn(this, TheFunction, ShouldInitializeAllMetadata);
+ ProcessFunctionHookFn(this, TheFunction);
FunctionProcessed = true;
@@ -1264,68 +1180,115 @@ int SlotTracker::processIndex() {
return TypeIdNext;
}
-void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
- SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
- GO.getAllMetadata(MDs);
- for (auto &MD : MDs)
- CreateMetadataSlot(MD.second);
-}
+namespace {
+class MetadataIDRenumberer {
+ DenseSet<const MDNode *> Visited;
+ uint32_t NextID = 0;
-void SlotTracker::processFunctionMetadata(const Function &F) {
- processGlobalObjectMetadata(F);
- for (auto &BB : F) {
- for (auto &I : BB) {
- for (const DbgRecord &DR : I.getDbgRecordRange())
- processDbgRecordMetadata(DR);
- processInstructionMetadata(I);
+ void renumber(const MDNode *N) {
+ if (isa<DIExpression>(N) || !Visited.insert(N).second)
+ return;
+
+ N->getContext().pImpl->setMetadataPrintID(const_cast<MDNode *>(N),
+ NextID++);
+ for (const MDOperand &Op : N->operands())
+ if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
+ renumber(OpNode);
+ }
+
+ void renumberGlobalObjectMetadata(const GlobalObject &GO) {
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ GO.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ renumber(MD.second);
+ }
+
+ void renumberDbgRecordMetadata(const DbgRecord &DR) {
+ if (const auto *DVR = dyn_cast<const DbgVariableRecord>(&DR)) {
+ if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawLocation()))
+ renumber(Empty);
+ if (DVR->getRawVariable())
+ renumber(DVR->getRawVariable());
+ if (DVR->isDbgAssign()) {
+ if (auto *AssignID = DVR->getRawAssignID())
+ renumber(cast<MDNode>(AssignID));
+ if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawAddress()))
+ renumber(Empty);
+ }
+ } else if (const auto *DLR = dyn_cast<const DbgLabelRecord>(&DR)) {
+ renumber(DLR->getRawLabel());
+ } else {
+ llvm_unreachable("unsupported DbgRecord kind");
}
+ if (DR.getDebugLoc())
+ renumber(DR.getDebugLoc().getAsMDNode());
+ }
+
+ void renumberInstructionMetadata(const Instruction &I) {
+ if (const auto *CI = dyn_cast<CallInst>(&I))
+ if (Function *F = CI->getCalledFunction())
+ if (F->isIntrinsic())
+ for (auto &Op : I.operands())
+ if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
+ if (auto *N = dyn_cast<MDNode>(V->getMetadata()))
+ renumber(N);
+
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ I.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ renumber(MD.second);
+ }
+
+ void renumberFunctionMetadata(const Function &F) {
+ renumberGlobalObjectMetadata(F);
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB) {
+ for (const DbgRecord &DR : I.getDbgRecordRange())
+ renumberDbgRecordMetadata(DR);
+ renumberInstructionMetadata(I);
+ }
}
-}
-void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
- // Tolerate null metadata pointers: it's a completely illegal debug record,
- // but we can have faulty metadata from debug-intrinsic days being
- // autoupgraded into debug records. This gets caught by the verifier, which
- // then will print the faulty IR, hitting this code path.
- if (const auto *DVR = dyn_cast<const DbgVariableRecord>(&DR)) {
- // Process metadata used by DbgRecords; we only specifically care about the
- // DILocalVariable, DILocation, and DIAssignID fields, as the Value and
- // Expression fields should only be printed inline and so do not use a slot.
- // Note: The above doesn't apply for empty-metadata operands.
- if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawLocation()))
- CreateMetadataSlot(Empty);
- if (DVR->getRawVariable())
- CreateMetadataSlot(DVR->getRawVariable());
- if (DVR->isDbgAssign()) {
- if (auto *AssignID = DVR->getRawAssignID())
- CreateMetadataSlot(cast<MDNode>(AssignID));
- if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawAddress()))
- CreateMetadataSlot(Empty);
+public:
+ void run(const Module &M, ArrayRef<const MDNode *> AdditionalMetadata,
+ ModuleSlotTracker::MachineMDNodeListType *AdditionalMetadataNodes =
+ nullptr) {
+ for (const GlobalVariable &Var : M.globals())
+ renumberGlobalObjectMetadata(Var);
+ for (const GlobalIFunc &I : M.ifuncs())
+ renumberGlobalObjectMetadata(I);
+ for (const NamedMDNode &NMD : M.named_metadata())
+ for (const MDNode *N : NMD.operands())
+ renumber(N);
+ for (const Function &F : M)
+ renumberFunctionMetadata(F);
+
+ uint32_t FirstAdditionalID = NextID;
+ for (const MDNode *N : AdditionalMetadata)
+ renumber(N);
+
+ if (!AdditionalMetadataNodes)
+ return;
+
+ for (const MDNode *N : Visited) {
+ unsigned ID = N->getContext().pImpl->getMetadataPrintID(N);
+ if (ID >= FirstAdditionalID)
+ AdditionalMetadataNodes->emplace_back(ID, N);
}
- } else if (const auto *DLR = dyn_cast<const DbgLabelRecord>(&DR)) {
- CreateMetadataSlot(DLR->getRawLabel());
- } else {
- llvm_unreachable("unsupported DbgRecord kind");
+ llvm::sort(*AdditionalMetadataNodes);
}
- if (DR.getDebugLoc())
- CreateMetadataSlot(DR.getDebugLoc().getAsMDNode());
-}
+};
+} // namespace
-void SlotTracker::processInstructionMetadata(const Instruction &I) {
- // Process metadata used directly by intrinsics.
- if (const auto *CI = dyn_cast<CallInst>(&I))
- if (Function *F = CI->getCalledFunction())
- if (F->isIntrinsic())
- for (auto &Op : I.operands())
- if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
- if (auto *N = dyn_cast<MDNode>(V->getMetadata()))
- CreateMetadataSlot(N);
+void Module::renumberMetadataForAssembly() {
+ MetadataIDRenumberer().run(*this, {});
+}
- // Process metadata attached to this instruction.
- SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
- I.getAllMetadata(MDs);
- for (auto &MD : MDs)
- CreateMetadataSlot(MD.second);
+void ModuleSlotTracker::renumberMetadataForAssembly(
+ ArrayRef<const MDNode *> AdditionalMetadata,
+ MachineMDNodeListType *AdditionalMetadataNodes) const {
+ assert(M && "metadata renumbering requires a module");
+ MetadataIDRenumberer().run(*M, AdditionalMetadata, AdditionalMetadataNodes);
}
/// Clean up after incorporating a function. This is the only way to get out of
@@ -1350,43 +1313,28 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) {
}
void SlotTracker::setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
- Fn) {
+ std::function<void(AbstractSlotTrackerStorage *, const Module *)> Fn) {
ProcessModuleHookFn = std::move(Fn);
}
void SlotTracker::setProcessHook(
- std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
- Fn) {
+ std::function<void(AbstractSlotTrackerStorage *, const Function *)> Fn) {
ProcessFunctionHookFn = std::move(Fn);
}
/// getMetadataSlot - Get the slot number of a MDNode.
-void SlotTracker::createMetadataSlot(const MDNode *N) {
- if (usePersistentMetadataIDs())
- CreatePersistentMetadataSlot(N);
- else
- CreateMetadataSlot(N);
-}
+void SlotTracker::createMetadataSlot(const MDNode *N) { CreateMetadataSlot(N); }
/// getMetadataSlot - Get the slot number of a MDNode.
int SlotTracker::getMetadataSlot(const MDNode *N) {
// Check for uninitialized state and do lazy initialization.
initializeIfNeeded();
- if (usePersistentMetadataIDs()) {
- if (isa<DIExpression>(N))
- return -1;
- if (trackPersistentMetadataDefinitions() || N->isTemporary())
- CreatePersistentMetadataSlot(N);
- if (N->isTemporary())
- return mdnMap.lookup(N);
- return N->getContext().pImpl->getMetadataPrintID(N);
- }
-
- // Find the MDNode in the module map
- mdn_iterator MI = mdnMap.find(N);
- return MI == mdnMap.end() ? -1 : (int)MI->second;
+ if (isa<DIExpression>(N))
+ return -1;
+ if (ShouldTrackMetadataDefinitions)
+ CreateMetadataSlot(N);
+ return N->getContext().pImpl->getMetadataPrintID(N);
}
/// getLocalSlot - Get the slot number for a value that is local to a function.
@@ -1479,37 +1427,16 @@ void SlotTracker::CreateFunctionSlot(const Value *V) {
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
assert(N && "Can't insert a null Value into SlotTracker!");
- // Don't make slots for DIExpressions. We just print them inline everywhere.
- if (isa<DIExpression>(N))
- return;
-
- unsigned DestSlot = mdnNext;
- if (!mdnMap.insert(std::make_pair(N, DestSlot)).second)
- return;
- ++mdnNext;
-
- // Recursively add any MDNodes referenced by operands.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (const auto *Op = dyn_cast_or_null<MDNode>(N->getOperand(i)))
- CreateMetadataSlot(Op);
-}
-
-void SlotTracker::CreatePersistentMetadataSlot(const MDNode *N) {
- assert(N && "Can't insert a null Value into SlotTracker!");
-
if (isa<DIExpression>(N))
return;
- unsigned ID =
- N->isTemporary() ? mdnNext : N->getContext().pImpl->getMetadataPrintID(N);
+ unsigned ID = N->getContext().pImpl->getMetadataPrintID(N);
if (!mdnMap.try_emplace(N, ID).second)
return;
- if (N->isTemporary())
- ++mdnNext;
for (const MDOperand &Op : N->operands())
if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
- CreatePersistentMetadataSlot(OpNode);
+ CreateMetadataSlot(OpNode);
}
void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
@@ -5098,17 +5025,6 @@ void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
}
void AssemblyWriter::writeAllMDNodes() {
- if (!Machine.usePersistentMetadataIDs()) {
- SmallVector<const MDNode *, 16> Nodes;
- Nodes.resize(Machine.mdn_size());
- for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
- Nodes[I.second] = cast<MDNode>(I.first);
-
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
- writeMDNode(i, Nodes[i]);
- return;
- }
-
SmallVector<std::pair<unsigned, const MDNode *>, 16> Nodes;
Nodes.reserve(Machine.mdn_size());
for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
@@ -5187,8 +5103,7 @@ void AssemblyWriter::printUseLists(const Function *F) {
void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
- SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
- MetadataPrintMode::PersistentReferences);
+ SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getParent(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5198,9 +5113,7 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder,
bool IsForDebug) const {
- SlotTracker SlotTable(this->getParent(),
- /*ShouldInitializeAllMetadata=*/false,
- MetadataPrintMode::PersistentReferences);
+ SlotTracker SlotTable(this->getParent());
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getModule(), AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5209,19 +5122,7 @@ void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
- SlotTracker SlotTable(this);
- formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
- ShouldPreserveUseListOrder);
- W.printModule(this);
-}
-
-void Module::printWithPersistentMetadataIDs(raw_ostream &ROS,
- AssemblyAnnotationWriter *AAW,
- bool ShouldPreserveUseListOrder,
- bool IsForDebug) const {
- SlotTracker SlotTable(this, /*ShouldInitializeAllMetadata=*/false,
- MetadataPrintMode::PersistentDefinitions);
+ SlotTracker SlotTable(this, /*ShouldTrackMetadataDefinitions=*/true);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
ShouldPreserveUseListOrder);
@@ -5291,26 +5192,15 @@ void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
}
}
-static bool isReferencingMDNode(const Instruction &I) {
- if (const auto *CI = dyn_cast<CallInst>(&I))
- if (Function *F = CI->getCalledFunction())
- if (F->isIntrinsic())
- for (auto &Op : I.operands())
- if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
- if (isa<MDNode>(V->getMetadata()))
- return true;
- return false;
-}
-
void DbgMarker::print(raw_ostream &ROS, bool IsForDebug) const {
- ModuleSlotTracker MST(getModuleFromDPI(this), true);
+ ModuleSlotTracker MST(getModuleFromDPI(this));
print(ROS, MST, IsForDebug);
}
void DbgVariableRecord::print(raw_ostream &ROS, bool IsForDebug) const {
- ModuleSlotTracker MST(getModuleFromDPI(this), true);
+ ModuleSlotTracker MST(getModuleFromDPI(this));
print(ROS, MST, IsForDebug);
}
@@ -5329,7 +5219,7 @@ void DbgMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
void DbgLabelRecord::print(raw_ostream &ROS, bool IsForDebug) const {
- ModuleSlotTracker MST(getModuleFromDPI(this), true);
+ ModuleSlotTracker MST(getModuleFromDPI(this));
print(ROS, MST, IsForDebug);
}
@@ -5373,13 +5263,7 @@ void Value::print(raw_ostream &ROS, bool IsForDebug) const {
return;
}
- bool ShouldInitializeAllMetadata = false;
- if (auto *I = dyn_cast<Instruction>(this))
- ShouldInitializeAllMetadata = isReferencingMDNode(*I);
- else if (isa<MetadataAsValue>(this))
- ShouldInitializeAllMetadata = true;
-
- ModuleSlotTracker MST(getModuleFromVal(this), ShouldInitializeAllMetadata);
+ ModuleSlotTracker MST(getModuleFromVal(this));
print(ROS, MST, IsForDebug);
}
@@ -5459,8 +5343,7 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType,
if (printWithoutType(*this, O, nullptr, M))
return;
- SlotTracker Machine(
- M, /* ShouldInitializeAllMetadata */ isa<MetadataAsValue>(this));
+ SlotTracker Machine(M);
ModuleSlotTracker MST(Machine, M);
printAsOperandImpl(*this, O, PrintType, MST);
}
@@ -5557,7 +5440,7 @@ static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
}
void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
- ModuleSlotTracker MST(M, isa<MDNode>(this));
+ ModuleSlotTracker MST(M);
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
}
@@ -5568,7 +5451,7 @@ void Metadata::printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
void Metadata::print(raw_ostream &OS, const Module *M,
bool /*IsForDebug*/) const {
- ModuleSlotTracker MST(M, isa<MDNode>(this));
+ ModuleSlotTracker MST(M);
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}
@@ -5578,7 +5461,7 @@ void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
}
void MDNode::printTree(raw_ostream &OS, const Module *M) const {
- ModuleSlotTracker MST(M, true);
+ ModuleSlotTracker MST(M);
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false,
/*PrintAsTree=*/true);
}
@@ -5596,15 +5479,13 @@ void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
W.printModuleSummaryIndex();
}
-void ModuleSlotTracker::collectMDNodes(MachineMDNodeListType &L, unsigned LB,
- unsigned UB) const {
+void ModuleSlotTracker::collectMDNodes(MachineMDNodeListType &L) const {
SlotTracker *ST = MachineStorage.get();
if (!ST)
return;
for (auto &I : llvm::make_range(ST->mdn_begin(), ST->mdn_end()))
- if (I.second >= LB && I.second < UB)
- L.push_back(std::make_pair(I.second, I.first));
+ L.push_back(std::make_pair(I.second, I.first));
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index a7abd3eed31c3..d1ee8411e392c 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -474,6 +474,7 @@ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename,
return true;
}
+ unwrap(M)->renumberMetadataForAssembly();
unwrap(M)->print(dest, nullptr);
dest.close();
@@ -491,6 +492,7 @@ char *LLVMPrintModuleToString(LLVMModuleRef M) {
std::string buf;
raw_string_ostream os(buf);
+ unwrap(M)->renumberMetadataForAssembly();
unwrap(M)->print(os, nullptr);
return strdup(buf.c_str());
diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp
index 61696bdbe24f7..23c68126a61d4 100644
--- a/llvm/lib/IR/IRPrintingPasses.cpp
+++ b/llvm/lib/IR/IRPrintingPasses.cpp
@@ -26,46 +26,43 @@ using namespace llvm;
namespace {
+static void printModule(raw_ostream &OS, StringRef Banner,
+ bool ShouldPreserveUseListOrder, Module &M) {
+ if (llvm::isFunctionInPrintList("*")) {
+ if (!Banner.empty())
+ OS << Banner << "\n";
+ M.print(OS, nullptr, ShouldPreserveUseListOrder);
+ return;
+ }
+
+ bool BannerPrinted = false;
+ for (const auto &F : M.functions()) {
+ if (!llvm::isFunctionInPrintList(F.getName()))
+ continue;
+ if (!BannerPrinted && !Banner.empty()) {
+ OS << Banner << "\n";
+ BannerPrinted = true;
+ }
+ F.print(OS);
+ }
+}
+
class PrintModulePassWrapper : public ModulePass {
raw_ostream &OS;
std::string Banner;
bool ShouldPreserveUseListOrder;
- bool UsePersistentMetadataIDs;
public:
static char ID;
PrintModulePassWrapper()
- : ModulePass(ID), OS(dbgs()), ShouldPreserveUseListOrder(false),
- UsePersistentMetadataIDs(true) {}
+ : ModulePass(ID), OS(dbgs()), ShouldPreserveUseListOrder(false) {}
PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
- bool ShouldPreserveUseListOrder,
- bool UsePersistentMetadataIDs)
+ bool ShouldPreserveUseListOrder)
: ModulePass(ID), OS(OS), Banner(Banner),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
- UsePersistentMetadataIDs(UsePersistentMetadataIDs) {}
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
bool runOnModule(Module &M) override {
- if (llvm::isFunctionInPrintList("*")) {
- if (!Banner.empty())
- OS << Banner << "\n";
- if (UsePersistentMetadataIDs)
- M.printWithPersistentMetadataIDs(OS, nullptr,
- ShouldPreserveUseListOrder);
- else
- M.print(OS, nullptr, ShouldPreserveUseListOrder);
- } else {
- bool BannerPrinted = false;
- for (const auto &F : M.functions()) {
- if (llvm::isFunctionInPrintList(F.getName())) {
- if (!BannerPrinted && !Banner.empty()) {
- OS << Banner << "\n";
- BannerPrinted = true;
- }
- F.print(OS);
- }
- }
- }
-
+ printModule(OS, Banner, ShouldPreserveUseListOrder, M);
return false;
}
@@ -76,6 +73,31 @@ class PrintModulePassWrapper : public ModulePass {
StringRef getPassName() const override { return "Print Module IR"; }
};
+class PrintCanonicalModulePassWrapper : public ModulePass {
+ raw_ostream &OS;
+ std::string Banner;
+ bool ShouldPreserveUseListOrder;
+
+public:
+ static char ID;
+ PrintCanonicalModulePassWrapper(raw_ostream &OS, const std::string &Banner,
+ bool ShouldPreserveUseListOrder)
+ : ModulePass(ID), OS(OS), Banner(Banner),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
+
+ bool runOnModule(Module &M) override {
+ M.renumberMetadataForAssembly();
+ printModule(OS, Banner, ShouldPreserveUseListOrder, M);
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+
+ StringRef getPassName() const override { return "Print Canonical Module IR"; }
+};
+
class PrintFunctionPassWrapper : public FunctionPass {
raw_ostream &OS;
std::string Banner;
@@ -91,7 +113,7 @@ class PrintFunctionPassWrapper : public FunctionPass {
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR()) {
OS << Banner << " (function: " << F.getName() << ")\n";
- F.getParent()->printWithPersistentMetadataIDs(OS);
+ F.getParent()->print(OS, nullptr);
} else
OS << Banner << '\n' << static_cast<Value &>(F);
}
@@ -118,16 +140,17 @@ INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
const std::string &Banner,
bool ShouldPreserveUseListOrder) {
- return createPrintModulePass(OS, Banner, ShouldPreserveUseListOrder,
- /*UsePersistentMetadataIDs=*/false);
+ return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
}
-ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
- const std::string &Banner,
- bool ShouldPreserveUseListOrder,
- bool UsePersistentMetadataIDs) {
- return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder,
- UsePersistentMetadataIDs);
+char PrintCanonicalModulePassWrapper::ID = 0;
+
+ModulePass *
+llvm::createPrintCanonicalModulePass(llvm::raw_ostream &OS,
+ const std::string &Banner,
+ bool ShouldPreserveUseListOrder) {
+ return new PrintCanonicalModulePassWrapper(OS, Banner,
+ ShouldPreserveUseListOrder);
}
FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
@@ -139,5 +162,6 @@ bool llvm::isIRPrintingPass(Pass *P) {
const char *PID = (const char *)P->getPassID();
return (PID == &PrintModulePassWrapper::ID) ||
+ (PID == &PrintCanonicalModulePassWrapper::ID) ||
(PID == &PrintFunctionPassWrapper::ID);
}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index d6915bd4439db..d2c9f54e03858 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1615,13 +1615,14 @@ class LLVMContextImpl {
uint32_t allocateMetadataPrintID() { return NextMetadataPrintID++; }
- uint32_t getNextMetadataPrintID() const { return NextMetadataPrintID; }
-
uint32_t getMetadataPrintID(const MDNode *N) const {
- assert(!N->isTemporary() && "temporary metadata has no print ID");
return N->getHeader().MetadataPrintID;
}
+ void setMetadataPrintID(MDNode *N, uint32_t ID) {
+ N->getHeader().MetadataPrintID = ID;
+ }
+
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index c100f86397dca..bbe75ab275092 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -393,9 +393,7 @@ class MPPassManager : public Pass, public PMDataManager {
/// createPrinterPass - Get a module printer pass.
Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const override {
- return createPrintModulePass(O, Banner,
- /*ShouldPreserveUseListOrder=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ return createPrintModulePass(O, Banner);
}
/// run - Execute all of the passes scheduled for execution. Keep track of
@@ -483,9 +481,7 @@ class PassManagerImpl : public Pass,
/// createPrinterPass - Get a module printer pass.
Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const override {
- return createPrintModulePass(O, Banner,
- /*ShouldPreserveUseListOrder=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ return createPrintModulePass(O, Banner);
}
/// run - Execute all of the passes scheduled for execution. Keep track of
@@ -1551,7 +1547,7 @@ MPPassManager::runOnModule(Module &M) {
BeforeStr.clear();
AfterStr.clear();
raw_svector_ostream OS(BeforeStr);
- M.printWithPersistentMetadataIDs(OS);
+ M.print(OS, /*AAW=*/nullptr);
}
{
@@ -1584,7 +1580,7 @@ MPPassManager::runOnModule(Module &M) {
if (ShouldPrintChanged) {
raw_svector_ostream OS(AfterStr);
- M.printWithPersistentMetadataIDs(OS);
+ M.print(OS, /*AAW=*/nullptr);
}
if (ReportChanged)
reportChangedIR(BeforeStr, AfterStr, MP->getPassName(), PassID,
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index c093fe66d27a5..bbd2a2b580303 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -669,8 +669,7 @@ void MDNode::operator delete(void *N) {
MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2)
: Metadata(ID, Storage), Context(Context) {
- if (!isTemporary())
- getHeader().MetadataPrintID = Context.pImpl->allocateMetadataPrintID();
+ getHeader().MetadataPrintID = Context.pImpl->allocateMetadataPrintID();
unsigned Op = 0;
for (Metadata *MD : Ops1)
@@ -793,7 +792,6 @@ void MDNode::makeUniqued() {
// Make this 'uniqued'.
Storage = Uniqued;
- getHeader().MetadataPrintID = getContext().pImpl->allocateMetadataPrintID();
countUnresolvedOperands();
if (!getNumUnresolved()) {
dropReplaceableUses();
@@ -1072,10 +1070,7 @@ void MDNode::deleteTemporary(MDNode *N) {
void MDNode::storeDistinctInContext() {
assert(!Context.hasReplaceableUses() && "Unexpected replaceable uses");
assert(!getNumUnresolved() && "Unexpected unresolved nodes");
- const bool WasTemporary = isTemporary();
Storage = Distinct;
- if (WasTemporary)
- getHeader().MetadataPrintID = getContext().pImpl->allocateMetadataPrintID();
assert(isResolved() && "Expected this to be resolved");
// Reset the hash.
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index 9b13f42ab0dc7..08d58379b7e69 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -49,9 +49,7 @@ ModulePass::~ModulePass() = default;
Pass *ModulePass::createPrinterPass(raw_ostream &OS,
const std::string &Banner) const {
- return createPrintModulePass(OS, Banner,
- /*ShouldPreserveUseListOrder=*/false,
- /*UsePersistentMetadataIDs=*/true);
+ return createPrintModulePass(OS, Banner);
}
PassManagerType ModulePass::getPotentialPassManagerType() const {
diff --git a/llvm/lib/IR/SSAContext.cpp b/llvm/lib/IR/SSAContext.cpp
index feb8570d32757..ca093a1e6a76c 100644
--- a/llvm/lib/IR/SSAContext.cpp
+++ b/llvm/lib/IR/SSAContext.cpp
@@ -93,7 +93,7 @@ template <> Printable SSAContext::print(const BasicBlock *BB) const {
return Printable([BB](raw_ostream &Out) { Out << BB->getName(); });
return Printable([BB](raw_ostream &Out) {
- ModuleSlotTracker MST{BB->getParent()->getParent(), false};
+ ModuleSlotTracker MST{BB->getParent()->getParent()};
MST.incorporateFunction(*BB->getParent());
Out << MST.getLocalSlot(BB);
});
diff --git a/llvm/lib/IRPrinter/IRPrintingPasses.cpp b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
index 73194c706c2ab..c285e47f9bffa 100644
--- a/llvm/lib/IRPrinter/IRPrintingPasses.cpp
+++ b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
@@ -24,31 +24,19 @@
using namespace llvm;
PrintModulePass::PrintModulePass()
- : OS(dbgs()), ShouldPreserveUseListOrder(false), EmitSummaryIndex(false),
- UsePersistentMetadataIDs(true) {}
+ : OS(dbgs()), ShouldPreserveUseListOrder(false), EmitSummaryIndex(false) {}
PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
bool ShouldPreserveUseListOrder,
bool EmitSummaryIndex)
- : PrintModulePass(OS, Banner, ShouldPreserveUseListOrder, EmitSummaryIndex,
- /*UsePersistentMetadataIDs=*/false) {}
-
-PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
- bool ShouldPreserveUseListOrder,
- bool EmitSummaryIndex,
- bool UsePersistentMetadataIDs)
: OS(OS), Banner(Banner),
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
- EmitSummaryIndex(EmitSummaryIndex),
- UsePersistentMetadataIDs(UsePersistentMetadataIDs) {}
+ EmitSummaryIndex(EmitSummaryIndex) {}
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
OS << Banner << "\n";
- if (UsePersistentMetadataIDs)
- M.printWithPersistentMetadataIDs(OS, nullptr, ShouldPreserveUseListOrder);
- else
- M.print(OS, nullptr, ShouldPreserveUseListOrder);
+ M.print(OS, nullptr, ShouldPreserveUseListOrder);
} else {
bool BannerPrinted = false;
for (const auto &F : M.functions()) {
@@ -74,6 +62,17 @@ PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
return PreservedAnalyses::all();
}
+PrintCanonicalModulePass::PrintCanonicalModulePass(
+ raw_ostream &OS, const std::string &Banner, bool ShouldPreserveUseListOrder,
+ bool EmitSummaryIndex)
+ : Printer(OS, Banner, ShouldPreserveUseListOrder, EmitSummaryIndex) {}
+
+PreservedAnalyses PrintCanonicalModulePass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ M.renumberMetadataForAssembly();
+ return Printer.run(M, AM);
+}
+
PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {}
PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
: OS(OS), Banner(Banner) {}
@@ -83,7 +82,7 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR()) {
OS << Banner << " (function: " << F.getName() << ")\n";
- F.getParent()->printWithPersistentMetadataIDs(OS);
+ F.getParent()->print(OS, nullptr);
} else
OS << Banner << '\n' << static_cast<Value &>(F);
}
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 7d8c830ea04f3..177d8ecd3508d 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -139,10 +139,7 @@ MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass(TM))
-MODULE_PASS("print", PrintModulePass(errs(), /*Banner=*/"",
- /*ShouldPreserveUseListOrder=*/false,
- /*EmitSummaryIndex=*/false,
- /*UsePersistentMetadataIDs=*/true))
+MODULE_PASS("print", PrintModulePass(errs()))
MODULE_PASS("print-callgraph", CallGraphPrinterPass(errs()))
MODULE_PASS("print-callgraph-sccs", CallGraphSCCsPrinterPass(errs()))
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(errs()))
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index aab9e83c11570..77693f8b25c98 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -201,7 +201,7 @@ void printIR(raw_ostream &OS, const Function *F) {
void printIR(raw_ostream &OS, const Module *M) {
if (isFunctionInPrintList("*") || forcePrintModuleIR()) {
- M->printWithPersistentMetadataIDs(OS);
+ M->print(OS, nullptr);
} else {
for (const auto &F : M->functions()) {
printIR(OS, &F);
@@ -327,12 +327,12 @@ void unwrapAndPrint(raw_ostream &OS, IRUnitRef IR) {
// Return true when this is a pass for which changes should be ignored
bool isIgnored(StringRef PassID) {
- return isSpecialPass(PassID,
- {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
- "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
- "VerifierPass", "PrintModulePass", "PrintMIRPass",
- "PrintMIRPreparePass", "RequireAnalysisPass",
- "InvalidateAnalysisPass"});
+ return isSpecialPass(
+ PassID,
+ {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
+ "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass", "VerifierPass",
+ "PrintModulePass", "PrintCanonicalModulePass", "PrintMIRPass",
+ "PrintMIRPreparePass", "RequireAnalysisPass", "InvalidateAnalysisPass"});
}
std::string makeHTMLReady(StringRef SR) {
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 272e2db675431..15ace15d5e845 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -9,6 +9,7 @@
#include "DXILPrettyPrinter.h"
#include "DirectX.h"
#include "DirectXIRPasses/DXILDebugInfo.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
@@ -265,12 +266,14 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
ModuleSlotTracker &MST;
AbstractSlotTrackerStorage &STS;
const DXILDebugInfoMap &DI;
+ DenseSet<const MDNode *> &EmittedMDNodes;
public:
DXILAssemblyAnnotationWriter(ModuleSlotTracker &MST,
AbstractSlotTrackerStorage &STS,
- const DXILDebugInfoMap &DI)
- : MST(MST), STS(STS), DI(DI) {}
+ const DXILDebugInfoMap &DI,
+ DenseSet<const MDNode *> &EmittedMDNodes)
+ : MST(MST), STS(STS), DI(DI), EmittedMDNodes(EmittedMDNodes) {}
void emitInstructionAnnot(const Instruction *OrigI,
formatted_raw_ostream &os) override {
@@ -282,10 +285,11 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
}
void emitMDNodeAnnot(const MDNode *N, formatted_raw_ostream &os) override {
+ EmittedMDNodes.insert(N);
+
if (const Metadata *NewMD = DI.MDReplace.lookup(N)) {
if (const auto *NewN = dyn_cast<MDNode>(NewMD))
- if (STS.getMetadataSlot(NewN) == -1)
- STS.createMetadataSlot(NewN);
+ STS.createMetadataSlot(NewN);
os << "; DXIL: ";
N->printAsOperand(os, MST);
@@ -297,8 +301,7 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
if (const Metadata *ExtraMD = DI.MDExtra.lookup(N)) {
if (const auto *ExtraN = dyn_cast<MDNode>(ExtraMD))
- if (STS.getMetadataSlot(ExtraN) == -1)
- STS.createMetadataSlot(ExtraN);
+ STS.createMetadataSlot(ExtraN);
os << "; DXIL: ";
N->printAsOperand(os, MST);
@@ -321,28 +324,27 @@ static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
ModuleSlotTracker MST(&M);
AbstractSlotTrackerStorage *STS = nullptr;
- unsigned NextMetadataSlot = 0;
MST.setProcessHook(
- [&](AbstractSlotTrackerStorage *STS_, const Module *, bool) {
- STS = STS_;
- NextMetadataSlot = STS->getNextMetadataSlot();
- });
+ [&](AbstractSlotTrackerStorage *STS_, const Module *) { STS = STS_; });
// Force initialisation. ModuleSlotTracker does not have a dedicated function
// for this so trigger it through a dummy print.
MDNode::get(M.getContext(), {})->print(llvm::nulls(), MST);
assert(STS && "Slot tracker storage should have been initialised");
- DXILAssemblyAnnotationWriter DAAW(MST, *STS, DI);
+ DenseSet<const MDNode *> EmittedMDNodes;
+ DXILAssemblyAnnotationWriter DAAW(MST, *STS, DI, EmittedMDNodes);
M.print(FOS, &DAAW);
ModuleSlotTracker::MachineMDNodeListType MDNodes;
- MST.collectMDNodes(MDNodes, NextMetadataSlot, ~0u);
+ MST.collectMDNodes(MDNodes);
std::sort(MDNodes.begin(), MDNodes.end(),
[](const std::pair<unsigned, const MDNode *> &A,
const std::pair<unsigned, const MDNode *> &B) {
return A.first < B.first;
});
for (auto [_, MDNode] : MDNodes) {
+ if (EmittedMDNodes.contains(MDNode))
+ continue;
DAAW.emitMDNodeAnnot(MDNode, FOS);
MDNode->print(FOS, MST);
FOS << "\n";
diff --git a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
index 6c9f5363e2371..b7fbe43cfa3a3 100644
--- a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
+++ b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
@@ -14,12 +14,12 @@ define void @test1(ptr %P, ptr %Q) nounwind ssp {
; CHECK-LABEL: Function: test1:
; CHECK: MayAlias: i8* %P, i8* %Q
-; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
-; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
+; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
-; CHECK: NoModRef: tail call void @llvm.experimental.noalias.scope.decl(metadata !0) <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
-; CHECK: NoModRef: tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK: NoModRef: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}}) <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
+; CHECK: NoModRef: tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
}
diff --git a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
index 773ef494a51b6..49f1bd83e96dd 100644
--- a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
+++ b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
@@ -7,7 +7,7 @@ define i32 @trivially_free() {
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 1
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
@@ -25,7 +25,7 @@ define i32 @trivially_free() {
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 1
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
diff --git a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
index f2117123ab8eb..4eeac08318cda 100644
--- a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
+++ b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
@@ -9,7 +9,7 @@ define i32 @trivially_free() {
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 4
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
@@ -29,7 +29,7 @@ define i32 @trivially_free() {
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 4
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
diff --git a/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll b/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
index e454f110e0ee3..eab298a9bedf5 100644
--- a/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
+++ b/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
@@ -7,7 +7,7 @@ define i32 @trivially_free() {
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 1
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
@@ -27,7 +27,7 @@ define i32 @trivially_free() {
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %alloca = alloca i8, align 1
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a0 = call i32 @llvm.annotation.i32.p0(i32 undef, ptr undef, ptr undef, i32 undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.assume(i1 undef)
-; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.sideeffect()
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a1 = call ptr @llvm.invariant.start.p0(i64 1, ptr undef)
; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.invariant.end.p0(ptr undef, i64 1, ptr undef)
diff --git a/llvm/test/Analysis/DependenceAnalysis/AA.ll b/llvm/test/Analysis/DependenceAnalysis/AA.ll
index 173744a07ef96..a336e4fd49bb4 100644
--- a/llvm/test/Analysis/DependenceAnalysis/AA.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/AA.ll
@@ -99,11 +99,11 @@ define void @test_global_size() {
define void @test_tbaa_same(ptr %A, ptr %B) {
; CHECK-LABEL: 'test_tbaa_same'
-; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !0 --> Dst: store i32 1, ptr %A, align 4, !tbaa !0
+; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
-; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !0 --> Dst: store i32 2, ptr %B, align 4, !tbaa !0
+; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 2, ptr %B, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - confused!
-; CHECK-NEXT: Src: store i32 2, ptr %B, align 4, !tbaa !0 --> Dst: store i32 2, ptr %B, align 4, !tbaa !0
+; CHECK-NEXT: Src: store i32 2, ptr %B, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 2, ptr %B, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
;
store i32 1, ptr %A, !tbaa !5
@@ -113,11 +113,11 @@ define void @test_tbaa_same(ptr %A, ptr %B) {
define void @test_tbaa_diff(ptr %A, ptr %B) {
; CHECK-LABEL: 'test_tbaa_diff'
-; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !0 --> Dst: store i32 1, ptr %A, align 4, !tbaa !0
+; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
-; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !0 --> Dst: store i16 2, ptr %B, align 2, !tbaa !4
+; CHECK-NEXT: Src: store i32 1, ptr %A, align 4, !tbaa !{{[0-9]+}} --> Dst: store i16 2, ptr %B, align 2, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
-; CHECK-NEXT: Src: store i16 2, ptr %B, align 2, !tbaa !4 --> Dst: store i16 2, ptr %B, align 2, !tbaa !4
+; CHECK-NEXT: Src: store i16 2, ptr %B, align 2, !tbaa !{{[0-9]+}} --> Dst: store i16 2, ptr %B, align 2, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
;
store i32 1, ptr %A, !tbaa !5
@@ -127,11 +127,11 @@ define void @test_tbaa_diff(ptr %A, ptr %B) {
define void @tbaa_loop(i32 %I, i32 %J, ptr nocapture %A, ptr nocapture readonly %B) {
; CHECK-LABEL: 'tbaa_loop'
-; CHECK-NEXT: Src: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !0 --> Dst: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !0
+; CHECK-NEXT: Src: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !{{[0-9]+}} --> Dst: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - input [* *]!
-; CHECK-NEXT: Src: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !0 --> Dst: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !4
+; CHECK-NEXT: Src: %0 = load i16, ptr %arrayidx.us, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - none!
-; CHECK-NEXT: Src: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !4 --> Dst: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !4
+; CHECK-NEXT: Src: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !{{[0-9]+}} --> Dst: store i32 %add.us.lcssa, ptr %arrayidx6.us, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: da analyze - output [*]!
;
entry:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/loops-with-indirect-reads-and-writes.ll b/llvm/test/Analysis/LoopAccessAnalysis/loops-with-indirect-reads-and-writes.ll
index 3518d92c3511f..69c645e3a2863 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/loops-with-indirect-reads-and-writes.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/loops-with-indirect-reads-and-writes.ll
@@ -25,12 +25,12 @@ define void @test_indirect_read_write_loop_also_modifies_pointer_array(ptr nound
; CHECK-NEXT: Unsafe indirect dependence.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: IndirectUnsafe:
-; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !4 ->
-; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !4
+; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !{{[0-9]+}} ->
+; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Unknown:
-; CHECK-NEXT: %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !0 ->
-; CHECK-NEXT: store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !0
+; CHECK-NEXT: %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !{{[0-9]+}} ->
+; CHECK-NEXT: store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
@@ -230,12 +230,12 @@ define void @test_indirect_read_write_loop_does_not_modify_pointer_array(ptr nou
; CHECK-NEXT: Unsafe indirect dependence.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: IndirectUnsafe:
-; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !4 ->
-; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !4
+; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !{{[0-9]+}} ->
+; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Unknown:
; CHECK-NEXT: %l.3 = load i64, ptr %gep.arr2.iv.1, align 8 ->
-; CHECK-NEXT: store i64 %inc.2, ptr %gep.arr2.iv.2, align 8, !tbaa !0
+; CHECK-NEXT: store i64 %inc.2, ptr %gep.arr2.iv.2, align 8, !tbaa !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/noalias-scope-decl.ll b/llvm/test/Analysis/LoopAccessAnalysis/noalias-scope-decl.ll
index fb296f5089422..df0695f216aa4 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/noalias-scope-decl.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/noalias-scope-decl.ll
@@ -11,12 +11,12 @@ define void @test_scope_in_loop(ptr %arg, i64 %num) {
; CHECK-NEXT: Backward loop carried data dependence.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Backward:
-; CHECK-NEXT: %load.prev = load i8, ptr %prev.ptr, align 1, !alias.scope !0, !noalias !3 ->
-; CHECK-NEXT: store i8 %add, ptr %cur.ptr, align 1, !alias.scope !3
+; CHECK-NEXT: %load.prev = load i8, ptr %prev.ptr, align 1, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}} ->
+; CHECK-NEXT: store i8 %add, ptr %cur.ptr, align 1, !alias.scope !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Forward:
-; CHECK-NEXT: %load.cur = load i8, ptr %cur.ptr, align 1, !alias.scope !3 ->
-; CHECK-NEXT: store i8 %add, ptr %cur.ptr, align 1, !alias.scope !3
+; CHECK-NEXT: %load.cur = load i8, ptr %cur.ptr, align 1, !alias.scope !{{[0-9]+}} ->
+; CHECK-NEXT: store i8 %add, ptr %cur.ptr, align 1, !alias.scope !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll b/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll
index 0708f908211ef..2a90b3179df6d 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll
@@ -11,8 +11,8 @@ define void @indirect_ptr_recurrences_read_write(ptr %A, ptr %B) {
; CHECK-NEXT: Unsafe indirect dependence.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: IndirectUnsafe:
-; CHECK-NEXT: %l = load i32, ptr %ptr.recur, align 4, !tbaa !4 ->
-; CHECK-NEXT: store i32 %xor, ptr %ptr.recur, align 4, !tbaa !4
+; CHECK-NEXT: %l = load i32, ptr %ptr.recur, align 4, !tbaa !{{[0-9]+}} ->
+; CHECK-NEXT: store i32 %xor, ptr %ptr.recur, align 4, !tbaa !{{[0-9]+}}
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
diff --git a/llvm/test/Analysis/MemorySSA/invariant-groups.ll b/llvm/test/Analysis/MemorySSA/invariant-groups.ll
index 2042855af5569..8cc0a30d9c4a7 100644
--- a/llvm/test/Analysis/MemorySSA/invariant-groups.ll
+++ b/llvm/test/Analysis/MemorySSA/invariant-groups.ll
@@ -348,7 +348,7 @@ define i8 @optimizable() {
entry:
%ptr = alloca i8
; CHECK: 1 = MemoryDef(liveOnEntry)
-; CHECK-NEXT: store i8 42, ptr %ptr, align 1, !invariant.group !0
+; CHECK-NEXT: store i8 42, ptr %ptr, align 1, !invariant.group !{{[0-9]+}}
store i8 42, ptr %ptr, !invariant.group !0
; CHECK: 2 = MemoryDef(1)
; CHECK-NEXT: call ptr @llvm.launder.invariant.group
@@ -377,7 +377,7 @@ entry:
define i8 @unoptimizable2() {
%ptr = alloca i8
; CHECK: 1 = MemoryDef(liveOnEntry)
-; CHECK-NEXT: store i8 42, ptr %ptr, align 1, !invariant.group !0
+; CHECK-NEXT: store i8 42, ptr %ptr, align 1, !invariant.group !{{[0-9]+}}
store i8 42, ptr %ptr, !invariant.group !0
; CHECK: 2 = MemoryDef(1)
; CHECK-NEXT: call ptr @llvm.launder.invariant.group
@@ -397,7 +397,7 @@ define i8 @unoptimizable2() {
; CHECK-NEXT: call void @use(ptr %ptr3)
call void @use(ptr %ptr3)
; CHECK: MemoryUse(7)
-; CHECK-NEXT: %v = load i8, ptr %ptr3, align 1, !invariant.group !0
+; CHECK-NEXT: %v = load i8, ptr %ptr3, align 1, !invariant.group !{{[0-9]+}}
%v = load i8, ptr %ptr3, !invariant.group !0
ret i8 %v
}
diff --git a/llvm/test/Analysis/MemorySSA/invariant-load-intrinsic.ll b/llvm/test/Analysis/MemorySSA/invariant-load-intrinsic.ll
index 0151912bfc205..0ab1eaa54ff34 100644
--- a/llvm/test/Analysis/MemorySSA/invariant-load-intrinsic.ll
+++ b/llvm/test/Analysis/MemorySSA/invariant-load-intrinsic.ll
@@ -7,7 +7,7 @@ define <4 x i32> @masked_load_invariant(ptr %p, <4 x i1> %mask, <4 x i32> %passt
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: call void @clobber(ptr %p)
; CHECK: MemoryUse(liveOnEntry)
-; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr align 4 %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
+; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr align 4 %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !{{[0-9]+}}
call void @clobber(ptr %p)
%v = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr align 4 %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
ret <4 x i32> %v
@@ -29,7 +29,7 @@ define <4 x i32> @masked_gather_invariant(ptr %p, <4 x ptr> %ptrs, <4 x i1> %mas
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: call void @clobber(ptr %p)
; CHECK: MemoryUse(liveOnEntry)
-; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> align 4 %ptrs, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
+; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> align 4 %ptrs, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !{{[0-9]+}}
call void @clobber(ptr %p)
%v = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> align 4 %ptrs, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
ret <4 x i32> %v
@@ -40,7 +40,7 @@ define <4 x i32> @masked_expandload_invariant(ptr %p, <4 x i1> %mask, <4 x i32>
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: call void @clobber(ptr %p)
; CHECK: MemoryUse(liveOnEntry)
-; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.expandload.v4i32.p0(ptr %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
+; CHECK-NEXT: %v = call <4 x i32> @llvm.masked.expandload.v4i32.p0(ptr %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !{{[0-9]+}}
call void @clobber(ptr %p)
%v = call <4 x i32> @llvm.masked.expandload.v4i32.p0(ptr %p, <4 x i1> %mask, <4 x i32> %passthru), !invariant.load !0
ret <4 x i32> %v
@@ -51,7 +51,7 @@ define <4 x i32> @vp_gather_invariant(ptr %p, <4 x ptr> %ptrs, <4 x i1> %mask, i
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: call void @clobber(ptr %p)
; CHECK: MemoryUse(liveOnEntry)
-; CHECK-NEXT: %v = call <4 x i32> @llvm.vp.gather.v4i32.v4p0(<4 x ptr> %ptrs, <4 x i1> %mask, i32 %vl), !invariant.load !0
+; CHECK-NEXT: %v = call <4 x i32> @llvm.vp.gather.v4i32.v4p0(<4 x ptr> %ptrs, <4 x i1> %mask, i32 %vl), !invariant.load !{{[0-9]+}}
call void @clobber(ptr %p)
%v = call <4 x i32> @llvm.vp.gather.v4i32.v4p0(<4 x ptr> %ptrs, <4 x i1> %mask, i32 %vl), !invariant.load !0
ret <4 x i32> %v
diff --git a/llvm/test/Analysis/ScalarEvolution/cycled_phis.ll b/llvm/test/Analysis/ScalarEvolution/cycled_phis.ll
index 478bcf94daf69..7e1fe130710c0 100644
--- a/llvm/test/Analysis/ScalarEvolution/cycled_phis.ll
+++ b/llvm/test/Analysis/ScalarEvolution/cycled_phis.ll
@@ -35,13 +35,13 @@ exit:
define void @test_02(ptr %p, ptr %q) {
; CHECK-LABEL: 'test_02'
; CHECK-NEXT: Classifying expressions for: @test_02
-; CHECK-NEXT: %start = load i32, ptr %p, align 4, !range !0
+; CHECK-NEXT: %start = load i32, ptr %p, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %start U: [0,1000) S: [0,1000)
; CHECK-NEXT: %outer_phi = phi i32 [ %start, %entry ], [ %inner_lcssa, %outer_backedge ]
; CHECK-NEXT: --> %outer_phi U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer_loop: Variant, %inner_loop: Invariant }
; CHECK-NEXT: %inner_phi = phi i32 [ %outer_phi, %outer_loop ], [ %inner_load, %inner_loop ]
; CHECK-NEXT: --> %inner_phi U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner_loop: Variant, %outer_loop: Variant }
-; CHECK-NEXT: %inner_load = load i32, ptr %q, align 4, !range !1
+; CHECK-NEXT: %inner_load = load i32, ptr %q, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %inner_load U: [2000,3000) S: [2000,3000) Exits: <<Unknown>> LoopDispositions: { %inner_loop: Variant, %outer_loop: Variant }
; CHECK-NEXT: %inner_cond = call i1 @cond()
; CHECK-NEXT: --> %inner_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner_loop: Variant, %outer_loop: Variant }
@@ -84,9 +84,9 @@ exit:
define void @test_03(ptr %p, ptr %q) {
; CHECK-LABEL: 'test_03'
; CHECK-NEXT: Classifying expressions for: @test_03
-; CHECK-NEXT: %start_1 = load i32, ptr %p, align 4, !range !0
+; CHECK-NEXT: %start_1 = load i32, ptr %p, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %start_1 U: [0,1000) S: [0,1000)
-; CHECK-NEXT: %start_2 = load i32, ptr %q, align 4, !range !1
+; CHECK-NEXT: %start_2 = load i32, ptr %q, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %start_2 U: [2000,3000) S: [2000,3000)
; CHECK-NEXT: %outer_phi = phi i32 [ %start_1, %entry ], [ %inner_lcssa, %outer_backedge ]
; CHECK-NEXT: --> %outer_phi U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer_loop: Variant, %inner_loop: Invariant }
diff --git a/llvm/test/Analysis/ScalarEvolution/unknown_phis.ll b/llvm/test/Analysis/ScalarEvolution/unknown_phis.ll
index c6d430f96b7de..99d23570f2d88 100644
--- a/llvm/test/Analysis/ScalarEvolution/unknown_phis.ll
+++ b/llvm/test/Analysis/ScalarEvolution/unknown_phis.ll
@@ -4,9 +4,9 @@
define void @merge_values_with_ranges(ptr %a_len_ptr, ptr %b_len_ptr, i1 %unknown_cond) {
; CHECK-LABEL: 'merge_values_with_ranges'
; CHECK-NEXT: Classifying expressions for: @merge_values_with_ranges
-; CHECK-NEXT: %len_a = load i32, ptr %a_len_ptr, align 4, !range !0
+; CHECK-NEXT: %len_a = load i32, ptr %a_len_ptr, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %len_a U: [0,2147483647) S: [0,2147483647)
-; CHECK-NEXT: %len_b = load i32, ptr %b_len_ptr, align 4, !range !0
+; CHECK-NEXT: %len_b = load i32, ptr %b_len_ptr, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %len_b U: [0,2147483647) S: [0,2147483647)
; CHECK-NEXT: %len = phi i32 [ %len_a, %if.true ], [ %len_b, %if.false ]
; CHECK-NEXT: --> %len U: [0,2147483647) S: [0,2147483647)
@@ -34,9 +34,9 @@ define void @merge_values_with_ranges_looped(ptr %a_len_ptr, ptr %b_len_ptr) {
; go into infinite loop analyzing these Phis.
; CHECK-LABEL: 'merge_values_with_ranges_looped'
; CHECK-NEXT: Classifying expressions for: @merge_values_with_ranges_looped
-; CHECK-NEXT: %len_a = load i32, ptr %a_len_ptr, align 4, !range !0
+; CHECK-NEXT: %len_a = load i32, ptr %a_len_ptr, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %len_a U: [0,2147483647) S: [0,2147483647)
-; CHECK-NEXT: %len_b = load i32, ptr %b_len_ptr, align 4, !range !0
+; CHECK-NEXT: %len_b = load i32, ptr %b_len_ptr, align 4, !range !{{[0-9]+}}
; CHECK-NEXT: --> %len_b U: [0,2147483647) S: [0,2147483647)
; CHECK-NEXT: %p1 = phi i32 [ %len_a, %entry ], [ %p2, %loop ]
; CHECK-NEXT: --> %p1 U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
diff --git a/llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll b/llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll
index 96fceee2bcfc6..35a87d5013d2c 100644
--- a/llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll
+++ b/llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll
@@ -40,16 +40,15 @@ attributes #0 = { nounwind uwtable }
; A list of scopes from both domains.
!0 = !{!1, !3, !4}
-; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !6
-; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !6
-; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !7
-; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !7 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !6
-; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !7 <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !6
-; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !7 <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !7
-; CHECK: NoAlias: %2 = load float, ptr %c, align 4, !alias.scope !6 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !6
-; CHECK: NoAlias: %2 = load float, ptr %c, align 4, !alias.scope !6 <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !6
-; CHECK: MayAlias: %2 = load float, ptr %c, align 4, !alias.scope !6 <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !7
-; CHECK: NoAlias: store float %1, ptr %arrayidx.i2, align 4, !noalias !6 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !6
-; CHECK: NoAlias: store float %2, ptr %arrayidx.i3, align 4, !noalias !7 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !6
-; CHECK: NoAlias: store float %2, ptr %arrayidx.i3, align 4, !noalias !7 <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !6
-
+; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !{{[0-9]+}}
+; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %1 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %2 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: %2 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !{{[0-9]+}}
+; CHECK: MayAlias: %2 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %2, ptr %arrayidx.i3, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: store float %1, ptr %arrayidx.i2, align 4, !noalias !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: store float %2, ptr %arrayidx.i3, align 4, !noalias !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: store float %2, ptr %arrayidx.i3, align 4, !noalias !{{[0-9]+}} <-> store float %1, ptr %arrayidx.i2, align 4, !noalias !{{[0-9]+}}
diff --git a/llvm/test/Analysis/ScopedNoAliasAA/basic.ll b/llvm/test/Analysis/ScopedNoAliasAA/basic.ll
index 0a16a11e007d5..e7f1a5f147035 100644
--- a/llvm/test/Analysis/ScopedNoAliasAA/basic.ll
+++ b/llvm/test/Analysis/ScopedNoAliasAA/basic.ll
@@ -13,11 +13,11 @@ entry:
store float %1, ptr %arrayidx, align 4
ret void
-; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !0
-; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %1, ptr %arrayidx, align 4
-; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !0
+; CHECK: NoAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
+; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %1, ptr %arrayidx, align 4
+; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %1, ptr %arrayidx, align 4
-; CHECK: NoAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !0
+; CHECK: NoAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !noalias !{{[0-9]+}}
}
attributes #0 = { nounwind uwtable }
diff --git a/llvm/test/Analysis/ScopedNoAliasAA/basic2.ll b/llvm/test/Analysis/ScopedNoAliasAA/basic2.ll
index b17f4e1a25fb8..3c8db958bdc21 100644
--- a/llvm/test/Analysis/ScopedNoAliasAA/basic2.ll
+++ b/llvm/test/Analysis/ScopedNoAliasAA/basic2.ll
@@ -15,19 +15,19 @@ entry:
store float %1, ptr %arrayidx, align 4
ret void
-; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !4, !noalia
-; CHECK: s !5
-; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !0, !noali
-; CHECK: as !4
-; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !0 <-> store float %1, ptr %arrayidx, align 4
-; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !4, !noalias !5
-; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !0, !noalias !4
+; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !{{[0-9]+}}, !noalia
+; CHECK: s !{{[0-9]+}}
+; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !{{[0-9]+}}, !noali
+; CHECK: as !{{[0-9]+}}
+; CHECK: MayAlias: %0 = load float, ptr %c, align 4, !alias.scope !{{[0-9]+}} <-> store float %1, ptr %arrayidx, align 4
+; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}}
+; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}}
; CHECK: MayAlias: %1 = load float, ptr %c, align 4 <-> store float %1, ptr %arrayidx, align 4
-; CHECK: NoAlias: store float %0, ptr %arrayidx1.i, align 4, !alias.scope !0, !noalias !4 <-> store float %0, ptr %arrayidx.i, align
-; CHECK: 4, !alias.scope !4, !noalias !5
-; CHECK: NoAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !4, !noalias !5
-; CHECK: MayAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !0, !noalias !
-; CHECK: 4
+; CHECK: NoAlias: store float %0, ptr %arrayidx1.i, align 4, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}} <-> store float %0, ptr %arrayidx.i, align
+; CHECK: 4, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}}
+; CHECK: NoAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx.i, align 4, !alias.scope !{{[0-9]+}}, !noalias !{{[0-9]+}}
+; CHECK: MayAlias: store float %1, ptr %arrayidx, align 4 <-> store float %0, ptr %arrayidx1.i, align 4, !alias.scope !{{[0-9]+}}, !noalias !
+; CHECK: {{[0-9]+}}
}
attributes #0 = { nounwind uwtable }
@@ -38,4 +38,3 @@ attributes #0 = { nounwind uwtable }
!3 = !{!3, !2, !"some other scope"}
!4 = !{!1}
!5 = !{!3}
-
diff --git a/llvm/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll b/llvm/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
index e9ce95b57d00b..7f28a6368e318 100644
--- a/llvm/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
+++ b/llvm/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
@@ -18,7 +18,7 @@
; Basic AA says MayAlias, TBAA says NoAlias
; CHECK: MayAlias: ptr* %5, i64* %9
-; CHECK: NoAlias: store i64 %conv, ptr %9, align 8, !tbaa !6 <-> store ptr null, ptr %5, align 8, !tbaa !9
+; CHECK: NoAlias: store i64 %conv, ptr %9, align 8, !tbaa !{{[0-9]+}} <-> store ptr null, ptr %5, align 8, !tbaa !{{[0-9]+}}
%struct.Foo = type { i64 }
%struct.Bar = type { ptr }
diff --git a/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll b/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll
index f9a2988dc7e40..2529dc6865fe9 100644
--- a/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll
+++ b/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll
@@ -13,7 +13,7 @@ define i32 @_Z1gPjP7StructAy(ptr %s, ptr %A, i64 %count) {
entry:
; Access to ptr and &(A->f32).
; CHECK: Function
-; CHECK: MayAlias: store i32 4, ptr %f32, align 4, !tbaa !8 <-> store i32 1, ptr %0, align 4, !tbaa !6
+; CHECK: MayAlias: store i32 4, ptr %f32, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %0, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -39,7 +39,7 @@ define i32 @_Z2g2PjP7StructAy(ptr %s, ptr %A, i64 %count) {
entry:
; Access to ptr and &(A->f16).
; CHECK: Function
-; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !8 <-> store i32 1, ptr %0, align 4, !tbaa !6
+; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %0, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i16 4
@@ -64,7 +64,7 @@ define i32 @_Z2g3P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) {
entry:
; Access to &(A->f32) and &(B->a.f32).
; CHECK: Function
-; CHECK: MayAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: MayAlias: store i32 4, ptr %f321, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -93,7 +93,7 @@ define i32 @_Z2g4P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) {
entry:
; Access to &(A->f32) and &(B->a.f16).
; CHECK: Function
-; CHECK: NoAlias: store i16 4, ptr %a, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i16 4, ptr %a, align 2, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i16 4
@@ -121,7 +121,7 @@ define i32 @_Z2g5P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) {
entry:
; Access to &(A->f32) and &(B->f32).
; CHECK: Function
-; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -149,7 +149,7 @@ define i32 @_Z2g6P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) {
entry:
; Access to &(A->f32) and &(B->a.f32_2).
; CHECK: Function
-; CHECK: NoAlias: store i32 4, ptr %f32_2, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i32 4, ptr %f32_2, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -178,7 +178,7 @@ define i32 @_Z2g7P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) {
entry:
; Access to &(A->f32) and &(S->f32).
; CHECK: Function
-; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -206,7 +206,7 @@ define i32 @_Z2g8P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) {
entry:
; Access to &(A->f32) and &(S->f16).
; CHECK: Function
-; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i16 4
@@ -233,7 +233,7 @@ define i32 @_Z2g9P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) {
entry:
; Access to &(S->f32) and &(S2->f32).
; CHECK: Function
-; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -261,7 +261,7 @@ define i32 @_Z3g10P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) {
entry:
; Access to &(S->f32) and &(S2->f16).
; CHECK: Function
-; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i16 4
@@ -288,7 +288,7 @@ define i32 @_Z3g11P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) {
entry:
; Access to &(C->b.a.f32) and &(D->b.a.f32).
; CHECK: Function
-; CHECK: NoAlias: store i32 4, ptr %f323, align 4, !tbaa !12 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: NoAlias: store i32 4, ptr %f323, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
@@ -322,7 +322,7 @@ define i32 @_Z3g12P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) {
entry:
; Access to &(b1->a.f32) and &(b2->a.f32).
; CHECK: Function
-; CHECK: MayAlias: store i32 4, ptr %f325, align 4, !tbaa !6 <-> store i32 1, ptr %f32, align 4, !tbaa !6
+; CHECK: MayAlias: store i32 4, ptr %f325, align 4, !tbaa !{{[0-9]+}} <-> store i32 1, ptr %f32, align 4, !tbaa !{{[0-9]+}}
; OPT: define
; OPT: store i32 1
; OPT: store i32 4
diff --git a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
index f7e69b0c1f04f..81044dfa17fce 100644
--- a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
+++ b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
@@ -230,8 +230,8 @@ define void @byval(ptr byval(i8) %i8_byval,
}
; CHECK-LABEL: 'f_0'
-; GLOBAL: %ptr = inttoptr i32 %val to ptr, !dereferenceable !0
-; POINT-NOT: %ptr = inttoptr i32 %val to ptr, !dereferenceable !0
+; GLOBAL: %ptr = inttoptr i32 %val to ptr, !dereferenceable !{{[0-9]+}}
+; POINT-NOT: %ptr = inttoptr i32 %val to ptr, !dereferenceable !{{[0-9]+}}
define i32 @f_0(i32 %val) {
%ptr = inttoptr i32 %val to ptr, !dereferenceable !0
call void @mayfree()
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-metadata.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-metadata.ll
index f8b1a3879421d..1c6c52e0be081 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-metadata.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-metadata.ll
@@ -7,7 +7,7 @@ define i32 @reloc_constant() {
; CHECK-LABEL: name: reloc_constant
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: [[INT:%[0-9]+]]:_(i32) = G_INTRINSIC intrinsic(@llvm.amdgcn.reloc.constant), !0
- ; CHECK-NEXT: [[INT1:%[0-9]+]]:_(i32) = G_INTRINSIC intrinsic(@llvm.amdgcn.reloc.constant), <{{0x[0-9a-f]+}}>
+ ; CHECK-NEXT: [[INT1:%[0-9]+]]:_(i32) = G_INTRINSIC intrinsic(@llvm.amdgcn.reloc.constant), !1
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(i32) = G_ADD [[INT]], [[INT1]]
; CHECK-NEXT: $vgpr0 = COPY [[ADD]](i32)
; CHECK-NEXT: SI_RETURN implicit $vgpr0
diff --git a/llvm/test/CodeGen/AMDGPU/dbg-value-ends-sched-region.mir b/llvm/test/CodeGen/AMDGPU/dbg-value-ends-sched-region.mir
index de68534fdfedc..8916ad00c9efe 100644
--- a/llvm/test/CodeGen/AMDGPU/dbg-value-ends-sched-region.mir
+++ b/llvm/test/CodeGen/AMDGPU/dbg-value-ends-sched-region.mir
@@ -90,7 +90,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: dead [[COPY7:%[0-9]+]]:sreg_64 = COPY $exec
; CHECK-NEXT: dead [[GLOBAL_LOAD_DWORDX4_:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 [[COPY1]], 0, 0, implicit $exec :: (load (s128), addrspace 1)
- ; CHECK-NEXT: DBG_VALUE [[GLOBAL_LOAD_DWORDX4_]], $noreg, <0x{{[0-9a-f]+}}>, !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), debug-location !DILocation(line: 0, scope: <0x{{[0-9a-f]+}}>)
+ ; CHECK-NEXT: DBG_VALUE [[GLOBAL_LOAD_DWORDX4_]], $noreg, !10, !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), debug-location !5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5:
; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000)
diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-partial-reg-uses-dbg.mir b/llvm/test/CodeGen/AMDGPU/rewrite-partial-reg-uses-dbg.mir
index 8eb8050dbd9f2..c670d1bc79ee4 100644
--- a/llvm/test/CodeGen/AMDGPU/rewrite-partial-reg-uses-dbg.mir
+++ b/llvm/test/CodeGen/AMDGPU/rewrite-partial-reg-uses-dbg.mir
@@ -38,19 +38,19 @@ body: |
; CHECK-LABEL: name: test_vreg_96_w64
; CHECK: undef [[V_MOV_B32_e32_:%[0-9]+]].sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec, debug-location !11
; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_]].sub0, $noreg, !9, !DIExpression(), debug-location !11
- ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 1, implicit $exec, debug-location !DILocation(line: 2, column: 1, scope: !5)
- ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_]].sub1, $noreg, !9, !DIExpression(), debug-location !DILocation(line: 2, column: 1, scope: !5)
- ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_]], debug-location !DILocation(line: 3, column: 1, scope: !5)
- ; CHECK-NEXT: undef [[V_MOV_B32_e32_1:%[0-9]+]].sub0:vreg_64 = V_MOV_B32_e32 11, implicit $exec, debug-location !DILocation(line: 4, column: 1, scope: !5)
- ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_1]].sub0, $noreg, !9, !DIExpression(), debug-location !DILocation(line: 4, column: 1, scope: !5)
- ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 12, implicit $exec, debug-location !DILocation(line: 5, column: 1, scope: !5)
- ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_1]].sub1, $noreg, !9, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !5)
- ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_1]], debug-location !DILocation(line: 6, column: 1, scope: !5)
- ; CHECK-NEXT: undef [[V_MOV_B32_e32_2:%[0-9]+]].sub0:vreg_64 = V_MOV_B32_e32 11, implicit $exec, debug-location !DILocation(line: 4, column: 1, scope: !5)
- ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_2]], $noreg, !9, !DIExpression(), debug-location !DILocation(line: 4, column: 1, scope: !5)
- ; CHECK-NEXT: [[V_MOV_B32_e32_2:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 12, implicit $exec, debug-location !DILocation(line: 5, column: 1, scope: !5)
- ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_2]], $noreg, !9, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !5)
- ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_2]], debug-location !DILocation(line: 6, column: 1, scope: !5)
+ ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 1, implicit $exec, debug-location !12
+ ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_]].sub1, $noreg, !9, !DIExpression(), debug-location !12
+ ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_]], debug-location !13
+ ; CHECK-NEXT: undef [[V_MOV_B32_e32_1:%[0-9]+]].sub0:vreg_64 = V_MOV_B32_e32 11, implicit $exec, debug-location !14
+ ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_1]].sub0, $noreg, !9, !DIExpression(), debug-location !14
+ ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 12, implicit $exec, debug-location !15
+ ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_1]].sub1, $noreg, !9, !DIExpression(), debug-location !15
+ ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_1]], debug-location !16
+ ; CHECK-NEXT: undef [[V_MOV_B32_e32_2:%[0-9]+]].sub0:vreg_64 = V_MOV_B32_e32 11, implicit $exec, debug-location !14
+ ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_2]], $noreg, !9, !DIExpression(), debug-location !14
+ ; CHECK-NEXT: [[V_MOV_B32_e32_2:%[0-9]+]].sub1:vreg_64 = V_MOV_B32_e32 12, implicit $exec, debug-location !15
+ ; CHECK-NEXT: DBG_VALUE [[V_MOV_B32_e32_2]], $noreg, !9, !DIExpression(), debug-location !15
+ ; CHECK-NEXT: S_NOP 0, implicit [[V_MOV_B32_e32_2]], debug-location !16
undef %0.sub0:vreg_96 = V_MOV_B32_e32 0, implicit $exec, debug-location !11
DBG_VALUE %0.sub0, $noreg, !9, !DIExpression(), debug-location !11
%0.sub1:vreg_96 = V_MOV_B32_e32 1, implicit $exec, debug-location !DILocation(line: 2, column: 1, scope: !5)
diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir b/llvm/test/CodeGen/AMDGPU/sgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
index 2af4e95b17cad..c576367f38e12 100644
--- a/llvm/test/CodeGen/AMDGPU/sgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
+++ b/llvm/test/CodeGen/AMDGPU/sgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
@@ -40,8 +40,12 @@ machineFunctionInfo:
privateSegmentWaveByteOffset: { reg: '$sgpr9' }
body: |
; CHECK-LABEL: name: test
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-DAG: '![[LOC:[0-9]+]] = !DILocation(line: 10, column: 9, scope: ![[SP:[0-9]+]])'
+ ; CHECK-DAG: '![[SP]] = distinct !DISubprogram
+ ; CHECK-DAG: '![[VAR:[0-9]+]] = !DILocalVariable(name: "a", scope: ![[SP]],
; CHECK: bb.0:
- ; CHECK: DBG_VALUE_LIST <{{.*}}>, !DIExpression(), $noreg, 0, debug-location !DILocation(line: 10, column: 9, scope: <{{.*}}>)
+ ; CHECK: DBG_VALUE_LIST ![[VAR]], !DIExpression(), $noreg, 0, debug-location ![[LOC]]
bb.0:
renamable $sgpr10 = IMPLICIT_DEF
diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir b/llvm/test/CodeGen/AMDGPU/vgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
index 4a77dd204fa38..8d36014c0560b 100644
--- a/llvm/test/CodeGen/AMDGPU/vgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
+++ b/llvm/test/CodeGen/AMDGPU/vgpr-spill-fi-skip-processing-stack-arg-dbg-value-list.mir
@@ -40,8 +40,12 @@ machineFunctionInfo:
privateSegmentWaveByteOffset: { reg: '$sgpr9' }
body: |
; CHECK-LABEL: name: test
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-DAG: '![[LOC:[0-9]+]] = !DILocation(line: 10, column: 9, scope: ![[SP:[0-9]+]])'
+ ; CHECK-DAG: '![[SP]] = distinct !DISubprogram
+ ; CHECK-DAG: '![[VAR:[0-9]+]] = !DILocalVariable(name: "a", scope: ![[SP]],
; CHECK: bb.0:
- ; CHECK: DBG_VALUE_LIST <{{.*}}>, !DIExpression(), $noreg, 0, debug-location !DILocation(line: 10, column: 9, scope: <{{.*}}>)
+ ; CHECK: DBG_VALUE_LIST ![[VAR]], !DIExpression(), $noreg, 0, debug-location ![[LOC]]
bb.0:
$vgpr2 = IMPLICIT_DEF
SI_SPILL_V32_SAVE $vgpr2, %stack.0, $sgpr32, 0, implicit $exec :: (store (s32) into %stack.0, align 4, addrspace 5)
diff --git a/llvm/test/CodeGen/DirectX/DebugInfo/di-globalvariable.ll b/llvm/test/CodeGen/DirectX/DebugInfo/di-globalvariable.ll
index 978c6f6cfb221..5324ceba1b209 100644
--- a/llvm/test/CodeGen/DirectX/DebugInfo/di-globalvariable.ll
+++ b/llvm/test/CodeGen/DirectX/DebugInfo/di-globalvariable.ll
@@ -1,4 +1,5 @@
; RUN: llc %s -o - | FileCheck %s
+; RUN: llc %s -o - | FileCheck %s --check-prefix=NO-DUP
target triple = "dxil-unknown-shadermodel6.3-library"
@@ -24,6 +25,11 @@ define void @foo() {
; CHECK-DAG: ![[FILE]] = !DIFile(filename: "cu.cpp", directory: "/tmp")
; CHECK-DAG: ![[TYPE]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+; NO-DUP: ![[GVX:[0-9]+]] = !DIGlobalVariable(name: "x"
+; NO-DUP: ![[GVY:[0-9]+]] = !DIGlobalVariable(name: "y"
+; NO-DUP-NOT: ![[GVX]] =
+; NO-DUP-NOT: ![[GVY]] =
+
!llvm.dbg.cu = !{!4}
!llvm.module.flags = !{!8, !9}
diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
index 009dd5c249b9d..4300fcf58fa9b 100644
--- a/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
+++ b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
@@ -7,6 +7,7 @@
# RUN: llc -passes=mir-debugify -debugify-level=locations -o - %s | FileCheck --check-prefixes=ALL --implicit-check-not=dbg_value %s
# RUN: llc -passes=mir-debugify,mir-strip-debug,mir-debugify -o - %s | FileCheck --check-prefixes=ALL,VALUE %s
# RUN: llc -passes=mir-debugify,mir-strip-debug -o - %s | FileCheck --check-prefix=STRIP %s
+# RUN: llc -run-pass=mir-debugify -o - %s | llc -x mir -run-pass=none -filetype=null
--- |
; ModuleID = 'loc-only.ll'
@@ -33,6 +34,9 @@
; VALUE: [[VAR2:![0-9]+]] = !DILocalVariable(name: "2"
; STRIP-NOT: !llvm.debugify
; STRIP-NOT: !llvm.mir.debugify
+ ; ALL: machineMetadataNodes:
+ ; ALL-DAG: - '![[L4:[0-9]+]] = !DILocation(line: 4, column: 1, scope: !{{[0-9]+}})'
+ ; ALL-DAG: - '![[L5:[0-9]+]] = !DILocation(line: 5, column: 1, scope: !{{[0-9]+}})'
...
---
@@ -53,8 +57,8 @@ body: |
; VALUE: DBG_VALUE %1(s32), $noreg, [[VAR2]], !DIExpression(), debug-location [[L2]]
; ALL: %2:_(s32) = G_CONSTANT i32 2, debug-location [[L3]]
; VALUE: DBG_VALUE %2(s32), $noreg, [[VAR1]], !DIExpression(), debug-location [[L3]]
- ; ALL: %3:_(s32) = G_ADD %0, %2, debug-location !DILocation(line: 4, column: 1, scope: [[SP:![0-9]+]])
- ; VALUE: DBG_VALUE %3(s32), $noreg, [[VAR1]], !DIExpression(), debug-location !DILocation(line: 4
- ; ALL: %4:_(s32) = G_SUB %3, %1, debug-location !DILocation(line: 5, column: 1, scope: [[SP]])
- ; VALUE: DBG_VALUE %4(s32), $noreg, [[VAR1]], !DIExpression(), debug-location !DILocation(line: 5
+ ; ALL: %3:_(s32) = G_ADD %0, %2, debug-location ![[L4]]
+ ; VALUE: DBG_VALUE %3(s32), $noreg, [[VAR1]], !DIExpression(), debug-location ![[L4]]
+ ; ALL: %4:_(s32) = G_SUB %3, %1, debug-location ![[L5]]
+ ; VALUE: DBG_VALUE %4(s32), $noreg, [[VAR1]], !DIExpression(), debug-location ![[L5]]
...
diff --git a/llvm/test/CodeGen/Generic/MIRStripDebug/dont-strip-real-debug-info.mir b/llvm/test/CodeGen/Generic/MIRStripDebug/dont-strip-real-debug-info.mir
index f241396648f2b..1737ce5419459 100644
--- a/llvm/test/CodeGen/Generic/MIRStripDebug/dont-strip-real-debug-info.mir
+++ b/llvm/test/CodeGen/Generic/MIRStripDebug/dont-strip-real-debug-info.mir
@@ -63,6 +63,8 @@
; CHECK: !10 = !DILocation(line: 1, column: 1, scope: !4)
; CHECK: !11 = !DILocation(line: 2, column: 1, scope: !4)
; CHECK: !12 = !DILocation(line: 3, column: 1, scope: !4)
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-DAG: - '![[ZERO_LOC:[0-9]+]] = !DILocation(line: 0, scope: !4)'
...
---
@@ -81,7 +83,7 @@ body: |
; CHECK-NEXT: bb
; CHECK-NEXT: %0:_(s32) = G_IMPLICIT_DEF{{$}}
; CHECK-NEXT: %1:_(s32) = G_IMPLICIT_DEF{{$}}
- ; CHECK-NEXT: %2:_(s32) = G_CONSTANT i32 2, debug-location !DILocation(line: 0, scope: !4)
+ ; CHECK-NEXT: %2:_(s32) = G_CONSTANT i32 2, debug-location ![[ZERO_LOC]]
; CHECK-NEXT: %3:_(s32) = G_ADD %0, %2, debug-location !10
; CHECK-NEXT: DBG_VALUE %3(s32), $noreg, !7, !DIExpression(), debug-location !10
; CHECK-NEXT: %4:_(s32) = G_SUB %3, %1, debug-location !11
diff --git a/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir b/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir
index 11fed8ae64fd0..d91b7340e5092 100644
--- a/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir
+++ b/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir
@@ -124,11 +124,18 @@ body: |
%0 = COPY $edi
; CHECK-LABEL: name: test_mir_created
- ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 1, scope: !14)
- ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 2, column: 2, scope: !14)
- ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 3, column: 2, scope: !14, isImplicitCode: true)
- ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 4, scope: !14, inlinedAt: !15)
- ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 5, scope: !14, inlinedAt: !DILocation(line: 4, scope: !14))
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-NEXT: - '![[LOC1:[0-9]+]] = !DILocation(line: 1, scope: !14)'
+ ; CHECK-NEXT: - '![[LOC2:[0-9]+]] = !DILocation(line: 2, column: 2, scope: !14)'
+ ; CHECK-NEXT: - '![[LOC3:[0-9]+]] = !DILocation(line: 3, column: 2, scope: !14, isImplicitCode: true)'
+ ; CHECK-NEXT: - '![[LOC4:[0-9]+]] = !DILocation(line: 4, scope: !14, inlinedAt: !15)'
+ ; CHECK-NEXT: - '![[LOC5:[0-9]+]] = !DILocation(line: 5, scope: !14, inlinedAt: ![[INLINE:[0-9]+]])'
+ ; CHECK-NEXT: - '![[INLINE]] = !DILocation(line: 4, scope: !14)'
+ ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location ![[LOC1]]
+ ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location ![[LOC2]]
+ ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location ![[LOC3]]
+ ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location ![[LOC4]]
+ ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location ![[LOC5]]
MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 1, scope: !15)
MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 2, column: 2, scope: !15)
MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 3, column: 2, scope: !15, isImplicitCode: true)
diff --git a/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir b/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
new file mode 100644
index 0000000000000..8eb1e2a44c17d
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
@@ -0,0 +1,30 @@
+# RUN: llc -mtriple=x86_64 -run-pass=none -o - %s | FileCheck %s
+# RUN: llc -mtriple=x86_64 -run-pass=none -o - %s | llc -mtriple=x86_64 -x mir -run-pass=none -filetype=null
+
+--- |
+ define void @test() {
+ ret void
+ }
+...
+---
+name: test
+machineMetadataNodes:
+ - '!0 = !DILocation(line: 1, scope: !1)'
+ - '!1 = distinct !DISubprogram(name: "test", scope: !2, file: !2, line: 1, type: !3, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !7)'
+ - '!2 = !DIFile(filename: "test.c", directory: "/tmp")'
+ - '!3 = !DISubroutineType(types: !4)'
+ - '!4 = !{null}'
+ - '!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)'
+ - '!6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)'
+ - '!7 = !{}'
+ - '!8 = !DILocalVariable(name: "x", scope: !1, file: !2, line: 1, type: !5)'
+body: |
+ bb.0:
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-DAG: - '![[LOC:[0-9]+]] = !DILocation(line: 1, scope: ![[SP:[0-9]+]])'
+ ; CHECK-DAG: - '![[SP]] = distinct !DISubprogram(name: "test"
+ ; CHECK-DAG: - '![[VAR:[0-9]+]] = !DILocalVariable(name: "x", scope: ![[SP]]
+ ; CHECK: DBG_VALUE $rax, $noreg, ![[VAR]], !DIExpression(), debug-location ![[LOC]]
+ DBG_VALUE $rax, $noreg, !8, !DIExpression(), debug-location !0
+ RET 0
+...
diff --git a/llvm/test/CodeGen/X86/machine-sink-dbg-loc.mir b/llvm/test/CodeGen/X86/machine-sink-dbg-loc.mir
index 8b46053d3f53c..7283994b197cb 100644
--- a/llvm/test/CodeGen/X86/machine-sink-dbg-loc.mir
+++ b/llvm/test/CodeGen/X86/machine-sink-dbg-loc.mir
@@ -7,13 +7,15 @@
# CHECK: ![[DBG_VALUE_SCOPE:[0-9]+]] = distinct !DISubprogram
# CHECK: ![[MERGE_SCOPE:[0-9]+]] = !DILexicalBlock
# CHECK: ![[DBG_VALUE_LOC:[0-9]+]] = !DILocation(line: 5, scope: ![[DBG_VALUE_SCOPE]])
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '![[MERGE_LOC:[0-9]+]] = !DILocation(line: 0, scope: ![[MERGE_SCOPE]])'
# CHECK: bb.2.if.else:
# CHECK-NEXT: successors: %bb.1
# CHECK-NEXT: {{ $}}
# CHECK-NEXT: [[MOVSX64rr32_:%[0-9]+]]:gr64 = MOVSX64rr32 %[[#]]
-# CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[MOVSX64rr32_]], 4, implicit-def dead $eflags, debug-location !DILocation(line: 0, scope: ![[MERGE_SCOPE]])
-# CHECK-NEXT: [[ADD64rm:%[0-9]+]]:gr64 = ADD64rm [[SHL64ri]], %[[#]], 1, $noreg, 0, $noreg, implicit-def dead $eflags, debug-location !DILocation(line: 0, scope: ![[MERGE_SCOPE]])
+# CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[MOVSX64rr32_]], 4, implicit-def dead $eflags, debug-location ![[MERGE_LOC]]
+# CHECK-NEXT: [[ADD64rm:%[0-9]+]]:gr64 = ADD64rm [[SHL64ri]], %[[#]], 1, $noreg, 0, $noreg, implicit-def dead $eflags, debug-location ![[MERGE_LOC]]
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, !9, !DIExpression(), debug-location ![[DBG_VALUE_LOC]]
diff --git a/llvm/test/CodeGen/X86/win64-eh-unwindv2-too-many-instr.mir b/llvm/test/CodeGen/X86/win64-eh-unwindv2-too-many-instr.mir
index 44d89356ecae7..2e03b7e01a837 100644
--- a/llvm/test/CodeGen/X86/win64-eh-unwindv2-too-many-instr.mir
+++ b/llvm/test/CodeGen/X86/win64-eh-unwindv2-too-many-instr.mir
@@ -69,6 +69,10 @@ body: |
...
# CHECK-LABEL: too_many_instr
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '![[LOC3:[0-9]+]] = !DILocation(line: 3, column: 1, scope: !6)'
+# CHECK-NEXT: - '![[LOC4:[0-9]+]] = !DILocation(line: 4, column: 1, scope: !6)'
+# CHECK-NEXT: - '![[LOC5:[0-9]+]] = !DILocation(line: 5, column: 1, scope: !6)'
# CHECK-LABEL: bb.0.entry:
# bb.1 + bb.2 have enough instructions that bb.0 has its own info.
# ALLOWLESS: SEH_SplitChainedAtEndOfBlock
@@ -80,17 +84,17 @@ body: |
# bb.2 doesn't fill the current info, so bb.1 gets added as well.
# CHECK-NOT: SEH_SplitChainedAtEndOfBlock
# CHECK: SEH_UnwindV2Start
-# CHECK: RET64 debug-location !DILocation(line: 3, column: 1, scope: !6)
+# CHECK: RET64 debug-location ![[LOC3]]
# CHECK-LABEL: bb.2
# bb.3 has enough instructions by itself that bb.2 needs to split.
# ALLOWLESS-NEXT: SEH_SplitChainedAtEndOfBlock
# ALLOWMORE-NOT: SEH_SplitChainedAtEndOfBlock
# CHECK: SEH_UnwindV2Start
-# CHECK: RET64 debug-location !DILocation(line: 4, column: 1, scope: !6)
+# CHECK: RET64 debug-location ![[LOC4]]
# CHECK-LABEL: bb.3
# Never split at the end.
# CHECK-NOT: SEH_SplitChainedAtEndOfBlock
# CHECK: SEH_UnwindV2Start
-# CHECK: RET64 debug-location !DILocation(line: 5, column: 1, scope: !6)
+# CHECK: RET64 debug-location ![[LOC5]]
diff --git a/llvm/test/DebugInfo/Generic/debug-label-mi.ll b/llvm/test/DebugInfo/Generic/debug-label-mi.ll
index 85260d6728152..e1738377fe87b 100644
--- a/llvm/test/DebugInfo/Generic/debug-label-mi.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label-mi.ll
@@ -7,8 +7,8 @@
; RUN: llc -debug-only=isel %s -o /dev/null 2> %t.debug
; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
;
-; CHECKMI: DBG_LABEL "top", debug-location !9
-; CHECKMI: DBG_LABEL "done", debug-location !11
+; CHECKMI: DBG_LABEL "top", debug-location !{{[0-9]+}}
+; CHECKMI: DBG_LABEL "done", debug-location !{{[0-9]+}}
;
; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECKASM
;
diff --git a/llvm/test/DebugInfo/Generic/debug-label-opt.ll b/llvm/test/DebugInfo/Generic/debug-label-opt.ll
index e875216164305..feacb0fc7bfff 100644
--- a/llvm/test/DebugInfo/Generic/debug-label-opt.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label-opt.ll
@@ -4,8 +4,8 @@
; RUN: llc -debug-only=isel %s -o /dev/null 2> %t.debug
; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
;
-; CHECKMI: DBG_LABEL "end_sum", debug-location !17
-; CHECKMI: DBG_LABEL "end", debug-location !19
+; CHECKMI: DBG_LABEL "end_sum", debug-location !{{[0-9]+}}
+; CHECKMI: DBG_LABEL "end", debug-location !{{[0-9]+}}
source_filename = "debug-label-opt.c"
define i32 @foo(ptr nocapture readonly %a, i32 %n) local_unnamed_addr !dbg !7 {
diff --git a/llvm/test/DebugInfo/Generic/invalid.ll b/llvm/test/DebugInfo/Generic/invalid.ll
index bea22ed9ec65a..7ce353d047898 100644
--- a/llvm/test/DebugInfo/Generic/invalid.ll
+++ b/llvm/test/DebugInfo/Generic/invalid.ll
@@ -3,9 +3,9 @@
; Make sure we emit this diagnostic only once (which means we don't visit the
; same DISubprogram twice.
; CHECK: subprogram definitions must have a compile unit
-; CHECK-NEXT: !3 = distinct !DISubprogram(name: "patatino", scope: null, type: !4, spFlags: DISPFlagDefinition)
+; CHECK-NEXT: !{{[0-9]+}} = distinct !DISubprogram(name: "patatino", scope: null, type: !{{[0-9]+}}, spFlags: DISPFlagDefinition)
; CHECK-NOT: subprogram definitions must have a compile unit
-; CHECK-NOT: !3 = distinct !DISubprogram(name: "patatino", scope: null, type: !4, spFlags: DISPFlagDefinition)
+; CHECK-NOT: !{{[0-9]+}} = distinct !DISubprogram(name: "patatino", scope: null, type: !{{[0-9]+}}, spFlags: DISPFlagDefinition)
; CHECK: warning: ignoring invalid debug info
define void @tinkywinky() !dbg !3 { ret void }
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir b/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir
index 45cc23831412c..4d98bb1f3558f 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir
@@ -2,7 +2,9 @@
## Check the MIR parser understands atomGroup and atomRank.
-# CHECK: RET64 $eax, debug-location !DILocation(line: 2, scope: ![[#]], atomGroup: 1, atomRank: 2)
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '![[LOC:[0-9]+]] = !DILocation(line: 2, scope: ![[#]], atomGroup: 1, atomRank: 2)'
+# CHECK: RET64 $eax, debug-location ![[LOC]]
--- |
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/DebugInfo/MIR/InstrRef/undef-phi-through-regalloc.mir b/llvm/test/DebugInfo/MIR/InstrRef/undef-phi-through-regalloc.mir
index 68c4589798078..474e0d82621cd 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/undef-phi-through-regalloc.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/undef-phi-through-regalloc.mir
@@ -29,7 +29,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: dead renamable $al = IMPLICIT_DEF
- ; CHECK-NEXT: DBG_INSTR_REF !7, !DIExpression(), dbg-instr-ref(1, 0), debug-location !DILocation(line: 0, scope: !3)
+ ; CHECK-NEXT: DBG_INSTR_REF !7, !DIExpression(), dbg-instr-ref(1, 0), debug-location !8
; CHECK-NEXT: RET 0
bb.0:
successors: %bb.1
diff --git a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc1.mir b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc1.mir
index 1504789cd5854..c740d551913ba 100644
--- a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc1.mir
+++ b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc1.mir
@@ -216,7 +216,10 @@ body: |
# CHECK-DAG: [[INLINER:![0-9]+]] = distinct !DISubprogram(name: "multiple_inl_one_loc"
# CHECK-DAG: [[INLINEE:![0-9]+]] = distinct !DISubprogram(name: "inl1"
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '[[MERGED_LOC:![0-9]+]] = !DILocation(line: 6, column: 5, scope: [[INLINEE]], inlinedAt: [[MERGED_INLINE_AT:![0-9]+]])'
+# CHECK-NEXT: - '[[MERGED_INLINE_AT]] = !DILocation(line: 0, scope: [[INLINER]])'
# CHECK-NOT: CALL64pcrel32
-# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location !DILocation(line: 6, column: 5, scope: [[INLINEE]], inlinedAt: !DILocation(line: 0, scope: [[INLINER]]))
+# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location [[MERGED_LOC]]
# CHECK-NOT: CALL64pcrel32
diff --git a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc2.mir b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc2.mir
index 0564b49fcafdd..d40228bb1d031 100644
--- a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc2.mir
+++ b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc2.mir
@@ -333,7 +333,10 @@ body: |
# CHECK-DAG: [[INLINER:![0-9]+]] = distinct !DISubprogram(name: "multiple_inl_multiple_loc"
# CHECK-DAG: [[INLINEE:![0-9]+]] = distinct !DISubprogram(name: "inl2"
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '[[MERGED_LOC:![0-9]+]] = !DILocation(line: 0, scope: [[INLINEE]], inlinedAt: [[MERGED_INLINE_AT:![0-9]+]])'
+# CHECK-NEXT: - '[[MERGED_INLINE_AT]] = !DILocation(line: 0, scope: [[INLINER]])'
# CHECK-NOT: CALL64pcrel32
-# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location !DILocation(line: 0, scope: [[INLINEE]], inlinedAt: !DILocation(line: 0, scope: [[INLINER]]))
+# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location [[MERGED_LOC]]
# CHECK-NOT: CALL64pcrel32
diff --git a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc3.mir b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc3.mir
index 2f21c7912c723..5cbb653dc7424 100644
--- a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc3.mir
+++ b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc3.mir
@@ -181,7 +181,9 @@ body: |
# multiple_inl_funcs(), without any inline information.
# CHECK: [[INLINER:![0-9]+]] = distinct !DISubprogram(name: "multiple_inl_funcs"
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '[[MERGED_LOC:![0-9]+]] = !DILocation(line: 0, scope: [[INLINER]])'
# CHECK-NOT: CALL64pcrel32
-# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location !DILocation(line: 0, scope: [[INLINER]])
+# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location [[MERGED_LOC]]
# CHECK-NOT: CALL64pcrel32
diff --git a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc4.mir b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc4.mir
index 24b17a6289203..691bd61783eb6 100644
--- a/llvm/test/DebugInfo/MIR/X86/merge-inline-loc4.mir
+++ b/llvm/test/DebugInfo/MIR/X86/merge-inline-loc4.mir
@@ -160,7 +160,9 @@ body: |
# merge_inl_and_non_inl(), without any inline information.
# CHECK: [[INLINER:![0-9]+]] = distinct !DISubprogram(name: "merge_inl_and_non_inl"
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '[[MERGED_LOC:![0-9]+]] = !DILocation(line: 0, scope: [[INLINER]])'
# CHECK-NOT: CALL64pcrel32
-# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location !DILocation(line: 0, scope: [[INLINER]])
+# CHECK: CALL64pcrel32 target-flags(x86-plt) @abort, {{.*}} debug-location [[MERGED_LOC]]
# CHECK-NOT: CALL64pcrel32
diff --git a/llvm/test/DebugInfo/X86/branch-folder-dbg-after-end.mir b/llvm/test/DebugInfo/X86/branch-folder-dbg-after-end.mir
index 743851c34610a..7a2c02c49a351 100644
--- a/llvm/test/DebugInfo/X86/branch-folder-dbg-after-end.mir
+++ b/llvm/test/DebugInfo/X86/branch-folder-dbg-after-end.mir
@@ -7,10 +7,12 @@
## Note the MIR doesn't match the IR as it's modified from:
## /home/och/dev/llvm-project/llvm/test/DebugInfo/X86/branch-folder-dbg.mir
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '![[MERGED_LOC:[0-9]+]] = !DILocation(line: 0, scope: ![[#]])'
# CHECK: bb.0
# CHECK: CALL64pcrel32 @f, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
## --- Start splice from bb.2.if.else (and debug instructions from bb.1.if.then) ---
-# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-location !DILocation(line: 0, scope: ![[#]])
+# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-location ![[MERGED_LOC]]
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location
## --- End splice ------------------------------------------------------------------
diff --git a/llvm/test/DebugInfo/X86/branch-folder-dbg.mir b/llvm/test/DebugInfo/X86/branch-folder-dbg.mir
index 11b3721809129..3259ec0fff1c7 100644
--- a/llvm/test/DebugInfo/X86/branch-folder-dbg.mir
+++ b/llvm/test/DebugInfo/X86/branch-folder-dbg.mir
@@ -12,6 +12,8 @@
##
## Check DBG_LABELs are hoisted and not modified (and don't cause a crash).
+# CHECK: machineMetadataNodes:
+# CHECK-NEXT: - '![[MERGED_LOC:[0-9]+]] = !DILocation(line: 0, scope: ![[#]])'
# CHECK: bb.0
# CHECK: CALL64pcrel32 @f, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
## --- Start splice from bb.2.if.else (and debug instructions from bb.1.if.then) ---
@@ -19,7 +21,7 @@
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location ![[#]]
# CHECK-NEXT: DBG_LABEL 1
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location ![[#]]
-# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-instr-number 2, debug-location !DILocation(line: 0, scope: ![[#]])
+# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-instr-number 2, debug-location ![[MERGED_LOC]]
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location ![[#]]
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location ![[#]]
## --- End splice ------------------------------------------------------------------
diff --git a/llvm/test/DebugInfo/X86/machinecse-wrongdebug-hoist.ll b/llvm/test/DebugInfo/X86/machinecse-wrongdebug-hoist.ll
index 4660315040b35..7802b2b6f1311 100644
--- a/llvm/test/DebugInfo/X86/machinecse-wrongdebug-hoist.ll
+++ b/llvm/test/DebugInfo/X86/machinecse-wrongdebug-hoist.ll
@@ -1,8 +1,8 @@
; RUN: llc %s -o - -print-after=machine-cse -mtriple=x86_64-- 2>&1 | FileCheck %s --match-full-lines
-; CHECK: %5:gr32 = SUB32ri %0:gr32(tied-def 0), 1, implicit-def $eflags, debug-location !24; a.c:3:13
+; CHECK: %5:gr32 = SUB32ri %0:gr32(tied-def 0), 1, implicit-def $eflags, debug-location !{{[0-9]+}}; a.c:3:13
; CHECK-NEXT: %10:gr32 = MOVSX32rr8 %4:gr8
-; CHECK-NEXT: JCC_1 %bb.2, 15, implicit $eflags, debug-location !25; a.c:3:18
+; CHECK-NEXT: JCC_1 %bb.2, 15, implicit $eflags, debug-location !{{[0-9]+}}; a.c:3:18
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.15.0"
diff --git a/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll b/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
index d382e093932a4..341584508ea79 100644
--- a/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
+++ b/llvm/test/Other/legacy-callgraph-scc-pass-printer.ll
@@ -11,8 +11,8 @@
; PERSISTENT-LABEL: *** IR Dump After DummyCGSCCPass (DummyCGSCCPass) ***
; PERSISTENT: define void @bar() {
-; PERSISTENT: ret void, !annotation !1
-; PERSISTENT: !1 = !{!"used"}
+; PERSISTENT: ret void, !annotation ![[USED:[0-9]+]]
+; PERSISTENT: ![[USED]] = !{!"used"}
define void @bar() {
ret void, !annotation !1
diff --git a/llvm/test/Other/print-changed-persistent-metadata-ids.ll b/llvm/test/Other/print-changed-persistent-metadata-ids.ll
index bf755b01095c4..01cb0eb3fb548 100644
--- a/llvm/test/Other/print-changed-persistent-metadata-ids.ll
+++ b/llvm/test/Other/print-changed-persistent-metadata-ids.ll
@@ -63,11 +63,11 @@ attributes #1 = { noinline }
; SPARSE: define i32 @second(i32 %arg) #1 {
; SPARSE: %keep = call i32 @opaque(i32 %arg)
-; SPARSE-SAME: !annotation !1, !other !3
+; SPARSE-SAME: !annotation ![[SPARSE_ANNOTATION:[1-9][0-9]*]], !other ![[SPARSE_OTHER:[0-9]+]]
; SPARSE-NOT: !0 =
-; SPARSE: !1 = !{!2}
-; SPARSE: !2 = !{!"second metadata"}
-; SPARSE: !3 = !{!"other metadata"}
+; SPARSE: ![[SPARSE_ANNOTATION]] = !{![[SPARSE_NESTED:[0-9]+]]}
+; SPARSE-DAG: ![[SPARSE_NESTED]] = !{!"second metadata"}
+; SPARSE-DAG: ![[SPARSE_OTHER]] = !{!"other metadata"}
; COMPACT: define i32 @second(i32 %arg) #1 {
; COMPACT: %keep = call i32 @opaque(i32 %arg)
diff --git a/llvm/test/Other/print-persistent-metadata-ids.ll b/llvm/test/Other/print-persistent-metadata-ids.ll
index 0fa89a6744fd1..79ae153353d02 100644
--- a/llvm/test/Other/print-persistent-metadata-ids.ll
+++ b/llvm/test/Other/print-persistent-metadata-ids.ll
@@ -65,11 +65,11 @@ attributes #1 = { nounwind }
; COMPACT: ret void, !annotation !5
; COMPACT: !named = !{!2}
-; PERSISTENT-MODULE: @named = global ptr @0, comdat($group), !annotation !5
-; PERSISTENT-MODULE: ret void, !annotation !1
-; PERSISTENT-MODULE: call void @callee(ptr @1) #1, !annotation !3
-; PERSISTENT-MODULE: ret void, !annotation !3
-; PERSISTENT-MODULE: !named = !{!0}
+; PERSISTENT-MODULE: @named = global ptr @0, comdat($group), !annotation ![[GLOBAL:[0-9]+]]
+; PERSISTENT-MODULE: ret void, !annotation ![[FIRST:[0-9]+]]
+; PERSISTENT-MODULE: call void @callee(ptr @1) #1, !annotation ![[SECOND:[0-9]+]]
+; PERSISTENT-MODULE: ret void, !annotation ![[SECOND]]
+; PERSISTENT-MODULE: !named = !{![[NAMED:[0-9]+]]}
; PERSISTENT-FUNCTION: define void @second() {
; PERSISTENT-FUNCTION: call void @callee(ptr @1) #1, !annotation ![[SECOND:[0-9]+]]
diff --git a/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll b/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll
index 42130c507fd09..91d5bce560e9f 100644
--- a/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll
+++ b/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll
@@ -1,7 +1,7 @@
; RUN: opt %s -safepoint-ir-verifier-print-only -verify-safepoint-ir -S 2>&1 | FileCheck %s
; CHECK: Illegal use of unrelocated value found!
-; CHECK-NEXT: Def: %base_phi4 = phi ptr addrspace(1) [ %addr98.relocated, %not_zero146 ], [ %base_phi2, %bci_37-aload ], !is_base_value !0
+; CHECK-NEXT: Def: %base_phi4 = phi ptr addrspace(1) [ %addr98.relocated, %not_zero146 ], [ %base_phi2, %bci_37-aload ], !is_base_value !{{[0-9]+}}
; CHECK-NEXT: Use: %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i32 ()) undef, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %base_phi1, ptr addrspace(1) %base_phi4, ptr addrspace(1) %relocated4, ptr addrspace(1) %relocated7) ]
diff --git a/llvm/test/Transforms/IRCE/only-lower-check.ll b/llvm/test/Transforms/IRCE/only-lower-check.ll
index f934ac02373a7..c0e7f0641aaa1 100644
--- a/llvm/test/Transforms/IRCE/only-lower-check.ll
+++ b/llvm/test/Transforms/IRCE/only-lower-check.ll
@@ -4,7 +4,7 @@
; CHECK: irce: loop has 1 inductive range checks:
; CHECK-NEXT: InductiveRangeCheck:
; CHECK-NEXT: Begin: (-1 + %n) Step: -1 End: 2147483647
-; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 Operand: 0
+; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !{{[0-9]+}} Operand: 0
; CHECK-NEXT: irce: in function only_lower_check: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
define void @only_lower_check(ptr %arr, ptr %a_len_ptr, i32 %n) {
diff --git a/llvm/test/Transforms/IRCE/only-upper-check.ll b/llvm/test/Transforms/IRCE/only-upper-check.ll
index d6ed8c80f2664..e9795c69faf6a 100644
--- a/llvm/test/Transforms/IRCE/only-upper-check.ll
+++ b/llvm/test/Transforms/IRCE/only-upper-check.ll
@@ -4,7 +4,7 @@
; CHECK: irce: loop has 1 inductive range checks:
; CHECK-NEXT:InductiveRangeCheck:
; CHECK-NEXT: Begin: %offset Step: 1 End: %len
-; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 Operand: 0
+; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !{{[0-9]+}} Operand: 0
; CHECK-NEXT: irce: in function incrementing: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
define void @incrementing(ptr %arr, ptr %a_len_ptr, i32 %n, i32 %offset) {
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing-metadata.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing-metadata.ll
index 26b0bc47fd257..ccc4e44dbcf9c 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing-metadata.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing-metadata.ll
@@ -23,13 +23,13 @@ define void @test_widen_metadata(ptr noalias %A, ptr noalias %B, i32 %n) {
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%gep.A> = getelementptr inbounds ir<%A>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds i32, ir<%gep.A>, ir<1>
-; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !0)
-; CHECK-NEXT: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float (!fpmath !4)
-; CHECK-NEXT: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00> (!fpmath !4)
+; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !{{[0-9]+}})
+; CHECK-NEXT: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float (!fpmath !{{[0-9]+}})
+; CHECK-NEXT: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00> (!fpmath !{{[0-9]+}})
; CHECK-NEXT: WIDEN-CAST ir<%conv.back> = fptosi ir<%mul> to i32
; CHECK-NEXT: CLONE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds i32, ir<%gep.B>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%conv.back> (!tbaa !0)
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%conv.back> (!tbaa !{{[0-9]+}})
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
@@ -51,12 +51,12 @@ define void @test_widen_metadata(ptr noalias %A, ptr noalias %B, i32 %n) {
; CHECK-NEXT: ir-bb<loop>:
; CHECK-NEXT: IR %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
; CHECK-NEXT: IR %gep.A = getelementptr inbounds i32, ptr %A, i32 %i
-; CHECK-NEXT: IR %lv = load i32, ptr %gep.A, align 4, !tbaa !0, !range !3
-; CHECK-NEXT: IR %conv = sitofp i32 %lv to float, !fpmath !4
-; CHECK-NEXT: IR %mul = fmul float %conv, 2.000000e+00, !fpmath !4
+; CHECK-NEXT: IR %lv = load i32, ptr %gep.A, align 4, !tbaa !{{[0-9]+}}, !range !{{[0-9]+}}
+; CHECK-NEXT: IR %conv = sitofp i32 %lv to float, !fpmath !{{[0-9]+}}
+; CHECK-NEXT: IR %mul = fmul float %conv, 2.000000e+00, !fpmath !{{[0-9]+}}
; CHECK-NEXT: IR %conv.back = fptosi float %mul to i32
; CHECK-NEXT: IR %gep.B = getelementptr inbounds i32, ptr %B, i32 %i
-; CHECK-NEXT: IR store i32 %conv.back, ptr %gep.B, align 4, !tbaa !0
+; CHECK-NEXT: IR store i32 %conv.back, ptr %gep.B, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: IR %i.next = add i32 %i, 1
; CHECK-NEXT: IR %cond = icmp eq i32 %i.next, %n
; CHECK-NEXT: No successors
@@ -104,11 +104,11 @@ define void @test_intrinsic_with_metadata(ptr noalias %A, ptr noalias %B, i32 %n
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%gep.A> = getelementptr inbounds ir<%A>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds float, ir<%gep.A>, ir<1>
-; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !0)
-; CHECK-NEXT: WIDEN-INTRINSIC ir<%sqrt> = call llvm.sqrt(ir<%lv>) (!fpmath !3)
+; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !{{[0-9]+}})
+; CHECK-NEXT: WIDEN-INTRINSIC ir<%sqrt> = call llvm.sqrt(ir<%lv>) (!fpmath !{{[0-9]+}})
; CHECK-NEXT: CLONE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds float, ir<%gep.B>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%sqrt> (!tbaa !0)
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%sqrt> (!tbaa !{{[0-9]+}})
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
@@ -130,10 +130,10 @@ define void @test_intrinsic_with_metadata(ptr noalias %A, ptr noalias %B, i32 %n
; CHECK-NEXT: ir-bb<loop>:
; CHECK-NEXT: IR %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
; CHECK-NEXT: IR %gep.A = getelementptr inbounds float, ptr %A, i32 %i
-; CHECK-NEXT: IR %lv = load float, ptr %gep.A, align 4, !tbaa !0
-; CHECK-NEXT: IR %sqrt = call float @llvm.sqrt.f32(float %lv), !fpmath !3
+; CHECK-NEXT: IR %lv = load float, ptr %gep.A, align 4, !tbaa !{{[0-9]+}}
+; CHECK-NEXT: IR %sqrt = call float @llvm.sqrt.f32(float %lv), !fpmath !{{[0-9]+}}
; CHECK-NEXT: IR %gep.B = getelementptr inbounds float, ptr %B, i32 %i
-; CHECK-NEXT: IR store float %sqrt, ptr %gep.B, align 4, !tbaa !0
+; CHECK-NEXT: IR store float %sqrt, ptr %gep.B, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: IR %i.next = add i32 %i, 1
; CHECK-NEXT: IR %cond = icmp eq i32 %i.next, %n
; CHECK-NEXT: No successors
@@ -178,13 +178,13 @@ define void @test_widen_with_multiple_metadata(ptr noalias %A, ptr noalias %B, i
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%gep.A> = getelementptr inbounds ir<%A>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds i32, ir<%gep.A>, ir<1>
-; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !0)
+; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VP5]]> (!tbaa !{{[0-9]+}})
; CHECK-NEXT: WIDEN-CAST ir<%conv> = sitofp ir<%lv> to float
; CHECK-NEXT: WIDEN ir<%mul> = fmul ir<%conv>, ir<2.000000e+00>
; CHECK-NEXT: WIDEN-CAST ir<%conv.back> = fptosi ir<%mul> to i32
; CHECK-NEXT: CLONE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[VP4]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds i32, ir<%gep.B>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%conv.back> (!tbaa !0)
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%conv.back> (!tbaa !{{[0-9]+}})
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
@@ -206,12 +206,12 @@ define void @test_widen_with_multiple_metadata(ptr noalias %A, ptr noalias %B, i
; CHECK-NEXT: ir-bb<loop>:
; CHECK-NEXT: IR %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
; CHECK-NEXT: IR %gep.A = getelementptr inbounds i32, ptr %A, i32 %i
-; CHECK-NEXT: IR %lv = load i32, ptr %gep.A, align 4, !tbaa !0, !range !3
+; CHECK-NEXT: IR %lv = load i32, ptr %gep.A, align 4, !tbaa !{{[0-9]+}}, !range !{{[0-9]+}}
; CHECK-NEXT: IR %conv = sitofp i32 %lv to float
; CHECK-NEXT: IR %mul = fmul float %conv, 2.000000e+00
; CHECK-NEXT: IR %conv.back = fptosi float %mul to i32
; CHECK-NEXT: IR %gep.B = getelementptr inbounds i32, ptr %B, i32 %i
-; CHECK-NEXT: IR store i32 %conv.back, ptr %gep.B, align 4, !tbaa !0
+; CHECK-NEXT: IR store i32 %conv.back, ptr %gep.B, align 4, !tbaa !{{[0-9]+}}
; CHECK-NEXT: IR %i.next = add i32 %i, 1
; CHECK-NEXT: IR %cond = icmp eq i32 %i.next, %n
; CHECK-NEXT: No successors
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing.ll
index 405e9004919a2..bdc7b1f5d29bf 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing.ll
@@ -435,10 +435,10 @@ define void @recipe_debug_loc_location(ptr nocapture %src) !dbg !5 {
; CHECK-EMPTY:
; CHECK-NEXT: ir-bb<loop>:
; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %if.end ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %isd = getelementptr inbounds i32, ptr %src, i64 %iv, !dbg !7
-; CHECK-NEXT: IR %lsd = load i32, ptr %isd, align 4, !dbg !8
-; CHECK-NEXT: IR %psd = add nuw nsw i32 %lsd, 23, !dbg !9
-; CHECK-NEXT: IR %cmp1 = icmp slt i32 %lsd, 100, !dbg !10
+; CHECK-NEXT: IR %isd = getelementptr inbounds i32, ptr %src, i64 %iv, !dbg !{{[0-9]+}}
+; CHECK-NEXT: IR %lsd = load i32, ptr %isd, align 4, !dbg !{{[0-9]+}}
+; CHECK-NEXT: IR %psd = add nuw nsw i32 %lsd, 23, !dbg !{{[0-9]+}}
+; CHECK-NEXT: IR %cmp1 = icmp slt i32 %lsd, 100, !dbg !{{[0-9]+}}
; CHECK-NEXT: No successors
; CHECK-NEXT: }
;
diff --git a/llvm/test/Transforms/MemProfContextDisambiguation/inlined2.ll b/llvm/test/Transforms/MemProfContextDisambiguation/inlined2.ll
index 2cc655e927d12..c906c5661a6e9 100644
--- a/llvm/test/Transforms/MemProfContextDisambiguation/inlined2.ll
+++ b/llvm/test/Transforms/MemProfContextDisambiguation/inlined2.ll
@@ -111,7 +111,7 @@ attributes #7 = { builtin }
; DUMP: CCG before cloning:
; DUMP: Callsite Context Graph:
; DUMP: Node [[BAR:0x[a-z0-9]+]]
-; DUMP: %call = call noalias noundef nonnull dereferenceable(10) ptr @_Znam(i64 noundef 10) #7, !heapallocsite !7 (clone 0)
+; DUMP: %call = call noalias noundef nonnull dereferenceable(10) ptr @_Znam(i64 noundef 10) #7, !heapallocsite !{{[0-9]+}} (clone 0)
; DUMP: AllocTypes: NotColdCold
; DUMP: ContextIds: 1 2
; DUMP: CalleeEdges:
diff --git a/llvm/test/Transforms/SandboxVectorizer/Passes/Other/print_region_pass.ll b/llvm/test/Transforms/SandboxVectorizer/Passes/Other/print_region_pass.ll
index 0b808d6025e46..1a9bf1c3a484c 100644
--- a/llvm/test/Transforms/SandboxVectorizer/Passes/Other/print_region_pass.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/Passes/Other/print_region_pass.ll
@@ -3,15 +3,15 @@
define void @foo(i8 %v) {
; CHECK: -- Region --
-; CHECK-NEXT: %add0 = add i8 %v, 0, !sandboxvec !0 {{.*}}
+; CHECK-NEXT: %add0 = add i8 %v, 0, !sandboxvec !{{[0-9]+}} {{.*}}
; CHECK: -- Region --
-; CHECK-NEXT: %add1 = add i8 %v, 1, !sandboxvec !1 {{.*}}
-; CHECK-NEXT: %add2 = add i8 %v, 2, !sandboxvec !1 {{.*}}
-; CHECK-NEXT: %add3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2 {{.*}}
-; CHECK-NEXT: %add4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !3 {{.*}}
+; CHECK-NEXT: %add1 = add i8 %v, 1, !sandboxvec !{{[0-9]+}} {{.*}}
+; CHECK-NEXT: %add2 = add i8 %v, 2, !sandboxvec !{{[0-9]+}} {{.*}}
+; CHECK-NEXT: %add3 = add i8 %v, 3, !sandboxvec !{{[0-9]+}}, !sandboxaux !{{[0-9]+}} {{.*}}
+; CHECK-NEXT: %add4 = add i8 %v, 4, !sandboxvec !{{[0-9]+}}, !sandboxaux !{{[0-9]+}} {{.*}}
; CHECK: Aux:
-; CHECK-NEXT: %add3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2 {{.*}}
-; CHECK-NEXT: %add4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !3 {{.*}}
+; CHECK-NEXT: %add3 = add i8 %v, 3, !sandboxvec !{{[0-9]+}}, !sandboxaux !{{[0-9]+}} {{.*}}
+; CHECK-NEXT: %add4 = add i8 %v, 4, !sandboxvec !{{[0-9]+}}, !sandboxaux !{{[0-9]+}} {{.*}}
%add0 = add i8 %v, 0, !sandboxvec !0
%add1 = add i8 %v, 1, !sandboxvec !1
%add2 = add i8 %v, 2, !sandboxvec !1
diff --git a/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll b/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
index 14e5888398996..965ee62fe8643 100644
--- a/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
+++ b/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
@@ -1,7 +1,7 @@
; RUN: opt %s -passes=verify 2>&1 | FileCheck %s
; CHECK: invalid type
-; CHECK: !20 = !DILocalVariable(name: "f", scope: !21, file: !13, line: 970, type: !14)
-; CHECK: !14 = !DISubroutineType(types: !15)
+; CHECK: !{{[0-9]+}} = !DILocalVariable(name: "f", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 970, type: !{{[0-9]+}})
+; CHECK: !{{[0-9]+}} = !DISubroutineType(types: !{{[0-9]+}})
%timespec.0.1.2.3.0.1.2 = type { i64, i64 }
diff --git a/llvm/test/Verifier/absolute_symbol.ll b/llvm/test/Verifier/absolute_symbol.ll
index df3da8e547cb3..3b78e1c99cf02 100644
--- a/llvm/test/Verifier/absolute_symbol.ll
+++ b/llvm/test/Verifier/absolute_symbol.ll
@@ -37,21 +37,21 @@ define void @absolute_func_empty_arguments() !absolute_symbol !0 {
@absolute_wrong_order = external global i32, !absolute_symbol !15
; CHECK: It should have at least one range!
-; CHECK-NEXT: !0 = !{}
+; CHECK-NEXT: !{{[0-9]+}} = !{}
; CHECK: It should have at least one range!
-; CHECK-NEXT: !0 = !{}
+; CHECK-NEXT: !{{[0-9]+}} = !{}
!0 = !{}
; CHECK-NEXT: Unfinished range!
-; CHECK-NEXT: !1 = !{i64 128}
+; CHECK-NEXT: !{{[0-9]+}} = !{i64 128}
!1 = !{i64 128}
; CHECK-NEXT: Unfinished range!
-; CHECK-NEXT: !2 = !{i64 128, i64 256, i64 512}
+; CHECK-NEXT: !{{[0-9]+}} = !{i64 128, i64 256, i64 512}
!2 = !{i64 128, i64 256, i64 512}
; CHECK-NEXT: Unfinished range!
-; CHECK-NEXT: !3 = !{i32 256}
+; CHECK-NEXT: !{{[0-9]+}} = !{i32 256}
!3 = !{i32 256}
; CHECK-NEXT: Range types must match instruction type!
@@ -67,7 +67,7 @@ define void @absolute_func_empty_arguments() !absolute_symbol !0 {
!6 = !{i64 256, i32 512}
; CHECK-NEXT: Range must not be empty!
-; CHECK-NEXT: !7 = !{i64 0, i64 0}
+; CHECK-NEXT: !{{[0-9]+}} = !{i64 0, i64 0}
!7 = !{i64 0, i64 0}
; CHECK-NEXT: The upper and lower limits cannot be the same value
@@ -93,4 +93,3 @@ define void @absolute_func_empty_arguments() !absolute_symbol !0 {
; CHECK-NEXT: The upper limit must be an integer!
!14 = !{i64 456, ptr inttoptr (i64 512 to ptr)}
!15 = !{i64 1024, i64 128}
-
diff --git a/llvm/test/Verifier/associated-metadata.ll b/llvm/test/Verifier/associated-metadata.ll
index 00f30e6b82878..112c2c4fecc71 100644
--- a/llvm/test/Verifier/associated-metadata.ll
+++ b/llvm/test/Verifier/associated-metadata.ll
@@ -2,37 +2,37 @@
; CHECK: associated value must be pointer typed
; CHECK-NEXT: ptr addrspace(1) @associated.int
-; CHECK-NEXT: !0 = !{i32 1}
+; CHECK-NEXT: !{{[0-9]+}} = !{i32 1}
@associated.int = external addrspace(1) constant [8 x i8], !associated !0
; CHECK: associated value must be pointer typed
; CHECK-NEXT: ptr addrspace(1) @associated.float
-; CHECK-NEXT: !1 = !{float 1.000000e+00}
+; CHECK-NEXT: !{{[0-9]+}} = !{float 1.000000e+00}
@associated.float = external addrspace(1) constant [8 x i8], !associated !1
; CHECK: associated metadata must have one operand
; CHECK-NEXT: ptr addrspace(1) @associated.too.many.ops
-; CHECK-NEXT: !2 = !{ptr @gv.decl0, ptr @gv.decl1}
+; CHECK-NEXT: !{{[0-9]+}} = !{ptr @gv.decl0, ptr @gv.decl1}
@associated.too.many.ops = external addrspace(1) constant [8 x i8], !associated !2
; CHECK: associated metadata must have one operand
; CHECK-NEXT: ptr addrspace(1) @associated.empty
-; CHECK-NEXT: !3 = !{}
+; CHECK-NEXT: !{{[0-9]+}} = !{}
@associated.empty = external addrspace(1) constant [8 x i8], !associated !3
; CHECK: associated metadata must have a global value
; CHECK-NEXT: ptr addrspace(1) @associated.null.metadata
-; CHECK-NEXT: !4 = !{null}
+; CHECK-NEXT: !{{[0-9]+}} = !{null}
@associated.null.metadata = external addrspace(1) constant [8 x i8], !associated !4
; CHECK: global values should not associate to themselves
; CHECK-NEXT: ptr @associated.self
-; CHECK-NEXT: !5 = !{ptr @associated.self}
+; CHECK-NEXT: !{{[0-9]+}} = !{ptr @associated.self}
@associated.self = external constant [8 x i8], !associated !5
; CHECK: associated metadata must be ValueAsMetadata
; CHECK-NEXT: ptr @associated.string
-; CHECK-NEXT: !6 = !{!"string"}
+; CHECK-NEXT: !{{[0-9]+}} = !{!"string"}
@associated.string = external constant [8 x i8], !associated !6
@gv.decl0 = external constant [8 x i8]
diff --git a/llvm/test/Verifier/commandline-meta1.ll b/llvm/test/Verifier/commandline-meta1.ll
index 5c39bbdde6da4..7bcceec4e478c 100644
--- a/llvm/test/Verifier/commandline-meta1.ll
+++ b/llvm/test/Verifier/commandline-meta1.ll
@@ -7,4 +7,4 @@
!0 = !{!"string1", !"string2"}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: incorrect number of operands in llvm.commandline metadata
-; CHECK-NEXT: !0
+; CHECK-NEXT: !{{[0-9]+}}
diff --git a/llvm/test/Verifier/dbg-orphaned-compileunit.ll b/llvm/test/Verifier/dbg-orphaned-compileunit.ll
index 9ab72824624df..4e442caa1e6e8 100644
--- a/llvm/test/Verifier/dbg-orphaned-compileunit.ll
+++ b/llvm/test/Verifier/dbg-orphaned-compileunit.ll
@@ -1,7 +1,7 @@
; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: assembly parsed, but does not verify
; CHECK-NEXT: DICompileUnit not listed in llvm.dbg.cu
-; CHECK-NEXT: !0 = distinct !DICompileUnit(language: DW_LANG_Fortran77, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+; CHECK-NEXT: !{{[0-9]+}} = distinct !DICompileUnit(language: DW_LANG_Fortran77, file: !{{[0-9]+}}, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
!named = !{!1}
!llvm.module.flags = !{!0}
diff --git a/llvm/test/Verifier/di-subroutine-localvar.ll b/llvm/test/Verifier/di-subroutine-localvar.ll
index 35ba6ef42d703..33a984a238257 100644
--- a/llvm/test/Verifier/di-subroutine-localvar.ll
+++ b/llvm/test/Verifier/di-subroutine-localvar.ll
@@ -1,7 +1,7 @@
; RUN: opt %s -passes=verify 2>&1 | FileCheck %s
; CHECK: invalid type
-; CHECK: !20 = !DILocalVariable(name: "f", scope: !21, file: !13, line: 970, type: !14)
-; CHECK: !14 = !DISubroutineType(types: !15)
+; CHECK: !{{[0-9]+}} = !DILocalVariable(name: "f", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 970, type: !{{[0-9]+}})
+; CHECK: !{{[0-9]+}} = !DISubroutineType(types: !{{[0-9]+}})
%timespec.0.1.2.3.0.1.2 = type { i64, i64 }
diff --git a/llvm/test/Verifier/function-metadata-bad.ll b/llvm/test/Verifier/function-metadata-bad.ll
index b3bd3c27c6d49..7743f31c17341 100644
--- a/llvm/test/Verifier/function-metadata-bad.ll
+++ b/llvm/test/Verifier/function-metadata-bad.ll
@@ -7,7 +7,7 @@ define i32 @bad1() !prof !0 {
!0 = !{i32 123, i32 3}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: expected string with name of the !prof annotation
-; CHECK-NEXT: !0 = !{i32 123, i32 3}
+; CHECK-NEXT: !{{[0-9]+}} = !{i32 123, i32 3}
define i32 @bad2() !prof !1 {
ret i32 0
@@ -15,7 +15,7 @@ define i32 @bad2() !prof !1 {
!1 = !{!"function_entry_count"}
; CHECK-NEXT: !prof annotations should have no less than 2 operands
-; CHECK-NEXT: !1 = !{!"function_entry_count"}
+; CHECK-NEXT: !{{[0-9]+}} = !{!"function_entry_count"}
define i32 @bad3() !prof !2 {
@@ -24,7 +24,7 @@ define i32 @bad3() !prof !2 {
!2 = !{!"some_other_count", i64 200}
; CHECK-NEXT: first operand should be 'function_entry_count'
-; CHECK-NEXT: !2 = !{!"some_other_count", i64 200}
+; CHECK-NEXT: !{{[0-9]+}} = !{!"some_other_count", i64 200}
define i32 @bad4() !prof !3 {
ret i32 0
@@ -32,4 +32,4 @@ define i32 @bad4() !prof !3 {
!3 = !{!"function_entry_count", !"string"}
; CHECK-NEXT: expected integer argument to function_entry_count
-; CHECK-NEXT: !3 = !{!"function_entry_count", !"string"}
+; CHECK-NEXT: !{{[0-9]+}} = !{!"function_entry_count", !"string"}
diff --git a/llvm/test/Verifier/ident-meta1.ll b/llvm/test/Verifier/ident-meta1.ll
index 3202fbd3e8f79..a82e228533519 100644
--- a/llvm/test/Verifier/ident-meta1.ll
+++ b/llvm/test/Verifier/ident-meta1.ll
@@ -8,5 +8,4 @@
!1 = !{!"string1", !"string2"}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: incorrect number of operands in llvm.ident metadata
-; CHECK-NEXT: !1
-
+; CHECK-NEXT: !{{[0-9]+}}
diff --git a/llvm/test/Verifier/llvm.loop.estimated_trip_count.ll b/llvm/test/Verifier/llvm.loop.estimated_trip_count.ll
index e0ec110efae86..aac3aa0c25ded 100644
--- a/llvm/test/Verifier/llvm.loop.estimated_trip_count.ll
+++ b/llvm/test/Verifier/llvm.loop.estimated_trip_count.ll
@@ -16,13 +16,13 @@ exit:
; GOOD-NOT: {{.}}
; BAD-VALUE: Expected second operand to be an integer constant of type i32 or smaller
-; BAD-VALUE-NEXT: !1 = !{!"llvm.loop.estimated_trip_count",
+; BAD-VALUE-NEXT: !{{[0-9]+}} = !{!"llvm.loop.estimated_trip_count",
; TOO-FEW: Expected two operands
-; TOO-FEW-NEXT: !1 = !{!"llvm.loop.estimated_trip_count"}
+; TOO-FEW-NEXT: !{{[0-9]+}} = !{!"llvm.loop.estimated_trip_count"}
; TOO-MANY: Expected two operands
-; TOO-MANY-NEXT: !1 = !{!"llvm.loop.estimated_trip_count", i32 5, i32 5}
+; TOO-MANY-NEXT: !{{[0-9]+}} = !{!"llvm.loop.estimated_trip_count", i32 5, i32 5}
; No value.
; RUN: cp %s %t
diff --git a/llvm/test/Verifier/mdcompositetype-templateparams-tuple.ll b/llvm/test/Verifier/mdcompositetype-templateparams-tuple.ll
index 8de6fac50eae5..3c88ed292b980 100644
--- a/llvm/test/Verifier/mdcompositetype-templateparams-tuple.ll
+++ b/llvm/test/Verifier/mdcompositetype-templateparams-tuple.ll
@@ -1,9 +1,9 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: invalid template params
-; CHECK-NEXT: !2 = !DICompositeType(
-; CHECK-SAME: templateParams: !1
-; CHECK-NEXT: !1 = !DITemplateTypeParameter(
+; CHECK-NEXT: !{{[0-9]+}} = !DICompositeType(
+; CHECK-SAME: templateParams: !{{[0-9]+}}
+; CHECK-NEXT: !{{[0-9]+}} = !DITemplateTypeParameter(
!named = !{!0, !1, !2}
!0 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/Verifier/mdcompositetype-templateparams.ll b/llvm/test/Verifier/mdcompositetype-templateparams.ll
index 5d4bef2232fc0..6a15b32b6458d 100644
--- a/llvm/test/Verifier/mdcompositetype-templateparams.ll
+++ b/llvm/test/Verifier/mdcompositetype-templateparams.ll
@@ -1,10 +1,10 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: invalid template parameter
-; CHECK-NEXT: !2 = !DICompositeType(
-; CHECK-SAME: templateParams: !1
-; CHECK-NEXT: !1 = !{!0}
-; CHECK-NEXT: !0 = !DIBasicType(
+; CHECK-NEXT: !{{[0-9]+}} = !DICompositeType(
+; CHECK-SAME: templateParams: !{{[0-9]+}}
+; CHECK-NEXT: !{{[0-9]+}} = !{!{{[0-9]+}}}
+; CHECK-NEXT: !{{[0-9]+}} = !DIBasicType(
!named = !{!0, !1, !2}
!0 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/Verifier/module-flags-cgprofile.ll b/llvm/test/Verifier/module-flags-cgprofile.ll
index 3eda5325f396e..ea90d6d066735 100644
--- a/llvm/test/Verifier/module-flags-cgprofile.ll
+++ b/llvm/test/Verifier/module-flags-cgprofile.ll
@@ -18,9 +18,9 @@ declare void @a()
; CHECK: expected a MDNode triple
; CHECK: !""
; CHECK: expected a MDNode triple
-; CHECK: !3 = !{ptr @a, ptr @b}
+; CHECK: !{{[0-9]+}} = !{ptr @a, ptr @b}
; CHECK: expected a MDNode triple
-; CHECK: !4 = !{ptr @a, ptr @b, i64 32, i64 32}
+; CHECK: !{{[0-9]+}} = !{ptr @a, ptr @b, i64 32, i64 32}
; CHECK: expected a Function or null
; CHECK: !"a"
; CHECK: expected a Function or null
diff --git a/llvm/test/Verifier/noalias-addrspace.ll b/llvm/test/Verifier/noalias-addrspace.ll
index 67a7293d2561c..6b7d88539fb25 100644
--- a/llvm/test/Verifier/noalias-addrspace.ll
+++ b/llvm/test/Verifier/noalias-addrspace.ll
@@ -1,28 +1,28 @@
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
; CHECK: It should have at least one range!
-; CHECK-NEXT: !0 = !{}
+; CHECK-NEXT: !{{[0-9]+}} = !{}
define i64 @noalias_addrspace__empty(ptr %ptr, i64 %val) {
%ret = atomicrmw add ptr %ptr, i64 %val seq_cst, !noalias.addrspace !0
ret i64 %ret
}
; CHECK: Unfinished range!
-; CHECK-NEXT: !1 = !{i32 0}
+; CHECK-NEXT: !{{[0-9]+}} = !{i32 0}
define i64 @noalias_addrspace__single_field(ptr %ptr, i64 %val) {
%ret = atomicrmw add ptr %ptr, i64 %val seq_cst, !noalias.addrspace !1
ret i64 %ret
}
; CHECK: Range must not be empty!
-; CHECK-NEXT: !2 = !{i32 0, i32 0}
+; CHECK-NEXT: !{{[0-9]+}} = !{i32 0, i32 0}
define i64 @noalias_addrspace__0_0(ptr %ptr, i64 %val) {
%ret = atomicrmw add ptr %ptr, i64 %val seq_cst, !noalias.addrspace !2
ret i64 %ret
}
; CHECK: noalias.addrspace type must be i32!
-; CHECK-NEXT: %ret = atomicrmw add ptr %ptr, i64 %val seq_cst, align 8, !noalias.addrspace !3
+; CHECK-NEXT: %ret = atomicrmw add ptr %ptr, i64 %val seq_cst, align 8, !noalias.addrspace !{{[0-9]+}}
define i64 @noalias_addrspace__i64(ptr %ptr, i64 %val) {
%ret = atomicrmw add ptr %ptr, i64 %val seq_cst, !noalias.addrspace !3
ret i64 %ret
@@ -57,4 +57,3 @@ define i64 @noalias_addrspace__nonconstant(ptr %ptr, i64 %val) {
!5 = !{ptr null, ptr addrspace(1) null}
!6 = !{i32 ptrtoint (ptr @gv0 to i32), i32 ptrtoint (ptr @gv1 to i32) }
-
diff --git a/llvm/test/Verifier/noalias_scope_decl.ll b/llvm/test/Verifier/noalias_scope_decl.ll
index 6fbb9ffa66080..b457c5129dd57 100644
--- a/llvm/test/Verifier/noalias_scope_decl.ll
+++ b/llvm/test/Verifier/noalias_scope_decl.ll
@@ -10,7 +10,7 @@ define void @test_single_scope02() nounwind ssp {
ret void
}
; CHECK: !id.scope.list must point to a list with a single scope
-; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !5)
+; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
define void @test_single_scope03() nounwind ssp {
tail call void @llvm.experimental.noalias.scope.decl(metadata !"test")
@@ -31,7 +31,7 @@ define void @test_dom02() nounwind ssp {
ret void
}
; CHECK-NEXT: llvm.experimental.noalias.scope.decl dominates another one with the same scope
-; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !2)
+; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
define void @test_dom03() nounwind ssp {
tail call void @llvm.experimental.noalias.scope.decl(metadata !2)
@@ -39,7 +39,7 @@ define void @test_dom03() nounwind ssp {
ret void
}
; CHECK-NEXT: llvm.experimental.noalias.scope.decl dominates another one with the same scope
-; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !2)
+; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-NOT: llvm.experimental.noalias.scope.decl
diff --git a/llvm/test/Verifier/ref.ll b/llvm/test/Verifier/ref.ll
index 58e195320583e..8dfa77aafaaa7 100644
--- a/llvm/test/Verifier/ref.ll
+++ b/llvm/test/Verifier/ref.ll
@@ -13,19 +13,19 @@
; CHECK: ref value must be pointer typed
; CHECK: ptr @a
-; CHECK: !0 = !{i32 1}
+; CHECK: !{{[0-9]+}} = !{i32 1}
; CHECK: values should not reference themselves
; CHECK: ptr @b
-; CHECK: !1 = !{ptr @b}
+; CHECK: !{{[0-9]+}} = !{ptr @b}
; CHECK: ref metadata must be ValueAsMetadata
; CHECK: ptr @c
-; CHECK: !2 = !{!"Hello World!"}
+; CHECK: !{{[0-9]+}} = !{!"Hello World!"}
; CHECK: ref metadata must have one operand
; CHECK: ptr @d
-; CHECK: !3 = !{ptr @c, ptr @a}
+; CHECK: !{{[0-9]+}} = !{ptr @c, ptr @a}
; CHECK: ref metadata must not be placed on a declaration
; CHECK: @e
diff --git a/llvm/test/Verifier/reloc-none.ll b/llvm/test/Verifier/reloc-none.ll
index 9c96799a36a36..55e60d262b5bd 100644
--- a/llvm/test/Verifier/reloc-none.ll
+++ b/llvm/test/Verifier/reloc-none.ll
@@ -1,7 +1,7 @@
; RUN: not llvm-as -disable-output 2>&1 %s | FileCheck %s
; CHECK: llvm.reloc.none argument must be a metadata string
-; CHECK-NEXT: call void @llvm.reloc.none(metadata !0)
+; CHECK-NEXT: call void @llvm.reloc.none(metadata !{{[0-9]+}})
define void @test_reloc_none_bad_arg() {
call void @llvm.reloc.none(metadata !0)
diff --git a/llvm/test/tools/llubi/metadata.ll b/llvm/test/tools/llubi/metadata.ll
index b5e5d48b6536f..71f71b0a36116 100644
--- a/llvm/test/tools/llubi/metadata.ll
+++ b/llvm/test/tools/llubi/metadata.ll
@@ -39,27 +39,27 @@ define void @main() {
; CHECK: Entering function: main
; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
; CHECK-NEXT: store i32 1, ptr %alloc, align 4
-; CHECK-NEXT: %range_load_valid = load i32, ptr %alloc, align 4, !range !0, !noundef !1 => i32 1
-; CHECK-NEXT: %range_load_invalid = load i32, ptr %alloc, align 4, !range !2 => poison
+; CHECK-NEXT: %range_load_valid = load i32, ptr %alloc, align 4, !range !{{[0-9]+}}, !noundef !{{[0-9]+}} => i32 1
+; CHECK-NEXT: %range_load_invalid = load i32, ptr %alloc, align 4, !range !{{[0-9]+}} => poison
; CHECK-NEXT: %alloc_vec = alloca <8 x i32>, align 32 => ptr 0x20 [alloc_vec]
; CHECK-NEXT: store <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, ptr %alloc_vec, align 32
-; CHECK-NEXT: %range_list_load_vec = load <8 x i32>, ptr %alloc_vec, align 32, !range !3 => { i32 0, i32 1, poison, i32 3, poison, i32 5, poison, i32 7 }
+; CHECK-NEXT: %range_list_load_vec = load <8 x i32>, ptr %alloc_vec, align 32, !range !{{[0-9]+}} => { i32 0, i32 1, poison, i32 3, poison, i32 5, poison, i32 7 }
; CHECK-NEXT: store float 0.000000e+00, ptr %alloc, align 4
-; CHECK-NEXT: %nofpclass_load_valid = load float, ptr %alloc, align 4, !noundef !1, !nofpclass !4 => float 0.000000e+00
-; CHECK-NEXT: %nofpclass_load_invalid = load float, ptr %alloc, align 4, !nofpclass !5 => poison
+; CHECK-NEXT: %nofpclass_load_valid = load float, ptr %alloc, align 4, !noundef !{{[0-9]+}}, !nofpclass !{{[0-9]+}} => float 0.000000e+00
+; CHECK-NEXT: %nofpclass_load_invalid = load float, ptr %alloc, align 4, !nofpclass !{{[0-9]+}} => poison
; CHECK-NEXT: %alloc_ptr = alloca ptr, align 8 => ptr 0x48 [alloc_ptr]
; CHECK-NEXT: store ptr %alloc_ptr, ptr %alloc_ptr, align 8
-; CHECK-NEXT: %align_nonnull_load_valid = load ptr, ptr %alloc_ptr, align 8, !nonnull !1, !dereferenceable !6, !dereferenceable_or_null !6, !align !6, !noundef !1 => ptr 0x48 [alloc_ptr]
+; CHECK-NEXT: %align_nonnull_load_valid = load ptr, ptr %alloc_ptr, align 8, !nonnull !{{[0-9]+}}, !dereferenceable !{{[0-9]+}}, !dereferenceable_or_null !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}} => ptr 0x48 [alloc_ptr]
; CHECK-NEXT: store ptr null, ptr %alloc_ptr, align 8
-; CHECK-NEXT: %align_load_valid = load ptr, ptr %alloc_ptr, align 8, !dereferenceable_or_null !6, !align !6, !noundef !1 => ptr 0x0 [nullary]
-; CHECK-NEXT: %nonnull_load_invalid = load ptr, ptr %alloc_ptr, align 8, !nonnull !1 => poison
+; CHECK-NEXT: %align_load_valid = load ptr, ptr %alloc_ptr, align 8, !dereferenceable_or_null !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}} => ptr 0x0 [nullary]
+; CHECK-NEXT: %nonnull_load_invalid = load ptr, ptr %alloc_ptr, align 8, !nonnull !{{[0-9]+}} => poison
; CHECK-NEXT: Entering function: callee
; CHECK-NEXT: ret i32 10
; CHECK-NEXT: Exiting function: callee
-; CHECK-NEXT: %range_call_valid = call i32 @callee(), !range !7 => i32 10
+; CHECK-NEXT: %range_call_valid = call i32 @callee(), !range !{{[0-9]+}} => i32 10
; CHECK-NEXT: Entering function: callee
; CHECK-NEXT: ret i32 10
; CHECK-NEXT: Exiting function: callee
-; CHECK-NEXT: %range_call_invalid = call i32 @callee(), !range !0 => poison
+; CHECK-NEXT: %range_call_invalid = call i32 @callee(), !range !{{[0-9]+}} => poison
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/metadata_noundef_ub.ll b/llvm/test/tools/llubi/metadata_noundef_ub.ll
index d18d6b20c20dc..1a2b71346ceec 100644
--- a/llvm/test/tools/llubi/metadata_noundef_ub.ll
+++ b/llvm/test/tools/llubi/metadata_noundef_ub.ll
@@ -11,6 +11,6 @@ define void @main() {
; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
; CHECK-NEXT: store i32 -1, ptr %alloc, align 4
; CHECK-NEXT: Stacktrace:
-; CHECK-NEXT: #0 %res = load i32, ptr %alloc, align 4, !range !0, !noundef !1 at @main <stdin>:7
+; CHECK-NEXT: #0 %res = load i32, ptr %alloc, align 4, !range !{{[0-9]+}}, !noundef !{{[0-9]+}} at @main <stdin>:7
; CHECK-NEXT: Immediate UB detected: The value poison violates !noundef metadata.
; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/test/tools/llubi/noalias_scope.ll b/llvm/test/tools/llubi/noalias_scope.ll
index c04b89df37b8a..1cd764b957d25 100644
--- a/llvm/test/tools/llubi/noalias_scope.ll
+++ b/llvm/test/tools/llubi/noalias_scope.ll
@@ -11,6 +11,6 @@ entry:
!1 = distinct !{!1, !2, !"func: %agg.result"}
!2 = distinct !{!2, !"func"}
; CHECK: Entering function: main
-; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test
index 51a807942c48e..b11128d164ea7 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test
@@ -40,11 +40,11 @@
; ONE-NEXT: [003] {Block}
; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: [004] 5 {Line}
-; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32'
+; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [004] 6 {Line}
-; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33'
+; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [004] 6 {Line}
-; ONE-NEXT: [004] {Code} 'br label %return, !dbg !33'
+; ONE-NEXT: [004] {Code} 'br label %return, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool'
@@ -60,19 +60,19 @@
; ONE-NEXT: [003] {Code} '%storedv = zext i1 %ParamBool to i8'
; ONE-NEXT: [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1'
; ONE-NEXT: [003] 8 {Line}
-; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34'
+; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 8 {Line}
-; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35'
+; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 8 {Line}
-; ONE-NEXT: [003] {Code} 'br label %return, !dbg !35'
+; ONE-NEXT: [003] {Code} 'br label %return, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 9 {Line}
-; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36'
+; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 9 {Line}
-; ONE-NEXT: [003] {Code} 'ret i32 %2, !dbg !36'
+; ONE-NEXT: [003] {Code} 'ret i32 %2, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 3 {Line}
-; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26'
+; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 3 {Line}
-; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26'
+; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 3 {Line}
-; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26'
+; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !{{[0-9]+}}'
; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test
index 51bbb30c1d97e..cae4183e7253f 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test
@@ -30,16 +30,16 @@
; ONE-NEXT: [000] {File} 'test-clang.ll'
; ONE-EMPTY:
; ONE-NEXT: [001] {CompileUnit} 'test.cpp'
-; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26'
-; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34'
-; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36'
-; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26'
+; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !{{[0-9]+}}'
+; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !{{[0-9]+}}'
+; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !{{[0-9]+}}'
+; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] {Code} '%storedv = zext i1 %ParamBool to i8'
-; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26'
-; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35'
+; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !{{[0-9]+}}'
+; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4'
-; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32'
-; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33'
+; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !{{[0-9]+}}'
+; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1'
; ONE-NEXT: [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8'
; ONE-EMPTY:
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test
index 76272e3f677ea..8280d0f41ff6d 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test
@@ -33,9 +33,9 @@
; ONE-NEXT: [003] {Code} '%retval = alloca i32, align 4'
; ONE-NEXT: [003] {Code} 'store i32 0, ptr %retval, align 4'
; ONE-NEXT: [003] 5 {Line}
-; ONE-NEXT: [003] {Code} '%call = call noundef i32 (ptr, ...) @_Z6printfPKcz(ptr noundef @.str), !dbg !22'
+; ONE-NEXT: [003] {Code} '%call = call noundef i32 (ptr, ...) @_Z6printfPKcz(ptr noundef @.str), !dbg !{{[0-9]+}}'
; ONE-NEXT: [003] 6 {Line}
-; ONE-NEXT: [003] {Code} 'ret i32 0, !dbg !23'
+; ONE-NEXT: [003] {Code} 'ret i32 0, !dbg !{{[0-9]+}}'
; ONE-EMPTY:
; ONE-NEXT: Logical View:
; ONE-NEXT: [000] {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test
index 3f6db431a676c..29fc246b27a21 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test
@@ -51,11 +51,11 @@
; ONE-NEXT: [0x0000000000][006] {Location}
; ONE-NEXT: [0x0000000000][007] {Entry} bregx 3 ptr %CONSTANT+0
; ONE-NEXT: [0x0000000030][004] 5 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000030][004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32'
+; ONE-NEXT: [0x0000000030][004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000034][004] 6 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000034][004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33'
+; ONE-NEXT: [0x0000000034][004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000038][004] 6 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000038][004] {Code} 'br label %return, !dbg !33'
+; ONE-NEXT: [0x0000000038][004] {Code} 'br label %return, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000014][003] 2 {Parameter} 'ParamPtr' -> [0x0000000028]'INTPTR'
; ONE-NEXT: [0x0000000014][004] {Coverage} 100.00%
; ONE-NEXT: [0x0000000000][004] {Location}
@@ -80,21 +80,21 @@
; ONE-NEXT: [0x000000001c][003] {Code} '%storedv = zext i1 %ParamBool to i8'
; ONE-NEXT: [0x0000000020][003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1'
; ONE-NEXT: [0x000000003c][003] 8 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x000000003c][003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34'
+; ONE-NEXT: [0x000000003c][003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000040][003] 8 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000040][003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35'
+; ONE-NEXT: [0x0000000040][003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000044][003] 8 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000044][003] {Code} 'br label %return, !dbg !35'
+; ONE-NEXT: [0x0000000044][003] {Code} 'br label %return, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000048][003] 9 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000048][003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36'
+; ONE-NEXT: [0x0000000048][003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x000000004c][003] 9 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x000000004c][003] {Code} 'ret i32 %2, !dbg !36'
+; ONE-NEXT: [0x000000004c][003] {Code} 'ret i32 %2, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000024][003] 3 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000024][003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26'
+; ONE-NEXT: [0x0000000024][003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000028][003] 3 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x0000000028][003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26'
+; ONE-NEXT: [0x0000000028][003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x000000002c][003] 3 {Line} '{{.*}}/general/test.cpp'
-; ONE-NEXT: [0x000000002c][003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26'
+; ONE-NEXT: [0x000000002c][003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !{{[0-9]+}}'
; ONE-NEXT: [0x0000000024][002] {BaseType} 'int'
; ONE-NEXT: [0x0000000028][002] 1 {TypeAlias} 'INTPTR' -> [0x000000002c]'* const int'
; ONE-NEXT: [0x0000000034][002] {BaseType} 'unsigned int'
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index a961f9cb0f7dd..2a986fc145fbf 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -263,6 +263,7 @@ int main(int argc, char **argv) {
// All that llvm-dis does is write the assembly to a file.
if (!DontPrint) {
if (M) {
+ M->renumberMetadataForAssembly();
M->print(Out->os(), Annotator.get(),
/* ShouldPreserveUseListOrder */ false);
}
diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp
index 439a4a48b350a..cf49f3618b891 100644
--- a/llvm/tools/llvm-extract/llvm-extract.cpp
+++ b/llvm/tools/llvm-extract/llvm-extract.cpp
@@ -411,8 +411,8 @@ int main(int argc, char **argv) {
}
if (OutputAssembly)
- PM.addPass(
- PrintModulePass(Out.os(), "", /* ShouldPreserveUseListOrder */ false));
+ PM.addPass(PrintCanonicalModulePass(Out.os(), "",
+ /*ShouldPreserveUseListOrder=*/false));
else if (Force || !CheckBitcodeOutputToConsole(Out.os()))
PM.addPass(
BitcodeWriterPass(Out.os(), /* ShouldPreserveUseListOrder */ true));
diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp
index e49082f2d7bfb..9390301f1b75a 100644
--- a/llvm/tools/llvm-link/llvm-link.cpp
+++ b/llvm/tools/llvm-link/llvm-link.cpp
@@ -518,6 +518,7 @@ int main(int argc, char **argv) {
if (Verbose)
errs() << "Writing bitcode...\n";
if (OutputAssembly) {
+ Composite->renumberMetadataForAssembly();
Composite->print(Out.os(), nullptr, /* ShouldPreserveUseListOrder */ false);
} else if (Force || !CheckBitcodeOutputToConsole(Out.os())) {
WriteBitcodeToFile(*Composite, Out.os(),
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index fa4da7a073f1e..e478a82f48071 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -449,6 +449,7 @@ void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
printMIR(ROS, *MMI, *MF);
}
} else {
+ M->renumberMetadataForAssembly();
M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
/*ShouldPreserveUseListOrder=*/true);
}
diff --git a/llvm/tools/llvm-split/llvm-split.cpp b/llvm/tools/llvm-split/llvm-split.cpp
index e7c9d52127274..4ead6fd4b88be 100644
--- a/llvm/tools/llvm-split/llvm-split.cpp
+++ b/llvm/tools/llvm-split/llvm-split.cpp
@@ -116,7 +116,7 @@ void writeStringToFile(StringRef Content, StringRef Path) {
OS << Content << "\n";
}
-void writeModuleToFile(const Module &M, StringRef Path, bool OutputAssembly) {
+void writeModuleToFile(Module &M, StringRef Path, bool OutputAssembly) {
int FD = -1;
if (std::error_code EC = sys::fs::openFileForWrite(Path, FD)) {
errs() << formatv("error opening file: {0}, error: {1}", Path, EC.message())
@@ -125,9 +125,10 @@ void writeModuleToFile(const Module &M, StringRef Path, bool OutputAssembly) {
}
raw_fd_ostream OS(FD, /*ShouldClose*/ true);
- if (OutputAssembly)
+ if (OutputAssembly) {
+ M.renumberMetadataForAssembly();
M.print(OS, /*AssemblyAnnotationWriter*/ nullptr);
- else
+ } else
WriteBitcodeToFile(M, OS);
}
diff --git a/llvm/tools/llvm-stress/llvm-stress.cpp b/llvm/tools/llvm-stress/llvm-stress.cpp
index e3c8a5c3d51ab..e99c83c2b9bac 100644
--- a/llvm/tools/llvm-stress/llvm-stress.cpp
+++ b/llvm/tools/llvm-stress/llvm-stress.cpp
@@ -754,6 +754,7 @@ int main(int argc, char **argv) {
report_fatal_error("Broken module found, compilation aborted!");
// Output textual IR.
+ M->renumberMetadataForAssembly();
M->print(Out->os(), nullptr);
Out->keep();
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 5a3e35f6f494d..bd61cd06899a3 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -529,7 +529,7 @@ bool llvm::runPassPipeline(
if (EmitSummaryIndex) {
MPM.addPass(AssignGUIDPass());
}
- MPM.addPass(PrintModulePass(
+ MPM.addPass(PrintCanonicalModulePass(
Out->os(), "", ShouldPreserveAssemblyUseListOrder, EmitSummaryIndex));
break;
case OK_OutputBitcode:
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index e8c50110acc82..13836e0ebed40 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -931,10 +931,10 @@ optMain(int argc, char **argv,
BOS = std::make_unique<raw_svector_ostream>(Buffer);
OS = BOS.get();
}
- if (OutputAssembly)
- Passes.add(createPrintModulePass(
+ if (OutputAssembly) {
+ Passes.add(createPrintCanonicalModulePass(
*OS, "", /* ShouldPreserveAssemblyUseListOrder */ false));
- else
+ } else
Passes.add(createBitcodeWriterPass(
*OS, /* ShouldPreserveBitcodeUseListOrder */ true));
}
diff --git a/llvm/tools/verify-uselistorder/verify-uselistorder.cpp b/llvm/tools/verify-uselistorder/verify-uselistorder.cpp
index 8f58cc00a3dd1..95edf41e84ce4 100644
--- a/llvm/tools/verify-uselistorder/verify-uselistorder.cpp
+++ b/llvm/tools/verify-uselistorder/verify-uselistorder.cpp
@@ -75,7 +75,7 @@ struct TempFile {
FileRemover Remover;
bool init(const std::string &Ext, bool IsText = false);
bool writeBitcode(const Module &M) const;
- bool writeAssembly(const Module &M) const;
+ bool writeAssembly(Module &M) const;
std::unique_ptr<Module> readBitcode(LLVMContext &Context) const;
std::unique_ptr<Module> readAssembly(LLVMContext &Context) const;
};
@@ -137,7 +137,7 @@ bool TempFile::writeBitcode(const Module &M) const {
return false;
}
-bool TempFile::writeAssembly(const Module &M) const {
+bool TempFile::writeAssembly(Module &M) const {
LLVM_DEBUG(dbgs() << " - write assembly\n");
std::error_code EC;
raw_fd_ostream OS(Filename, EC, sys::fs::OF_TextWithCRLF);
@@ -146,6 +146,7 @@ bool TempFile::writeAssembly(const Module &M) const {
return true;
}
+ M.renumberMetadataForAssembly();
M.print(OS, nullptr, /* ShouldPreserveUseListOrder */ true);
return false;
}
@@ -379,7 +380,7 @@ static void verifyBitcodeUseListOrder(const Module &M) {
verifyAfterRoundTrip(M, F.readBitcode(Context));
}
-static void verifyAssemblyUseListOrder(const Module &M) {
+static void verifyAssemblyUseListOrder(Module &M) {
TempFile F;
if (F.init("ll", /*IsText=*/true))
report_fatal_error("failed to initialize assembly file");
@@ -391,7 +392,7 @@ static void verifyAssemblyUseListOrder(const Module &M) {
verifyAfterRoundTrip(M, F.readAssembly(Context));
}
-static void verifyUseListOrder(const Module &M) {
+static void verifyUseListOrder(Module &M) {
outs() << "verify bitcode\n";
verifyBitcodeUseListOrder(M);
outs() << "verify assembly\n";
diff --git a/llvm/unittests/IR/AsmWriterTest.cpp b/llvm/unittests/IR/AsmWriterTest.cpp
index 5a4421d5daef0..6c04309af810e 100644
--- a/llvm/unittests/IR/AsmWriterTest.cpp
+++ b/llvm/unittests/IR/AsmWriterTest.cpp
@@ -173,7 +173,7 @@ TEST(AsmWriterTest, PersistentPrintTemporaryMetadata) {
std::string ModuleText;
raw_string_ostream ModuleOS(ModuleText);
- M.printWithPersistentMetadataIDs(ModuleOS);
+ M.print(ModuleOS, nullptr);
EXPECT_THAT(ModuleText, HasSubstr("!0 = distinct !{!\"permanent\"}"));
EXPECT_THAT(ModuleText, HasSubstr("!1 = <temporary!> !{!0}"));
@@ -182,8 +182,8 @@ TEST(AsmWriterTest, PersistentPrintTemporaryMetadata) {
std::string LaterText;
raw_string_ostream LaterOS(LaterText);
F->print(LaterOS);
- EXPECT_THAT(LaterText, HasSubstr("!later !1"));
- EXPECT_THAT(LaterText, HasSubstr("!temporary !2"));
+ EXPECT_THAT(LaterText, HasSubstr("!later !2"));
+ EXPECT_THAT(LaterText, HasSubstr("!temporary !1"));
}
TEST(AsmWriterTest, PrintAddrspaceWithNullOperand) {
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 07496cec696ca..9facfda0b32ce 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -282,15 +282,11 @@ TEST_F(MDNodeTest, Print) {
std::string Expected;
{
raw_string_ostream OS(Expected);
- OS << "<" << (void *)N << "> = !{";
+ OS << "!3 = !{";
C->printAsOperand(OS);
OS << ", ";
S->printAsOperand(OS);
- OS << ", null";
- MDNode *Nodes[] = {N0, N1, N2};
- for (auto *Node : Nodes)
- OS << ", <" << (void *)Node << ">";
- OS << "}";
+ OS << ", null, !0, !1, !2}";
}
std::string Actual;
@@ -319,9 +315,9 @@ TEST_F(MDNodeTest, PrintTemporary) {
NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
NMD->addOperand(N);
- EXPECT_PRINTER_EQ("!0 = !{!1}", N->print(OS, &M));
- EXPECT_PRINTER_EQ("!1 = <temporary!> !{!2}", Temp->print(OS, &M));
- EXPECT_PRINTER_EQ("!2 = !{}", Arg->print(OS, &M));
+ EXPECT_PRINTER_EQ("!2 = !{!1}", N->print(OS, &M));
+ EXPECT_PRINTER_EQ("!1 = <temporary!> !{!0}", Temp->print(OS, &M));
+ EXPECT_PRINTER_EQ("!0 = !{}", Arg->print(OS, &M));
// Cleanup.
Temp->replaceAllUsesWith(Arg);
@@ -343,11 +339,11 @@ TEST_F(MDNodeTest, PrintFromModule) {
std::string Expected;
{
raw_string_ostream OS(Expected);
- OS << "!0 = !{";
+ OS << "!3 = !{";
C->printAsOperand(OS);
OS << ", ";
S->printAsOperand(OS);
- OS << ", null, !1, !2, !3}";
+ OS << ", null, !0, !1, !2}";
}
EXPECT_PRINTER_EQ(Expected, N->print(OS, &M));
diff --git a/llvm/unittests/IR/ModuleTest.cpp b/llvm/unittests/IR/ModuleTest.cpp
index e8c2ecfb9f3a8..d5b06e85128b7 100644
--- a/llvm/unittests/IR/ModuleTest.cpp
+++ b/llvm/unittests/IR/ModuleTest.cpp
@@ -438,6 +438,7 @@ define void @Foo2() {
ASSERT_EQ(NMD.getParent(), &*M1);
}
+ M1->renumberMetadataForAssembly();
std::string M1Print;
{
llvm::raw_string_ostream Os(M1Print);
diff --git a/llvm/unittests/MIR/MachineMetadata.cpp b/llvm/unittests/MIR/MachineMetadata.cpp
index f58a3cac1bb0f..6abd2f507e61d 100644
--- a/llvm/unittests/MIR/MachineMetadata.cpp
+++ b/llvm/unittests/MIR/MachineMetadata.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/FileCheck/FileCheck.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
@@ -49,20 +50,9 @@ class MachineMetadataTest : public testing::Test {
void SetUp() override { M = std::make_unique<Module>("Dummy", Context); }
void addHooks(ModuleSlotTracker &MST, const MachineOperand &MO) {
- // Setup hooks to assign slot numbers for the specified machine metadata.
- MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Module *M,
- bool ShouldInitializeAllMetadata) {
- if (ShouldInitializeAllMetadata) {
- if (MO.isMetadata())
- AST->createMetadataSlot(MO.getMetadata());
- }
- });
- MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Function *F,
- bool ShouldInitializeAllMetadata) {
- if (!ShouldInitializeAllMetadata) {
- if (MO.isMetadata())
- AST->createMetadataSlot(MO.getMetadata());
- }
+ MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Module *) {
+ if (MO.isMetadata())
+ AST->createMetadataSlot(MO.getMetadata());
});
}
@@ -140,9 +130,7 @@ TEST_F(MachineMetadataTest, TrivialHook) {
}
TEST_F(MachineMetadataTest, BasicHook) {
- // Verify that post-process hook is invoked to assign slot numbers for
- // machine metadata. When both LLVM IR and machine IR contain metadata,
- // ensure that machine metadata is always assigned after LLVM IR.
+ // Verify that the post-process hook records machine metadata.
ASSERT_TRUE(M);
// Create a MachineOperand with a metadata and print it.
@@ -165,16 +153,16 @@ TEST_F(MachineMetadataTest, BasicHook) {
addHooks(MST, MO);
// Print a MachineOperand containing a metadata node.
- EXPECT_EQ("!1", print([&](raw_ostream &OS) {
+ EXPECT_EQ("!0", print([&](raw_ostream &OS) {
MO.print(OS, MST, LLT{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,
/*IsStandalone=*/false,
/*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,
/*TRI=*/nullptr);
}));
// Print the definition of these unnamed metadata nodes.
- EXPECT_EQ("!0 = !{!\"bar\"}",
+ EXPECT_EQ("!1 = !{!\"bar\"}",
print([&](raw_ostream &OS) { Node->print(OS, MST); }));
- EXPECT_EQ("!1 = !{!\"foo\"}",
+ EXPECT_EQ("!0 = !{!\"foo\"}",
print([&](raw_ostream &OS) { MachineNode->print(OS, MST); }));
}
@@ -252,8 +240,8 @@ body: |
MachineModuleSlotTracker MST(
[&](const Function &F) { return MMI.getMachineFunction(F); }, MF);
- // Print that MI with new machine metadata, which slot numbers should be
- // assigned.
+ MST.renumberMetadataForAssembly();
+ // Print the MI using the stored IDs of the new machine metadata.
EXPECT_EQ("%1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, "
"!alias.scope !0, !noalias !3)",
print([&](raw_ostream &OS) {
@@ -342,10 +330,37 @@ body: |
auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));
auto *MBB = MF->getBlockNumbered(0);
+ MachineInstr *DbgValue = nullptr;
for (auto It = MBB->begin(); It != MBB->end(); ++It) {
MachineInstr &MI = *It;
ASSERT_TRUE(MI.isMetaInstruction());
+ if (MI.isDebugValue())
+ DbgValue = &MI;
}
+
+ ASSERT_NE(DbgValue, nullptr);
+ auto *IRVar = cast<DILocalVariable>(DbgValue->getOperand(2).getMetadata());
+ auto *MachineNode = MDNode::get(Context, MDString::get(Context, "machine"));
+ MBB->front().addOperand(*MF, MachineOperand::CreateMetadata(MachineNode));
+ auto *MachineLoc =
+ DILocation::get(Context, 2, 1, DbgValue->getDebugLoc()->getScope());
+ DbgValue->setDebugLoc(DebugLoc(MachineLoc));
+
+ MachineModuleSlotTracker MST(
+ [&](const Function &F) { return MMI.getMachineFunction(F); }, MF);
+ MST.renumberMetadataForAssembly();
+ MachineModuleSlotTracker::MachineMDNodeListType MDList;
+ MST.collectMachineMDNodes(MDList);
+ EXPECT_TRUE(llvm::any_of(
+ MDList, [&](const auto &MD) { return MD.second == MachineNode; }));
+ EXPECT_TRUE(llvm::any_of(
+ MDList, [&](const auto &MD) { return MD.second == MachineLoc; }));
+ EXPECT_TRUE(
+ llvm::any_of(MDList, [&](const auto &MD) { return MD.second == IRVar; }));
+
+ std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });
+ MachineModuleInfo RoundTripMMI(TM.get());
+ EXPECT_TRUE(parseMIR(*TM, Output, RoundTripMMI)) << Output;
}
TEST_F(MachineMetadataTest, MMSlotTrackerX64) {
@@ -403,14 +418,15 @@ body: |
MachineModuleSlotTracker MST(
[&](const Function &F) { return MMI.getMachineFunction(F); }, MF);
- // Print that MI with new machine metadata, which slot numbers should be
- // assigned.
- EXPECT_EQ("%1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, "
- "!alias.scope !0, !noalias !3)",
- print([&](raw_ostream &OS) {
- MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,
- /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
- }));
+ MST.renumberMetadataForAssembly();
+ // Print the MI using the stored IDs of the new machine metadata.
+ EXPECT_EQ(
+ "%1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, "
+ "!alias.scope !0, !noalias !3)",
+ print([&](raw_ostream &OS) {
+ MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,
+ /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
+ }));
std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
// Examine machine metadata collected. They should match ones
@@ -502,8 +518,8 @@ body: |
MachineModuleSlotTracker MST(
[&](const Function &F) { return MMI.getMachineFunction(F); }, MF);
- // Print that MI with new machine metadata, which slot numbers should be
- // assigned.
+ MST.renumberMetadataForAssembly();
+ // Print the MI using the stored IDs of the new machine metadata.
EXPECT_EQ(
"%5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit "
"$flat_scr :: (load (s32) from %ir.p, !alias.scope !0, !noalias !3)",
diff --git a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
index fef191a302ac8..1797efec0252f 100644
--- a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
@@ -31,6 +31,7 @@ void registerToLLVMIRTranslation() {
if (!llvmModule)
return failure();
+ llvmModule->renumberMetadataForAssembly();
llvmModule->print(output, nullptr);
return success();
},
>From c607629bc43914210abdd0d43bbfe92075bfa535 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Thu, 20 Aug 2026 21:51:10 -0400
Subject: [PATCH 6/6] [IR] Fix metadata renumbering and MIR serialization
---
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 43 ++++-----------
llvm/lib/CodeGen/MachineModuleSlotTracker.cpp | 23 +++++++-
llvm/lib/IR/AsmWriter.cpp | 15 ++++++
llvm/lib/IR/LLVMContextImpl.cpp | 9 ++++
llvm/lib/IR/LLVMContextImpl.h | 6 +++
llvm/lib/IR/Metadata.cpp | 13 +++++
llvm/lib/IR/MetadataImpl.h | 2 +
llvm/lib/Passes/StandardInstrumentations.cpp | 4 +-
.../Analysis/BasicAA/noalias-scope-decl.ll | 8 +--
.../MIR/Generic/machine-metadata-err0.mir | 2 +-
.../MIR/Generic/machine-metadata-err1.mir | 2 +-
.../MIR/Generic/machine-metadata-err2.mir | 2 +-
.../MIR/Generic/machine-metadata-err6.mir | 2 +-
.../MIR/Generic/machine-metadata-err7.mir | 2 +-
.../MIR/Generic/machine-metadata-err8.mir | 2 +-
.../MIR/X86/machine-metadata-round-trip.mir | 35 ++++++++++++
.../MIR/X86/machine-metadata-specialized.mir | 10 ++++
llvm/unittests/IR/ModuleTest.cpp | 54 +++++++++++++++++++
18 files changed, 187 insertions(+), 47 deletions(-)
create mode 100644 llvm/test/CodeGen/MIR/X86/machine-metadata-round-trip.mir
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index fee9f3e676391..fc2eacf8fc4cb 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -13,7 +13,6 @@
#include "llvm/CodeGen/MIRParser/MIRParser.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
@@ -179,9 +178,6 @@ class MIRParserImpl {
MachineBasicBlock *&MBB,
const yaml::StringValue &Source);
- bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
- const yaml::StringValue &Source);
-
/// Return a MIR diagnostic converted from an MI string diagnostic.
SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
SMRange SourceRange);
@@ -1227,37 +1223,9 @@ bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
return false;
}
-bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
- const yaml::StringValue &Source) {
- SMDiagnostic Error;
- if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
- return error(Error, Source.SourceRange);
- return false;
-}
-
bool MIRParserImpl::parseMachineMetadataNodes(
PerFunctionMIParsingState &PFS, MachineFunction &MF,
const yaml::MachineFunction &YMF) {
- bool HasSpecializedNode =
- llvm::any_of(YMF.MachineMetadataNodes, [](const yaml::StringValue &MDS) {
- StringRef RHS = StringRef(MDS.Value).split('=').second.ltrim();
- if (RHS.consume_front("distinct"))
- RHS = RHS.ltrim();
- return RHS.starts_with("!DI") || RHS.starts_with("!GenericDI");
- });
- if (!HasSpecializedNode) {
- for (const auto &MDS : YMF.MachineMetadataNodes) {
- if (parseMachineMetadata(PFS, MDS))
- return true;
- }
- if (!PFS.MachineForwardRefMDNodes.empty())
- return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
- "use of undefined metadata '!" +
- Twine(PFS.MachineForwardRefMDNodes.begin()->first) +
- "'");
- return false;
- }
-
std::string Definitions;
for (const auto &MDS : YMF.MachineMetadataNodes) {
Definitions.append(MDS.Value);
@@ -1271,7 +1239,16 @@ bool MIRParserImpl::parseMachineMetadataNodes(
unsigned Line = std::max(Error.getLineNo(), 1);
unsigned Index =
std::min<unsigned>(Line - 1, YMF.MachineMetadataNodes.size() - 1);
- return error(Error, YMF.MachineMetadataNodes[Index].SourceRange);
+ const yaml::StringValue &Source = YMF.MachineMetadataNodes[Index];
+ if (Line > YMF.MachineMetadataNodes.size()) {
+ const char *Start = Source.SourceRange.Start.getPointer();
+ const char *End = Source.SourceRange.End.getPointer();
+ SMLoc Loc = Source.SourceRange.End;
+ if (Start < End && (*Start == '\'' || *Start == '"'))
+ Loc = SMLoc::getFromPointer(End - 1);
+ return error(Loc, Error.getMessage());
+ }
+ return error(Error, Source.SourceRange);
}
for (auto &[ID, MD] : Slots.MetadataNodes)
diff --git a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
index 1c43f7be85129..14e4d684c1089 100644
--- a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
+++ b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
@@ -11,6 +11,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Module.h"
using namespace llvm;
@@ -23,6 +24,13 @@ void MachineModuleSlotTracker::collectMachineFunctionMetadata(
if (DebugLoc DL = MI.getDebugLoc())
Metadata.push_back(DL.getAsMDNode());
+ if (MDNode *N = MI.getHeapAllocMarker())
+ Metadata.push_back(N);
+ if (MDNode *N = MI.getPCSections())
+ Metadata.push_back(N);
+ if (MDNode *N = MI.getMMRAMetadata())
+ Metadata.push_back(N);
+
for (const MachineOperand &MO : MI.operands())
if (MO.isMetadata())
Metadata.push_back(MO.getMetadata());
@@ -31,14 +39,25 @@ void MachineModuleSlotTracker::collectMachineFunctionMetadata(
AAMDNodes AAInfo = MMO->getAAInfo();
if (AAInfo.TBAA)
Metadata.push_back(AAInfo.TBAA);
- if (AAInfo.TBAAStruct)
- Metadata.push_back(AAInfo.TBAAStruct);
if (AAInfo.Scope)
Metadata.push_back(AAInfo.Scope);
if (AAInfo.NoAlias)
Metadata.push_back(AAInfo.NoAlias);
+ if (AAInfo.NoAliasAddrSpace)
+ Metadata.push_back(AAInfo.NoAliasAddrSpace);
+ if (const MDNode *N = MMO->getRanges())
+ Metadata.push_back(N);
+ if (const MDNode *N = MMO->getMemCacheHint())
+ Metadata.push_back(N);
}
}
+
+ for (const MachineFunction::VariableDbgInfo &DebugVar :
+ MF.getVariableDbgInfo()) {
+ Metadata.push_back(DebugVar.Var);
+ Metadata.push_back(DebugVar.Expr);
+ Metadata.push_back(DebugVar.Loc);
+ }
}
void MachineModuleSlotTracker::processMachineFunctionMetadata(
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 4fc6b4dadd908..ccb1a151dea9e 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1267,6 +1267,21 @@ class MetadataIDRenumberer {
for (const MDNode *N : AdditionalMetadata)
renumber(N);
+ // Keep IDs unique for nodes outside the canonical output.
+ SmallVector<MDNode *, 32> RemainingNodes;
+ M.getContext().pImpl->getAllMetadataNodes(RemainingNodes);
+ llvm::erase_if(RemainingNodes, [&](const MDNode *N) {
+ return Visited.contains(N) ||
+ M.getContext().pImpl->getMetadataPrintID(N) >= NextID;
+ });
+ llvm::sort(RemainingNodes, [&](const MDNode *LHS, const MDNode *RHS) {
+ return M.getContext().pImpl->getMetadataPrintID(LHS) <
+ M.getContext().pImpl->getMetadataPrintID(RHS);
+ });
+ for (MDNode *N : RemainingNodes)
+ M.getContext().pImpl->setMetadataPrintID(
+ N, M.getContext().pImpl->allocateMetadataPrintID());
+
if (!AdditionalMetadataNodes)
return;
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 90afa09f73abe..83baaf16b7c8c 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -40,6 +40,15 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
Int64Ty(C, 64), Int128Ty(C, 128), Byte1Ty(C, 1), Byte8Ty(C, 8),
Byte16Ty(C, 16), Byte32Ty(C, 32), Byte64Ty(C, 64), Byte128Ty(C, 128) {}
+void LLVMContextImpl::getAllMetadataNodes(
+ SmallVectorImpl<MDNode *> &Nodes) const {
+ Nodes.append(DistinctMDNodes.begin(), DistinctMDNodes.end());
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
+ Nodes.append(CLASS##s.begin(), CLASS##s.end());
+#include "llvm/IR/Metadata.def"
+ Nodes.append(TemporaryMDNodes.begin(), TemporaryMDNodes.end());
+}
+
LLVMContextImpl::~LLVMContextImpl() {
#ifndef NDEBUG
// Check that any variable location records that fell off the end of a block
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index d2c9f54e03858..7d87f91b6000c 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1615,6 +1615,8 @@ class LLVMContextImpl {
uint32_t allocateMetadataPrintID() { return NextMetadataPrintID++; }
+ void getAllMetadataNodes(SmallVectorImpl<MDNode *> &Nodes) const;
+
uint32_t getMetadataPrintID(const MDNode *N) const {
return N->getHeader().MetadataPrintID;
}
@@ -1636,6 +1638,10 @@ class LLVMContextImpl {
// them on context teardown.
std::vector<MDNode *> DistinctMDNodes;
+ // Temporary nodes are caller-owned, but track live ones for persistent
+ // metadata print IDs.
+ DenseSet<MDNode *> TemporaryMDNodes;
+
// ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
// ConstantRange. Since this is a dynamically sized class, it's not
// possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index bbd2a2b580303..2b1a7bb117308 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -785,6 +785,9 @@ void MDNode::countUnresolvedOperands() {
void MDNode::makeUniqued() {
assert(isTemporary() && "Expected this to be temporary");
assert(!isResolved() && "Expected this to be unresolved");
+ bool WasTracked = getContext().pImpl->TemporaryMDNodes.erase(this);
+ assert(WasTracked && "Temporary node not tracked");
+ (void)WasTracked;
// Enable uniquing callbacks.
for (auto &Op : mutable_operands())
@@ -985,6 +988,11 @@ void MDNode::handleChangedOperand(void *Ref, Metadata *New) {
}
void MDNode::deleteAsSubclass() {
+ if (isTemporary()) {
+ bool WasTracked = getContext().pImpl->TemporaryMDNodes.erase(this);
+ assert(WasTracked && "Temporary node not tracked");
+ (void)WasTracked;
+ }
switch (getMetadataID()) {
default:
llvm_unreachable("Invalid subclass of MDNode");
@@ -1070,6 +1078,11 @@ void MDNode::deleteTemporary(MDNode *N) {
void MDNode::storeDistinctInContext() {
assert(!Context.hasReplaceableUses() && "Unexpected replaceable uses");
assert(!getNumUnresolved() && "Unexpected unresolved nodes");
+ if (isTemporary()) {
+ bool WasTracked = getContext().pImpl->TemporaryMDNodes.erase(this);
+ assert(WasTracked && "Temporary node not tracked");
+ (void)WasTracked;
+ }
Storage = Distinct;
assert(isResolved() && "Expected this to be resolved");
diff --git a/llvm/lib/IR/MetadataImpl.h b/llvm/lib/IR/MetadataImpl.h
index b4188dd7d3ee4..0045b7c406f97 100644
--- a/llvm/lib/IR/MetadataImpl.h
+++ b/llvm/lib/IR/MetadataImpl.h
@@ -33,6 +33,7 @@ template <class T> T *MDNode::storeImpl(T *N, StorageType Storage) {
N->storeDistinctInContext();
break;
case Temporary:
+ N->getContext().pImpl->TemporaryMDNodes.insert(N);
break;
}
return N;
@@ -48,6 +49,7 @@ T *MDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) {
N->storeDistinctInContext();
break;
case Temporary:
+ N->getContext().pImpl->TemporaryMDNodes.insert(N);
break;
}
return N;
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 77693f8b25c98..5b788926bd7c9 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -331,8 +331,8 @@ bool isIgnored(StringRef PassID) {
PassID,
{"PassManager", "PassAdaptor", "AnalysisManagerProxy",
"DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass", "VerifierPass",
- "PrintModulePass", "PrintCanonicalModulePass", "PrintMIRPass",
- "PrintMIRPreparePass", "RequireAnalysisPass", "InvalidateAnalysisPass"});
+ "PrintModulePass", "PrintMIRPass", "PrintMIRPreparePass",
+ "RequireAnalysisPass", "InvalidateAnalysisPass"});
}
std::string makeHTMLReady(StringRef SR) {
diff --git a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
index b7fbe43cfa3a3..99b0c6e38cf37 100644
--- a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
+++ b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll
@@ -14,12 +14,12 @@ define void @test1(ptr %P, ptr %Q) nounwind ssp {
; CHECK-LABEL: Function: test1:
; CHECK: MayAlias: i8* %P, i8* %Q
-; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
-; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
+; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPE:[0-9]+]])
+; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPE]])
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
-; CHECK: NoModRef: tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}}) <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
-; CHECK: NoModRef: tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <-> tail call void @llvm.experimental.noalias.scope.decl(metadata !{{[0-9]+}})
+; CHECK: NoModRef: tail call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPE]]) <-> tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
+; CHECK: NoModRef: tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <-> tail call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPE]])
}
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err0.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err0.mir
index 0502ac90e51eb..9d5848b80e0c5 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err0.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err0.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '9 = distinct !{!9, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:6: expected a metadata node
+# CHECK: [[@LINE-2]]:6: expected a metadata definition
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err1.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err1.mir
index 4ac5202527d2f..dd77caccb0cf1 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err1.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err1.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '! = distinct !{!9, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:8: expected metadata id after '!'
+# CHECK: [[@LINE-2]]:8: expected integer
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err2.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err2.mir
index 0e731b12c6456..8bb00b0aa6333 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err2.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err2.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '!9 = distinct {!9, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:20: expected a metadata node
+# CHECK: [[@LINE-2]]:20: Expected '!' here
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err6.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err6.mir
index 51cca1b259cd0..21dce2f8c4d97 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err6.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err6.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '!9 = distinct !{9, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:22: expected '!' here
+# CHECK: [[@LINE-2]]:22: expected metadata operand
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err7.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err7.mir
index 0cc5ef1b8af83..eaf78448f1245 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err7.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err7.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '!9 = distinct !{!, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:23: expected metadata id after '!'
+# CHECK: [[@LINE-2]]:23: expected integer
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err8.mir b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err8.mir
index 1d51dbc5d659d..ade425348782e 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-metadata-err8.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-metadata-err8.mir
@@ -12,4 +12,4 @@ name: t0
machineMetadataNodes:
- '!9 = distinct !{!9, !7, !"Dst"}'
...
-# CHECK: [[@LINE-2]]:26: use of undefined metadata '!7'
+# CHECK: [[@LINE-2]]:27: use of undefined metadata '!7'
diff --git a/llvm/test/CodeGen/MIR/X86/machine-metadata-round-trip.mir b/llvm/test/CodeGen/MIR/X86/machine-metadata-round-trip.mir
new file mode 100644
index 0000000000000..c1bcfd9794ece
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/machine-metadata-round-trip.mir
@@ -0,0 +1,35 @@
+# RUN: llc -mtriple=x86_64 -run-pass=none -o - %s | FileCheck %s
+# RUN: llc -mtriple=x86_64 -run-pass=none -o - %s | llc -mtriple=x86_64 -x mir -run-pass=none -filetype=null
+
+--- |
+ define i8 @test(ptr %p) {
+ %value = load i8, ptr %p
+ ret i8 %value
+ }
+...
+---
+name: test
+machineMetadataNodes:
+ - '!0 = !{!"heap"}'
+ - '!1 = !{!"pcsections"}'
+ - '!2 = !{!"tag", !"value"}'
+ - '!3 = !{i32 1}'
+ - '!4 = !{i8 0, i8 10}'
+ - '!5 = !{i32 0, !6}'
+ - '!6 = !{!"cache", !"streaming"}'
+body: |
+ bb.0:
+ liveins: $rdi
+
+ ; CHECK: machineMetadataNodes:
+ ; CHECK-DAG: - '![[HEAP:[0-9]+]] = !{!"heap"}'
+ ; CHECK-DAG: - '![[PCSECTIONS:[0-9]+]] = !{!"pcsections"}'
+ ; CHECK-DAG: - '![[MMRA:[0-9]+]] = !{!"tag", !"value"}'
+ ; CHECK-DAG: - '![[NOALIAS:[0-9]+]] = !{i32 1}'
+ ; CHECK-DAG: - '![[RANGE:[0-9]+]] = !{i8 0, i8 10}'
+ ; CHECK-DAG: - '![[CACHE:[0-9]+]] = !{i32 0, ![[CACHE_HINT:[0-9]+]]}'
+ ; CHECK-DAG: - '![[CACHE_HINT]] = !{!"cache", !"streaming"}'
+ ; CHECK: renamable $al = MOV8rm killed renamable $rdi, 1, $noreg, 0, $noreg, heap-alloc-marker ![[HEAP]], pcsections ![[PCSECTIONS]], mmra ![[MMRA]] :: (load (s8) from %ir.p, !noalias.addrspace ![[NOALIAS]], !range ![[RANGE]], !mem.cache_hint ![[CACHE]])
+ renamable $al = MOV8rm killed renamable $rdi, 1, $noreg, 0, $noreg, heap-alloc-marker !0, pcsections !1, mmra !2 :: (load (s8) from %ir.p, !noalias.addrspace !3, !range !4, !mem.cache_hint !5)
+ RET64 implicit killed $al
+...
diff --git a/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir b/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
index 8eb1e2a44c17d..4b1ba5cf159c1 100644
--- a/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
+++ b/llvm/test/CodeGen/MIR/X86/machine-metadata-specialized.mir
@@ -18,12 +18,22 @@ machineMetadataNodes:
- '!6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)'
- '!7 = !{}'
- '!8 = !DILocalVariable(name: "x", scope: !1, file: !2, line: 1, type: !5)'
+ - '!9 = !DILocalVariable(name: "y", scope: !1, file: !2, line: 2, type: !5)'
+ - '!10 = !DILocation(line: 2, scope: !1)'
+entry_values:
+ - { entry-value-register: '$rax', debug-info-variable: '!9', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1)',
+ debug-info-location: '!10' }
+# CHECK: entry_values:
+# CHECK: - { entry-value-register: '$rax', debug-info-variable: '![[ENTRY_VAR:[0-9]+]]', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1)',
+# CHECK: debug-info-location: '![[ENTRY_LOC:[0-9]+]]' }
body: |
bb.0:
; CHECK: machineMetadataNodes:
; CHECK-DAG: - '![[LOC:[0-9]+]] = !DILocation(line: 1, scope: ![[SP:[0-9]+]])'
; CHECK-DAG: - '![[SP]] = distinct !DISubprogram(name: "test"
; CHECK-DAG: - '![[VAR:[0-9]+]] = !DILocalVariable(name: "x", scope: ![[SP]]
+ ; CHECK-DAG: - '![[ENTRY_VAR]] = !DILocalVariable(name: "y", scope: ![[SP]]
+ ; CHECK-DAG: - '![[ENTRY_LOC]] = !DILocation(line: 2, scope: ![[SP]])'
; CHECK: DBG_VALUE $rax, $noreg, ![[VAR]], !DIExpression(), debug-location ![[LOC]]
DBG_VALUE $rax, $noreg, !8, !DIExpression(), debug-location !0
RET 0
diff --git a/llvm/unittests/IR/ModuleTest.cpp b/llvm/unittests/IR/ModuleTest.cpp
index d5b06e85128b7..82e652aadc013 100644
--- a/llvm/unittests/IR/ModuleTest.cpp
+++ b/llvm/unittests/IR/ModuleTest.cpp
@@ -447,6 +447,60 @@ define void @Foo2() {
ASSERT_EQ(M2Str, M1Print);
}
+TEST(ModuleTest, RenumberMetadataPreservesContextWideUniqueIDs) {
+ LLVMContext Context;
+ Module M("M", Context);
+ MDNode *Detached =
+ MDNode::getDistinct(Context, MDString::get(Context, "detached"));
+ MDNode *Attached =
+ MDNode::getDistinct(Context, MDString::get(Context, "attached"));
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("n");
+ NMD->addOperand(Attached);
+
+ M.renumberMetadataForAssembly();
+ NMD->addOperand(Detached);
+
+ std::string Assembly;
+ raw_string_ostream OS(Assembly);
+ M.print(OS, nullptr);
+ EXPECT_NE(Assembly.find("!n = !{!0, !2}"), std::string::npos);
+
+ LLVMContext ParsedContext;
+ SMDiagnostic Err;
+ EXPECT_TRUE(parseAssemblyString(Assembly, Err, ParsedContext))
+ << Err.getMessage().str();
+}
+
+TEST(ModuleTest, RenumberMetadataPreservesUniqueTemporaryIDs) {
+ LLVMContext Context;
+ Module M("M", Context);
+ TempMDTuple DetachedA =
+ MDTuple::getTemporary(Context, MDString::get(Context, "detached-a"));
+ TempMDTuple DetachedB =
+ MDTuple::getTemporary(Context, MDString::get(Context, "detached-b"));
+ MDNode *AttachedA =
+ MDNode::getDistinct(Context, MDString::get(Context, "attached-a"));
+ MDNode *AttachedB =
+ MDNode::getDistinct(Context, MDString::get(Context, "attached-b"));
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("n");
+ NMD->addOperand(AttachedA);
+ NMD->addOperand(AttachedB);
+
+ M.renumberMetadataForAssembly();
+ NMD->addOperand(MDNode::replaceWithDistinct(std::move(DetachedA)));
+ NMD->addOperand(MDNode::replaceWithDistinct(std::move(DetachedB)));
+
+ std::string Assembly;
+ raw_string_ostream OS(Assembly);
+ M.print(OS, nullptr);
+ EXPECT_NE(Assembly.find("!n = !{!0, !1, !4, !5}"), std::string::npos);
+
+ LLVMContext ParsedContext;
+ SMDiagnostic Err;
+ EXPECT_TRUE(parseAssemblyString(Assembly, Err, ParsedContext))
+ << Err.getMessage().str();
+}
+
TEST(ModuleTest, FunctionDefinitions) {
// Test getFunctionDefs() method which returns only functions with bodies
LLVMContext Context;
More information about the Mlir-commits
mailing list