Skip to content

Commit 0ace96c

Browse files
authored
[SCCP][FuncSpec] Poison unreachable constant global variable user (#155753)
Fixes #155738. The original assumption "we already replaced its users with a constant" for the global variable becomes incorrect after #154668. The users in the dead function are not simplified, in fact. This patch poisons all the unsimplified constant global variable users.
1 parent 78b45b4 commit 0ace96c

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

llvm/lib/Transforms/IPO/SCCP.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,15 @@ static bool runIPSCCP(
330330
LLVM_DEBUG(dbgs() << "Found that GV '" << GV->getName()
331331
<< "' is constant!\n");
332332
for (User *U : make_early_inc_range(GV->users())) {
333-
// We can remove LoadInst here, because we already replaced its users
334-
// with a constant.
333+
// We can remove LoadInst here. The LoadInsts in dead functions marked by
334+
// FuncSpec are not simplified to constants, thus poison them.
335335
assert((isa<StoreInst>(U) || isa<LoadInst>(U)) &&
336336
"Only Store|Load Instruction can be user of GlobalVariable at "
337337
"reaching here.");
338-
cast<Instruction>(U)->eraseFromParent();
338+
Instruction *I = cast<Instruction>(U);
339+
if (isa<LoadInst>(I))
340+
I->replaceAllUsesWith(PoisonValue::get(I->getType()));
341+
I->eraseFromParent();
339342
}
340343

341344
// Try to create a debug constant expression for the global variable
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=ipsccp --funcspec-min-function-size=1 -S < %s | FileCheck %s
3+
4+
@gv = internal global ptr null
5+
6+
define i8 @caller() {
7+
; CHECK-LABEL: define i8 @caller() {
8+
; CHECK-NEXT: [[ENTRY:.*:]]
9+
; CHECK-NEXT: [[CALL1:%.*]] = call i8 @callee.specialized.1(i32 1)
10+
; CHECK-NEXT: [[CALL2:%.*]] = call i8 @callee.specialized.2(i32 0)
11+
; CHECK-NEXT: ret i8 undef
12+
;
13+
entry:
14+
%call1 = call i8 @callee(i32 1)
15+
%call2 = call i8 @callee(i32 0)
16+
ret i8 %call2
17+
}
18+
19+
define internal i8 @callee(i32 %arg) {
20+
entry:
21+
%useless = icmp ne i32 %arg, 0
22+
br label %loop
23+
24+
loop: ; preds = %loop, %entry
25+
br label %loop
26+
27+
dead_bb: ; No predecessors!
28+
%l1 = load ptr, ptr @gv, align 8
29+
%l2 = load ptr, ptr %l1, align 8
30+
ret i8 0
31+
}

0 commit comments

Comments
 (0)