[llvm] r224146 - IR: Don't track nullptr on metadata RAUW

Duncan P. N. Exon Smith dexonsmith at apple.com
Fri Dec 12 15:27:36 PST 2014


No problem, that's what I figured :).

I actually spent a long time trying to reduce an IR testcase or
construct one from scratch, when I suddenly realized it was trivial
to expose via API and went that route instead.

> On 2014 Dec 12, at 15:24, Philip Reames <listmail at philipreames.com> wrote:
> 
> Oops, sorry.  I was expecting an IR file and didn't read closely enough.
> 
> On 12/12/2014 02:57 PM, Duncan P. N. Exon Smith wrote:
>> See: unittests/IR/MetadataTest.cpp
>> 
>>> On 2014 Dec 12, at 14:54, Philip Reames <listmail at philipreames.com> wrote:
>>> 
>>> Test case?
>>> 
>>> On 12/12/2014 11:24 AM, Duncan P. N. Exon Smith wrote:
>>>> Author: dexonsmith
>>>> Date: Fri Dec 12 13:24:33 2014
>>>> New Revision: 224146
>>>> 
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=224146&view=rev
>>>> Log:
>>>> IR: Don't track nullptr on metadata RAUW
>>>> 
>>>> The RAUW support in `Metadata` supports going to `nullptr` specifically
>>>> to handle values being deleted, causing `ValueAsMetadata` to be deleted.
>>>> 
>>>> Fix the case where the reference is from a `TrackingMDRef` (as opposed
>>>> to an `MDOperand` or a `MetadataAsValue`).
>>>> 
>>>> This is surprisingly rare -- metadata tracked by `TrackingMDRef` going
>>>> to null -- but it came up in an openSUSE bootstrap during inlining.  The
>>>> tracking ref was held by the `ValueMap` because it was referencing a
>>>> local, the basic block containing the local became dead after it had
>>>> been merged in, and when the local was deleted, the tracking ref
>>>> asserted in an `isa`.
>>>> 
>>>> Modified:
>>>>     llvm/trunk/lib/IR/Metadata.cpp
>>>>     llvm/trunk/unittests/IR/MetadataTest.cpp
>>>> 
>>>> Modified: llvm/trunk/lib/IR/Metadata.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=224146&r1=224145&r2=224146&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/IR/Metadata.cpp (original)
>>>> +++ llvm/trunk/lib/IR/Metadata.cpp Fri Dec 12 13:24:33 2014
>>>> @@ -173,7 +173,8 @@ void ReplaceableMetadataImpl::replaceAll
>>>>        // Update unowned tracking references directly.
>>>>        Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
>>>>        Ref = MD;
>>>> -      MetadataTracking::track(Ref);
>>>> +      if (MD)
>>>> +        MetadataTracking::track(Ref);
>>>>        UseMap.erase(Pair.first);
>>>>        continue;
>>>>      }
>>>> 
>>>> Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=224146&r1=224145&r2=224146&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
>>>> +++ llvm/trunk/unittests/IR/MetadataTest.cpp Fri Dec 12 13:24:33 2014
>>>> @@ -207,6 +207,53 @@ TEST_F(MetadataAsValueTest, MDNodeConsta
>>>>    EXPECT_EQ(V, V2);
>>>>  }
>>>>  +typedef MetadataTest ValueAsMetadataTest;
>>>> +
>>>> +TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
>>>> +  Type *Ty = Type::getInt1PtrTy(Context);
>>>> +  std::unique_ptr<GlobalVariable> GV0(
>>>> +      new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
>>>> +  auto *MD = ValueAsMetadata::get(GV0.get());
>>>> +  EXPECT_TRUE(MD->getValue() == GV0.get());
>>>> +  ASSERT_TRUE(GV0->use_empty());
>>>> +
>>>> +  std::unique_ptr<GlobalVariable> GV1(
>>>> +      new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
>>>> +  GV0->replaceAllUsesWith(GV1.get());
>>>> +  EXPECT_TRUE(MD->getValue() == GV1.get());
>>>> +}
>>>> +
>>>> +typedef MetadataTest TrackingMDRefTest;
>>>> +
>>>> +TEST_F(TrackingMDRefTest, UpdatesOnRAUW) {
>>>> +  Type *Ty = Type::getInt1PtrTy(Context);
>>>> +  std::unique_ptr<GlobalVariable> GV0(
>>>> +      new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
>>>> +  TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get()));
>>>> +  EXPECT_TRUE(MD->getValue() == GV0.get());
>>>> +  ASSERT_TRUE(GV0->use_empty());
>>>> +
>>>> +  std::unique_ptr<GlobalVariable> GV1(
>>>> +      new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
>>>> +  GV0->replaceAllUsesWith(GV1.get());
>>>> +  EXPECT_TRUE(MD->getValue() == GV1.get());
>>>> +
>>>> +  // Reset it, so we don't inadvertently test deletion.
>>>> +  MD.reset();
>>>> +}
>>>> +
>>>> +TEST_F(TrackingMDRefTest, UpdatesOnDeletion) {
>>>> +  Type *Ty = Type::getInt1PtrTy(Context);
>>>> +  std::unique_ptr<GlobalVariable> GV(
>>>> +      new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
>>>> +  TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get()));
>>>> +  EXPECT_TRUE(MD->getValue() == GV.get());
>>>> +  ASSERT_TRUE(GV->use_empty());
>>>> +
>>>> +  GV.reset();
>>>> +  EXPECT_TRUE(!MD);
>>>> +}
>>>> +
>>>>  TEST(NamedMDNodeTest, Search) {
>>>>    LLVMContext Context;
>>>>    ConstantAsMetadata *C =
>>>> 
>>>> 
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 





More information about the llvm-commits mailing list