diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-03-31 20:50:50 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-03-31 20:50:50 +0000 |
commit | cb33d6f5467653c1b74162c788e4ddbf3c987fb1 (patch) | |
tree | 4e33500f5695a9407bbf3e3709507476b4eb410f /llvm/unittests/IR | |
parent | 95e38baa525f50ab8e3a5db82e1f22ef78e5af14 (diff) | |
download | bcm5719-llvm-cb33d6f5467653c1b74162c788e4ddbf3c987fb1.tar.gz bcm5719-llvm-cb33d6f5467653c1b74162c788e4ddbf3c987fb1.zip |
IR: Enable uniquing callbacks during MDNode::replaceWithUniqued()
Uniqued nodes have more complete registration with
`ReplaceableMetadataImpl` so that they can update themselves when
operands change. Fix a bug where `MDNode::replaceWithUniqued()` wasn't
enabling these callbacks.
The two most obvious ways missing callbacks causes problems is that
auto-resolution fails and re-uniquing (on changed operands) just doesn't
happen. I've added tests for both -- in both cases, I confirmed that
the final check was failing before the fix.
rdar://problem/20365935
llvm-svn: 233751
Diffstat (limited to 'llvm/unittests/IR')
-rw-r--r-- | llvm/unittests/IR/MetadataTest.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 655551af9d8..270349e226a 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -627,6 +627,48 @@ TEST_F(MDNodeTest, replaceWithUniqued) { } } +TEST_F(MDNodeTest, replaceWithUniquedUnresolved) { + // temp !{} + MDTuple *Op = MDTuple::getTemporary(Context, None).release(); + EXPECT_FALSE(Op->isResolved()); + + // temp !{temp !{}} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); + EXPECT_FALSE(N->isResolved()); + + // temp !{temp !{}} => !{temp !{}} + ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); + EXPECT_FALSE(N->isResolved()); + + // !{temp !{}} => !{!{}} + ASSERT_EQ(Op, MDNode::replaceWithUniqued(TempMDTuple(Op))); + EXPECT_TRUE(Op->isResolved()); + EXPECT_TRUE(N->isResolved()); +} + +TEST_F(MDNodeTest, replaceWithUniquedUnresolvedChangedOperand) { + // i1* @GV + Type *Ty = Type::getInt1PtrTy(Context); + std::unique_ptr<GlobalVariable> GV( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); + + // temp !{i1* @GV} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); + + // temp !{i1* @GV} => !{i1* @GV} + ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); + ASSERT_TRUE(N->isUniqued()); + + // !{i1* @GV} => !{null} + GV.reset(); + ASSERT_TRUE(N->isUniqued()); + Metadata *NullOps[] = {nullptr}; + ASSERT_EQ(N, MDTuple::get(Context, NullOps)); +} + TEST_F(MDNodeTest, replaceWithDistinct) { { auto *Empty = MDTuple::get(Context, None); |