llvm-project/llvm/unittests/IR
Duncan P. N. Exon Smith 9cbc69d1fe IR: Drop uniquing when an MDNode Value operand is deleted
This is a fix for PR28697.

An MDNode can indirectly refer to a GlobalValue, through a
ConstantAsMetadata.  When the GlobalValue is deleted, the MDNode operand
is reset to `nullptr`.  If the node is uniqued, this can lead to a
hard-to-detect cache invalidation in a Metadata map that's shared across
an LLVMContext.

Consider:

 1. A map from Metadata* to `T` called RemappedMDs.
 2. A node that references a global variable, `!{i1* @GV}`.
 3. Insert `!{i1* @GV} -> SomeT` in the map.
 4. Delete `@GV`, leaving behind `!{null} -> SomeT`.

Looking up the generic and uninteresting `!{null}` gives you `SomeT`,
which is likely related to `@GV`.  Worse, `SomeT`'s lifetime may be tied
to the deleted `@GV`.

This occurs in practice in the shared ValueMap used since r266579 in the
IRMover.  Other code that handles more than one Module (with different
lifetimes) in the same LLVMContext could hit it too.

The fix here is a partial revert of r225223: in the rare case that an
MDNode operand is a ConstantAsMetadata (i.e., wrapping a node from the
Value hierarchy), drop uniquing if it gets replaced with `nullptr`.
This changes step #4 above to leave behind `distinct !{null} -> SomeT`,
which can't be confused with the generic `!{null}`.

In theory, this can cause some churn in the LLVMContext's MDNode
uniquing map when Values are being deleted.  However:

  - The number of GlobalValues referenced from uniqued MDNodes is
    expected to be quite small.  E.g., the debug info metadata schema
    only references GlobalValues from distinct nodes.

  - Other Constants have the lifetime of the LLVMContext, whose teardown
    is careful to drop references before deleting the constants.

As a result, I don't expect a compile time regression from this change.

llvm-svn: 277625
2016-08-03 18:19:43 +00:00
..
AsmWriterTest.cpp Fix crash when printing instructions that have a metadata attached but no parent. 2016-01-07 20:14:30 +00:00
AttributesTest.cpp Fix non-determinism in order of LLVM attributes 2016-04-04 23:06:05 +00:00
CMakeLists.txt IR: LLVMContextTest => DebugTypeODRUniquingTest, NFC 2016-04-19 17:11:06 +00:00
ConstantRangeTest.cpp [ConstantRange] Add an getEquivalentICmp helper 2016-05-19 03:53:06 +00:00
ConstantsTest.cpp Fix constant folding of addrspacecast of null 2016-05-21 00:14:04 +00:00
DebugInfoTest.cpp IR: Give 'DI' prefix to debug info metadata 2015-04-29 16:38:44 +00:00
DebugTypeODRUniquingTest.cpp IR: Enable debug info type ODR uniquing for forward decls 2016-04-19 18:00:19 +00:00
DominatorTreeTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
FunctionTest.cpp Fix warnings in FunctionTest.cpp. 2016-07-13 18:17:46 +00:00
IRBuilderTest.cpp Remove some unused variables 2016-03-13 22:00:18 +00:00
InstructionsTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
IntrinsicsTest.cpp Handle more edge cases in intrinsic name binary search 2016-01-26 22:33:19 +00:00
LegacyPassManagerTest.cpp [NFC] Header cleanup 2016-04-18 09:17:29 +00:00
MDBuilderTest.cpp IR: Split Metadata from Value 2014-12-09 18:38:53 +00:00
MetadataTest.cpp IR: Drop uniquing when an MDNode Value operand is deleted 2016-08-03 18:19:43 +00:00
PassManagerTest.cpp [PM] Run clang-format over various parts of the new pass manager code 2016-06-17 07:15:29 +00:00
PatternMatch.cpp Remove PreserveNames template parameter from IRBuilder 2016-03-13 21:05:13 +00:00
TypeBuilderTest.cpp [NFC] Header cleanup 2016-04-18 09:17:29 +00:00
TypesTest.cpp Fix several accidental DOS line endings in source files 2016-01-03 17:22:03 +00:00
UseTest.cpp Format: Modernize using variadic templates. 2015-02-15 22:15:41 +00:00
UserTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
ValueHandleTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
ValueMapTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
ValueTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00
VerifierTest.cpp Port the strip-invalid-debuginfo logic to the legacy verifier pass, too. 2016-05-25 21:33:20 +00:00
WaymarkTest.cpp Remove every uses of getGlobalContext() in LLVM (but the C API) 2016-04-14 21:59:01 +00:00