From ae5224d468f8e4ebe8d1f72bfee8bcc4c36806db Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 9 Dec 2014 23:04:59 +0000 Subject: [PATCH] IR: Metadata: Detect an RAUW recursion Speculatively handle a recursion in `GenericMDNode::handleChangedOperand()`. I'm hoping this fixes the failing hexagon bot [1]. [1]: http://lab.llvm.org:8011/builders/llvm-hexagon-elf/builds/13434 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223849 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Metadata.h | 5 +++-- lib/IR/Metadata.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index ffdd7002cea..573e49fbb06 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -49,6 +49,7 @@ class Metadata { protected: /// \brief Storage flag for non-uniqued, otherwise unowned, metadata. bool IsDistinctInContext : 1; + bool InRAUW : 1; // TODO: expose remaining bits to subclasses. unsigned short SubclassData16; @@ -65,8 +66,8 @@ public: protected: Metadata(unsigned ID) - : SubclassID(ID), IsDistinctInContext(false), SubclassData16(0), - SubclassData32(0) {} + : SubclassID(ID), IsDistinctInContext(false), InRAUW(false), + SubclassData16(0), SubclassData32(0) {} ~Metadata() {} /// \brief Store this in a big non-uniqued untyped bucket. diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index 805b7377bce..7a354c42c4c 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -495,6 +495,14 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { setOperand(Op, New); return; } + if (InRAUW) { + // We just hit a recursion due to RAUW. Set the operand and move on, since + // we're about to be deleted. + // + // FIXME: Can this cycle really happen? + setOperand(Op, New); + return; + } auto &Store = getContext().pImpl->MDNodeSet; Store.erase(this); @@ -550,6 +558,7 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { // Collision. if (!isResolved()) { // Still unresolved, so RAUW. + InRAUW = true; ReplaceableUses->replaceAllUsesWith(*I); delete this; return;