From 706f37e8df7b9e18d3f17d18e938d02d0a4d3c47 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 4 Aug 2015 06:42:31 +0000 Subject: Linker: Fix references to uniqued nodes after r243883 r243883 started moving 'distinct' nodes instead of duplicated them in lib/Linker. This had the side-effect of sometimes not cloning uniqued nodes that reference them. I missed a corner case: !named = !{!0} !0 = !{!1} !1 = distinct !{!0} !0 is the entry point for "remapping", and a temporary clone (say, !0-temp) is created and mapped in case we need to model a uniquing cycle. Recursive descent into !1. !1 is distinct, so we leave it alone, but update its operand to !0-temp. Pop back out to !0. Its only operand, !1, hasn't changed, so we don't need to use !0-temp. !0-temp goes out of scope, and we're finished remapping, but we're left with: !named = !{!0} !0 = !{!1} !1 = distinct !{null} ; uh oh... Previously, if !0 and !0-temp ended up with identical operands, then !0-temp couldn't have been referenced at all. Now that distinct nodes don't get duplicated, that assumption is invalid. We need to !0-temp->replaceAllUsesWith(!0) before freeing !0-temp. I found this while running an internal `-flto -g` bootstrap. Strangely, there was no case of this in the open source bootstrap I'd done before commit... llvm-svn: 243961 --- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Transforms/Utils/ValueMapper.cpp') diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index d967e0a95c6..8aa546c7211 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -258,9 +258,11 @@ static Metadata *mapUniquedNode(const MDNode *Node, // Create a temporary node upfront in case we have a metadata cycle. auto ClonedMD = Node->clone(); - if (!remap(Node, ClonedMD.get(), Cycles, VM, Flags, TypeMapper, Materializer)) + if (!remap(Node, ClonedMD.get(), Cycles, VM, Flags, TypeMapper, Materializer)) { // No operands changed, so use the identity mapping. + ClonedMD->replaceAllUsesWith(const_cast(Node)); return mapToSelf(VM, Node); + } // At least one operand has changed, so uniquify the cloned node. return mapToMetadata(VM, Node, -- cgit v1.2.3