Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7e6ece9

Browse files
nikicllvmbot
authored andcommitted
[PPCMergeStringPool] Only replace constant once (llvm#92996)
In llvm#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 llvm#92991. (cherry picked from commit 9f85bc8)
1 parent 1ce2d26 commit 7e6ece9

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp

+7-30
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,6 @@ bool PPCMergeStringPool::mergeModuleStringPool(Module &M) {
290290
return true;
291291
}
292292

293-
static bool userHasOperand(User *TheUser, GlobalVariable *GVOperand) {
294-
for (Value *Op : TheUser->operands())
295-
if (Op == GVOperand)
296-
return true;
297-
return false;
298-
}
299-
300293
// For pooled strings we need to add the offset into the pool for each string.
301294
// This is done by adding a Get Element Pointer (GEP) before each user. This
302295
// function adds the GEP.
@@ -307,29 +300,13 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
307300
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), 0));
308301
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
309302

310-
// Need to save a temporary copy of each user list because we remove uses
311-
// as we replace them.
312-
SmallVector<User *> Users;
313-
for (User *CurrentUser : GlobalToReplace->users())
314-
Users.push_back(CurrentUser);
315-
316-
for (User *CurrentUser : Users) {
317-
// The user was not found so it must have been replaced earlier.
318-
if (!userHasOperand(CurrentUser, GlobalToReplace))
319-
continue;
320-
321-
// We cannot replace operands in globals so we ignore those.
322-
if (isa<GlobalValue>(CurrentUser))
323-
continue;
324-
325-
Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
326-
PooledStructType, GPool, Indices);
327-
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
328-
LLVM_DEBUG(GlobalToReplace->dump());
329-
LLVM_DEBUG(dbgs() << "with this:\n");
330-
LLVM_DEBUG(ConstGEP->dump());
331-
GlobalToReplace->replaceAllUsesWith(ConstGEP);
332-
}
303+
Constant *ConstGEP =
304+
ConstantExpr::getInBoundsGetElementPtr(PooledStructType, GPool, Indices);
305+
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
306+
LLVM_DEBUG(GlobalToReplace->dump());
307+
LLVM_DEBUG(dbgs() << "with this:\n");
308+
LLVM_DEBUG(ConstGEP->dump());
309+
GlobalToReplace->replaceAllUsesWith(ConstGEP);
333310
}
334311

335312
} // namespace
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
3+
4+
@g = private constant [4 x i32] [i32 122, i32 67, i32 35, i32 56]
5+
@g2 = private constant [1 x i64] [i64 1], align 8
6+
7+
define void @test(ptr %p, ptr %p2) {
8+
; CHECK-LABEL: test:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: addis 5, 2, .L__ModuleStringPool@toc@ha
11+
; CHECK-NEXT: addi 5, 5, .L__ModuleStringPool@toc@l
12+
; CHECK-NEXT: addi 6, 5, 12
13+
; CHECK-NEXT: std 6, 0(3)
14+
; CHECK-NEXT: addi 3, 5, 16
15+
; CHECK-NEXT: std 3, 0(4)
16+
; CHECK-NEXT: blr
17+
store ptr getelementptr inbounds ([4 x i32], ptr @g, i64 0, i64 1), ptr %p
18+
store ptr getelementptr inbounds ([4 x i32], ptr @g, i64 0, i64 2), ptr %p2
19+
ret void
20+
}

0 commit comments

Comments
 (0)