From 3408708548035aa0063fbf2d14915a6fdf267ba2 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Thu, 8 Jan 2015 22:42:30 +0000 Subject: [PATCH] Utils: Keep distinct MDNodes distinct in MapMetadata() Create new copies of distinct `MDNode`s instead of following the uniquing `MDNode` logic. Just like self-references (or other cycles), `MapMetadata()` creates a new node. In practice most calls use `RF_NoModuleLevelChanges`, in which case nothing is duplicated anyway. Part of PR22111. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225476 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/ValueMapper.cpp | 14 +++++++++++ test/Linker/Inputs/distinct.ll | 13 ++++++++++ test/Linker/distinct.ll | 37 ++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 test/Linker/Inputs/distinct.ll create mode 100644 test/Linker/distinct.ll diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index a2eb1a07253..064cc575548 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -212,6 +212,20 @@ static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM, if (Flags & RF_NoModuleLevelChanges) return mapToSelf(VM, MD); + // Distinct nodes are always recreated. + if (Node->isDistinct()) { + // Create the node first so it's available for cyclical references. + SmallVector EmptyOps(Node->getNumOperands()); + MDNode *NewMD = MDNode::getDistinct(Node->getContext(), EmptyOps); + mapToMetadata(VM, Node, NewMD); + + // Fix the operands. + for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) + NewMD->replaceOperandWith(I, getMappedOp(Node->getOperand(I))); + + return NewMD; + } + // Create a dummy node in case we have a metadata cycle. MDNodeFwdDecl *Dummy = MDNode::getTemporary(Node->getContext(), None); mapToMetadata(VM, Node, Dummy); diff --git a/test/Linker/Inputs/distinct.ll b/test/Linker/Inputs/distinct.ll new file mode 100644 index 00000000000..07ae224d28a --- /dev/null +++ b/test/Linker/Inputs/distinct.ll @@ -0,0 +1,13 @@ +@global = linkonce global i32 0 + +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} + +!0 = !{} +!1 = !{!0} +!2 = !{i32* @global} +!3 = distinct !{} +!4 = distinct !{!0} +!5 = distinct !{i32* @global} +!6 = !{!3} +!7 = !{!4} +!8 = !{!5} diff --git a/test/Linker/distinct.ll b/test/Linker/distinct.ll new file mode 100644 index 00000000000..c8e5c89eb09 --- /dev/null +++ b/test/Linker/distinct.ll @@ -0,0 +1,37 @@ +; RUN: llvm-link %s %S/Inputs/distinct.ll -o - -S | FileCheck %s + +; Test that distinct nodes from other modules remain distinct. The @global +; cases are the most interesting, since the operands actually need to be +; remapped. + +; CHECK: @global = linkonce global i32 0 +@global = linkonce global i32 0 + +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !0, !1, !2, !9, !10, !11, !12, !13, !14} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} + +; CHECK: !0 = !{} +; CHECK-NEXT: !1 = !{!0} +; CHECK-NEXT: !2 = !{i32* @global} +; CHECK-NEXT: !3 = distinct !{} +; CHECK-NEXT: !4 = distinct !{!0} +; CHECK-NEXT: !5 = distinct !{i32* @global} +; CHECK-NEXT: !6 = !{!3} +; CHECK-NEXT: !7 = !{!4} +; CHECK-NEXT: !8 = !{!5} +; CHECK-NEXT: !9 = distinct !{} +; CHECK-NEXT: !10 = distinct !{!0} +; CHECK-NEXT: !11 = distinct !{i32* @global} +; CHECK-NEXT: !12 = !{!9} +; CHECK-NEXT: !13 = !{!10} +; CHECK-NEXT: !14 = !{!11} +; CHECK-NOT: ! +!0 = !{} +!1 = !{!0} +!2 = !{i32* @global} +!3 = distinct !{} +!4 = distinct !{!0} +!5 = distinct !{i32* @global} +!6 = !{!3} +!7 = !{!4} +!8 = !{!5} -- 2.34.1