[llvm] Reapply "[IR] `replaceUsesWith` when aliasing a GV and the use is `dso_local_equivalent`" (#220450) (PR #222036)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 08:46:16 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Mircea Trofin (mtrofin)

<details>
<summary>Changes</summary>

This reverts commit 751ed7b16433d2279286d0765f51cd36edc6d771.

The patch is quite indepdendent from PR #<!-- -->203171, which uncovered the issue. We decouple them. The fix is tested in the unittest introduced here. When we reland #<!-- -->203171, we'll add the cfi_dso_local_equivalent.ll test.

---
Full diff: https://github.com/llvm/llvm-project/pull/222036.diff


2 Files Affected:

- (modified) llvm/lib/IR/Constants.cpp (+9-16) 
- (modified) llvm/unittests/IR/ConstantsTest.cpp (+22) 


``````````diff
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 675cdaf6f1689..5b56a0008b1d1 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -2130,34 +2130,27 @@ Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {
   assert(From == getGlobalValue() && "Changing value does not match operand.");
   assert(isa<Constant>(To) && "Can only replace the operands with a constant");
 
-  // The replacement is with another global value.
-  if (const auto *ToObj = dyn_cast<GlobalValue>(To)) {
-    if (DSOLocalEquivalent *NewEquiv =
-            getContext().pImpl->DSOLocalEquivalents.lookup(ToObj))
-      return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
-  }
-
   // If the argument is replaced with a null value, just replace this constant
   // with a null value.
   if (isa<ConstantPointerNull>(To))
     return To;
 
-  // The replacement could be a bitcast or an alias to another function. We can
-  // replace it with a bitcast to the dso_local_equivalent of that function.
-  auto *Func = cast<Function>(To->stripPointerCastsAndAliases());
+  // The replacement could be a bitcast to another GlobalValue. We can
+  // replace it with a bitcast to the dso_local_equivalent of that GV.
+  GlobalValue *GV = cast<GlobalValue>(To->stripPointerCasts());
   if (DSOLocalEquivalent *NewEquiv =
-          getContext().pImpl->DSOLocalEquivalents.lookup(Func))
+          getContext().pImpl->DSOLocalEquivalents.lookup(GV))
     return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
 
-  // erase invalidates iterators/references, hence the duplicate Func lookup.
+  // erase invalidates iterators/references, hence the duplicate GV lookup.
   getContext().pImpl->DSOLocalEquivalents.erase(getGlobalValue());
-  getContext().pImpl->DSOLocalEquivalents[Func] = this;
-  setOperand(0, Func);
+  getContext().pImpl->DSOLocalEquivalents[GV] = this;
+  setOperand(0, GV);
 
-  if (Func->getType() != getType()) {
+  if (GV->getType() != getType()) {
     // It is ok to mutate the type here because this constant should always
     // reflect the type of the function it's holding.
-    mutateType(Func->getType());
+    mutateType(GV->getType());
   }
   return nullptr;
 }
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 6716ec581bd06..c484eb4d920c2 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -376,6 +376,28 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
   ASSERT_EQ(GEP->getOperand(0), Alias);
 }
 
+TEST(ConstantsTest, DSOLocalEquivalentReplaceWithAlias) {
+  LLVMContext Context;
+  std::unique_ptr<Module> M(new Module("MyModule", Context));
+
+  Type *VoidTy = Type::getVoidTy(Context);
+  FunctionType *FTy = FunctionType::get(VoidTy, false);
+  Function *F =
+      Function::Create(FTy, GlobalValue::InternalLinkage, "f", M.get());
+  auto *Equiv = DSOLocalEquivalent::get(F);
+
+  GlobalVariable *Ref = new GlobalVariable(*M, Equiv->getType(), false,
+                                           GlobalValue::ExternalLinkage, Equiv);
+  ASSERT_EQ(Equiv, Ref->getInitializer());
+
+  auto *Alias = GlobalAlias::create(FTy, 0, GlobalValue::ExternalLinkage,
+                                    "alias", F, M.get());
+  F->replaceAllUsesWith(Alias);
+
+  auto *NewEquiv = cast<DSOLocalEquivalent>(Ref->getInitializer());
+  ASSERT_EQ(NewEquiv->getGlobalValue(), Alias);
+}
+
 TEST(ConstantsTest, AliasCAPI) {
   LLVMContext Context;
   SMDiagnostic Error;

``````````

</details>


https://github.com/llvm/llvm-project/pull/222036


More information about the llvm-commits mailing list