[llvm] aeefb10 - [IR] Simplify ValueAsMetadata::handleRAUW. NFC (#223301)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 23:35:54 PDT 2026


Author: Fangrui Song
Date: 2026-09-13T23:35:49-07:00
New Revision: aeefb10b01fb7cf11a1917230f10b663d5ec109b

URL: https://github.com/llvm/llvm-project/commit/aeefb10b01fb7cf11a1917230f10b663d5ec109b
DIFF: https://github.com/llvm/llvm-project/commit/aeefb10b01fb7cf11a1917230f10b663d5ec109b.diff

LOG: [IR] Simplify ValueAsMetadata::handleRAUW. NFC (#223301)

Metadata refers to a Value through its unique ValueAsMetadata wrapper.
When a Value is RAUW'd, handleRAUW reuses the old value's wrapper for
the new value if the new value has none yet; otherwise it moves the uses
to the new value's wrapper, with special cases for a local becoming a
constant, a constant becoming a local, and a value moving to another
function.

Always move the uses (or drop them in the last two cases) and delete the
old wrapper, so that a ValueAsMetadata wraps the same value for its
whole life.

Instruction counts for SLPVectorizer.cpp and X86ISelLowering.cpp at -O2
-g are unchanged (-0.04%, -0.01%).

Aided by Opus 5

Added: 
    

Modified: 
    llvm/lib/IR/Metadata.cpp
    llvm/unittests/IR/MetadataTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index fc03bf4a87eb1..87766f4d47437 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -551,15 +551,13 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
   assert(From != To && "Expected changed value");
   assert(&From->getContext() == &To->getContext() && "Expected same context");
 
-  LLVMContext &Context = From->getType()->getContext();
-  auto &Store = Context.pImpl->ValuesAsMetadata;
+  auto &Store = From->getContext().pImpl->ValuesAsMetadata;
   auto I = Store.find(From);
   if (I == Store.end()) {
     assert(!From->IsUsedByMD && "Expected From not to be used by metadata");
     return;
   }
 
-  // Remove old entry from the map.
   assert(From->IsUsedByMD && "Expected From to be used by metadata");
   From->IsUsedByMD = false;
   ValueAsMetadata *MD = I->second;
@@ -567,40 +565,19 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
   assert(MD->getValue() == From && "Expected valid mapping");
   Store.erase(I);
 
-  if (isa<LocalAsMetadata>(MD)) {
-    if (auto *C = dyn_cast<Constant>(To)) {
-      // Local became a constant.
-      MD->replaceAllUsesWith(ConstantAsMetadata::get(C));
-      delete MD;
-      return;
-    }
-    if (getLocalFunctionMetadata(From) && getLocalFunctionMetadata(To) &&
-        getLocalFunctionMetadata(From) != getLocalFunctionMetadata(To)) {
-      // DISubprogram changed.
-      MD->replaceAllUsesWith(nullptr);
-      delete MD;
-      return;
-    }
-  } else if (!isa<Constant>(To)) {
-    // Changed to function-local value.
-    MD->replaceAllUsesWith(nullptr);
-    delete MD;
-    return;
-  }
-
-  auto *&Entry = Store[To];
-  if (Entry) {
-    // The target already exists.
-    MD->replaceAllUsesWith(Entry);
-    delete MD;
-    return;
-  }
-
-  // Update MD in place (and update the map entry).
-  assert(!To->IsUsedByMD && "Expected this to be the only metadata use");
-  To->IsUsedByMD = true;
-  MD->V = To;
-  Entry = MD;
+  // Move the uses to To's node. Uses of a function-local value are dropped if
+  // it becomes a local of another function or replaces a constant.
+  Metadata *New = nullptr;
+  if (isa<Constant>(To)) {
+    New = ValueAsMetadata::get(To);
+  } else if (isa<LocalAsMetadata>(MD)) {
+    DISubprogram *FromSP = getLocalFunctionMetadata(From);
+    DISubprogram *ToSP = FromSP ? getLocalFunctionMetadata(To) : nullptr;
+    if (!FromSP || !ToSP || FromSP == ToSP)
+      New = ValueAsMetadata::get(To);
+  }
+  MD->replaceAllUsesWith(New);
+  delete MD;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index cb0096d8f4a2c..8edff02ca0b16 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -5209,9 +5209,12 @@ TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
   EXPECT_TRUE(MD->getValue() == GV0.get());
   ASSERT_TRUE(GV0->use_empty());
 
+  TrackingMDRef Ref(MD);
   std::unique_ptr<GlobalVariable> GV1(
       new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+  // RAUW updates `Ref`.
   GV0->replaceAllUsesWith(GV1.get());
+  MD = cast<ValueAsMetadata>(Ref.get());
   EXPECT_TRUE(MD->getValue() == GV1.get());
 }
 
@@ -5224,11 +5227,13 @@ TEST_F(ValueAsMetadataTest, handleRAUWWithTypeChange) {
   auto *I32Poison = PoisonValue::get(Type::getInt32Ty(Context));
   auto *I64Poison = PoisonValue::get(Type::getInt64Ty(Context));
   auto *MD = ConstantAsMetadata::get(I32Poison);
+  TrackingMDRef Ref(MD);
 
   EXPECT_EQ(MD->getValue(), I32Poison);
   EXPECT_NE(MD->getValue(), I64Poison);
 
   ValueAsMetadata::handleRAUW(I32Poison, I64Poison);
+  MD = cast<ConstantAsMetadata>(Ref.get());
 
   EXPECT_NE(MD->getValue(), I32Poison);
   EXPECT_EQ(MD->getValue(), I64Poison);


        


More information about the llvm-commits mailing list