git: f30188c4680a - main - Merge commit 9f85bc834b07 from llvm-project (by Nikita Popov):

From: Dimitry Andric <dim_at_FreeBSD.org>
Date: Thu, 30 May 2024 15:35:43 UTC
The branch main has been updated by dim:

URL: https://cgit.FreeBSD.org/src/commit/?id=f30188c4680a85126e793de157b851bf5ee47529

commit f30188c4680a85126e793de157b851bf5ee47529
Author:     Dimitry Andric <dim@FreeBSD.org>
AuthorDate: 2024-05-30 15:35:15 +0000
Commit:     Dimitry Andric <dim@FreeBSD.org>
CommitDate: 2024-05-30 15:35:15 +0000

    Merge commit 9f85bc834b07 from llvm-project (by Nikita Popov):
    
      [PPCMergeStringPool] Only replace constant once (#92996)
    
      In #88846 I changed this code to use RAUW to perform the replacement
      instead of manual updates -- but kept the outer loop, which means we try
      to perform RAUW once per user. However, some of the users might be freed
      by the RAUW operation, resulting in use-after-free.
    
      The case where this happens is constant users where the replacement
      might result in the destruction of the original constant.
    
      Fixes https://github.com/llvm/llvm-project/issues/92991.
    
    This fixes a possible crash when building crypto/openssh/sshkey.c for
    PowerPC targets.
    
    Reported by:    cperciva
    PR:             276104
    MFC after:      3 days
---
 .../llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp | 37 ++++------------------
 1 file changed, 7 insertions(+), 30 deletions(-)

diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
index ebd876d50c44..0830b02370cd 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
@@ -290,13 +290,6 @@ bool PPCMergeStringPool::mergeModuleStringPool(Module &M) {
   return true;
 }
 
-static bool userHasOperand(User *TheUser, GlobalVariable *GVOperand) {
-  for (Value *Op : TheUser->operands())
-    if (Op == GVOperand)
-      return true;
-  return false;
-}
-
 // For pooled strings we need to add the offset into the pool for each string.
 // This is done by adding a Get Element Pointer (GEP) before each user. This
 // function adds the GEP.
@@ -307,29 +300,13 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
   Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), 0));
   Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
 
-  // Need to save a temporary copy of each user list because we remove uses
-  // as we replace them.
-  SmallVector<User *> Users;
-  for (User *CurrentUser : GlobalToReplace->users())
-    Users.push_back(CurrentUser);
-
-  for (User *CurrentUser : Users) {
-    // The user was not found so it must have been replaced earlier.
-    if (!userHasOperand(CurrentUser, GlobalToReplace))
-      continue;
-
-    // We cannot replace operands in globals so we ignore those.
-    if (isa<GlobalValue>(CurrentUser))
-      continue;
-
-    Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
-        PooledStructType, GPool, Indices);
-    LLVM_DEBUG(dbgs() << "Replacing this global:\n");
-    LLVM_DEBUG(GlobalToReplace->dump());
-    LLVM_DEBUG(dbgs() << "with this:\n");
-    LLVM_DEBUG(ConstGEP->dump());
-    GlobalToReplace->replaceAllUsesWith(ConstGEP);
-  }
+  Constant *ConstGEP =
+      ConstantExpr::getInBoundsGetElementPtr(PooledStructType, GPool, Indices);
+  LLVM_DEBUG(dbgs() << "Replacing this global:\n");
+  LLVM_DEBUG(GlobalToReplace->dump());
+  LLVM_DEBUG(dbgs() << "with this:\n");
+  LLVM_DEBUG(ConstGEP->dump());
+  GlobalToReplace->replaceAllUsesWith(ConstGEP);
 }
 
 } // namespace