summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/IR/MetadataTest.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 19:13:46 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 19:13:46 +0000
commit4ee4a98eaae16bbf9041acd3bc0f605b03d196e2 (patch)
treed96a528b2f7d05c661b4ebd3084552754202c905 /llvm/unittests/IR/MetadataTest.cpp
parent82f1c775a074feaa724948cbc1795336deaa2b4f (diff)
downloadbcm5719-llvm-4ee4a98eaae16bbf9041acd3bc0f605b03d196e2.tar.gz
bcm5719-llvm-4ee4a98eaae16bbf9041acd3bc0f605b03d196e2.zip
IR: Add MDNode::replaceWithPermanent()
Add new API for converting temporaries that may self-reference. Self-referencing nodes are not allowed to be uniqued, so sending them into `replaceWithUniqued()` is dangerous (and this commit adds assertions that prevent it). `replaceWithPermanent()` has similar semantics to `get()` followed by calls to `replaceOperandWith()`. In particular, if there's a self-reference, it returns a distinct node; otherwise, it returns a uniqued one. Like `replaceWithUniqued()` and `replaceWithDistinct()` (well, it calls out to them) it mutates the temporary node in place if possible, only calling `replaceAllUsesWith()` on a uniquing collision. llvm-svn: 228726
Diffstat (limited to 'llvm/unittests/IR/MetadataTest.cpp')
-rw-r--r--llvm/unittests/IR/MetadataTest.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 9bc8164dd48..e8e6d68c5fa 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -518,6 +518,44 @@ TEST_F(MDNodeTest, replaceWithDistinct) {
}
}
+TEST_F(MDNodeTest, replaceWithPermanent) {
+ Metadata *Ops[] = {nullptr};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ auto *T = Temp.get();
+
+ // U is a normal, uniqued node that references T.
+ auto *U = MDTuple::get(Context, T);
+ EXPECT_TRUE(U->isUniqued());
+
+ // Make Temp self-referencing.
+ Temp->replaceOperandWith(0, T);
+
+ // Try to uniquify Temp. This should, despite the name in the API, give a
+ // 'distinct' node, since self-references aren't allowed to be uniqued.
+ //
+ // Since it's distinct, N should have the same address as when it was a
+ // temporary (i.e., be equal to T not U).
+ auto *N = MDNode::replaceWithPermanent(std::move(Temp));
+ EXPECT_EQ(N, T);
+ EXPECT_TRUE(N->isDistinct());
+
+ // U should be the canonical unique node with N as the argument.
+ EXPECT_EQ(U, MDTuple::get(Context, N));
+ EXPECT_TRUE(U->isUniqued());
+
+ // This temporary should collide with U when replaced, but it should still be
+ // uniqued.
+ EXPECT_EQ(U, MDNode::replaceWithPermanent(MDTuple::getTemporary(Context, N)));
+ EXPECT_TRUE(U->isUniqued());
+
+ // This temporary should become a new uniqued node.
+ auto Temp2 = MDTuple::getTemporary(Context, U);
+ auto *V = Temp2.get();
+ EXPECT_EQ(V, MDNode::replaceWithPermanent(std::move(Temp2)));
+ EXPECT_TRUE(V->isUniqued());
+ EXPECT_EQ(U, V->getOperand(0));
+}
+
TEST_F(MDNodeTest, deleteTemporaryWithTrackingRef) {
TrackingMDRef Ref;
EXPECT_EQ(nullptr, Ref.get());
OpenPOWER on IntegriCloud