Skip to content

Commit d9e764f

Browse files
committed
implement another approach
1 parent c97a6c6 commit d9e764f

File tree

11 files changed

+102
-109
lines changed

11 files changed

+102
-109
lines changed

llvm/include/llvm/Transforms/Scalar/JumpThreading.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
169169
bool processGuards(BasicBlock *BB);
170170
bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
171171

172+
// Determine unreachability with a possibly not up-to-date DominatorTree.
173+
// If BB is unreachable, return a list of BB and all its predecessors.
174+
// Otherwise, return an empty list.
175+
SmallVector<BasicBlock *, 32> unreachableFromBB(BasicBlock *BB,
176+
DomTreeUpdater *DTU);
177+
172178
private:
173179
BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
174180
const char *Suffix);

llvm/lib/IR/BasicBlock.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -556,14 +556,8 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
556556
if (NumPreds == 1)
557557
continue;
558558

559-
// Try to replace the PHI node with a constant value, but make sure that
560-
// this value isn't using the PHI node. (Except it's a PHI node itself. PHI
561-
// nodes are allowed to reference themselves.)
562-
if (Value *PhiConstant = Phi.hasConstantValue();
563-
PhiConstant &&
564-
(!isa<Instruction>(PhiConstant) || isa<PHINode>(PhiConstant) ||
565-
llvm::all_of(Phi.users(),
566-
[PhiConstant](User *U) { return U != PhiConstant; }))) {
559+
// Try to replace the PHI node with a constant value.
560+
if (Value *PhiConstant = Phi.hasConstantValue()) {
567561
Phi.replaceAllUsesWith(PhiConstant);
568562
Phi.eraseFromParent();
569563
}

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,19 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
335335
if (&BB == &F->getEntryBlock() || DTU->isBBPendingDeletion(&BB))
336336
continue;
337337

338-
if (pred_empty(&BB)) {
338+
if (SmallVector<BasicBlock *, 32> Unreachable =
339+
unreachableFromBB(&BB, DTU.get());
340+
!Unreachable.empty()) {
339341
// When processBlock makes BB unreachable it doesn't bother to fix up
340342
// the instructions in it. We must remove BB to prevent invalid IR.
341-
LLVM_DEBUG(dbgs() << " JT: Deleting dead block '" << BB.getName()
342-
<< "' with terminator: " << *BB.getTerminator()
343-
<< '\n');
344-
LoopHeaders.erase(&BB);
345-
LVI->eraseBlock(&BB);
346-
DeleteDeadBlock(&BB, DTU.get());
343+
for (BasicBlock *UBB : Unreachable) {
344+
LLVM_DEBUG(dbgs()
345+
<< " JT: Deleting dead block '" << UBB->getName()
346+
<< "' with terminator: " << *UBB->getTerminator() << '\n');
347+
LoopHeaders.erase(UBB);
348+
LVI->eraseBlock(UBB);
349+
}
350+
DeleteDeadBlocks(Unreachable, DTU.get());
347351
Changed = ChangedSinceLastAnalysisUpdate = true;
348352
continue;
349353
}
@@ -381,6 +385,26 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
381385
return EverChanged;
382386
}
383387

388+
SmallVector<BasicBlock *, 32>
389+
JumpThreadingPass::unreachableFromBB(BasicBlock *BB, DomTreeUpdater *DTU) {
390+
if (BB->isEntryBlock() || DTU->isBBPendingDeletion(BB))
391+
return {};
392+
393+
SmallVector<BasicBlock *, 32> Unreachable({BB});
394+
SmallPtrSet<BasicBlock *, 32> Seen({BB});
395+
396+
for (unsigned U = 0; U < Unreachable.size(); ++U) {
397+
for (BasicBlock *Pred : predecessors(Unreachable[U])) {
398+
if (Pred->isEntryBlock())
399+
return {};
400+
if (Seen.insert(Pred).second && !DTU->isBBPendingDeletion(Pred))
401+
Unreachable.push_back(Pred);
402+
}
403+
}
404+
405+
return Unreachable;
406+
}
407+
384408
// Replace uses of Cond with ToVal when safe to do so. If all uses are
385409
// replaced, we can remove Cond. We cannot blindly replace all uses of Cond
386410
// because we may incorrectly replace uses when guards/assumes are uses of

llvm/test/Transforms/JumpThreading/PR33357-lvi-recursion.ll

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -S -passes=jump-threading,verify -o - %s | FileCheck %s
23
@a = external global i16, align 1
34

4-
; CHECK-LABEL: f
5-
; CHECK: bb6:
6-
; CHECK: bb2:
7-
; CHECK: bb3:
8-
; CHECK-NOT: bb0:
9-
; CHECK-NOT: bb1:
10-
; CHECK-NOT: bb4:
11-
; CHECK-NOT: bb5:
125
define void @f(i32 %p1) {
6+
; CHECK-LABEL: define void @f(
7+
; CHECK-SAME: i32 [[P1:%.*]]) {
8+
; CHECK-NEXT: [[BB6:.*:]]
9+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[P1]], 0
10+
; CHECK-NEXT: ret void
11+
;
1312
bb0:
1413
%0 = icmp eq i32 %p1, 0
1514
br i1 true, label %bb6, label %bb1

llvm/test/Transforms/JumpThreading/ne-undef.ll

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,7 @@ declare i1 @cond()
55

66
define hidden void @hoge(i1 %c1, i32 %x) {
77
; CHECK-LABEL: @hoge(
8-
; CHECK-NEXT: bb:
9-
; CHECK-NEXT: br label [[BB13:%.*]]
10-
; CHECK: bb4:
11-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP7:%.*]], undef
12-
; CHECK-NEXT: br i1 [[TMP3]], label [[BB5:%.*]], label [[BB13]]
13-
; CHECK: bb5:
14-
; CHECK-NEXT: br label [[BB6:%.*]]
15-
; CHECK: bb6:
16-
; CHECK-NEXT: [[TMP7]] = phi i32 [ [[TMP7]], [[BB5]] ], [ [[X:%.*]], [[BB8:%.*]] ]
17-
; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
18-
; CHECK-NEXT: br i1 [[C]], label [[BB4:%.*]], label [[BB8]]
19-
; CHECK: bb8:
20-
; CHECK-NEXT: br label [[BB6]]
21-
; CHECK: bb13:
8+
; CHECK-NEXT: bb13:
229
; CHECK-NEXT: ret void
2310
;
2411
bb:

llvm/test/Transforms/JumpThreading/phi-xor-branch.ll

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,7 @@
55

66
define void @test() {
77
; CHECK-LABEL: @test(
8-
; CHECK-NEXT: entry:
9-
; CHECK-NEXT: br label [[EXIT:%.*]]
10-
; CHECK: loop:
11-
; CHECK-NEXT: [[DUMMY:%.*]] = phi i16 [ 0, [[LOOP:%.*]] ]
12-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 0, 1
13-
; CHECK-NEXT: [[XOR:%.*]] = xor i1 false, [[XOR]]
14-
; CHECK-NEXT: br i1 [[XOR]], label [[LOOP]], label [[EXIT]]
15-
; CHECK: exit:
8+
; CHECK-NEXT: exit:
169
; CHECK-NEXT: ret void
1710
;
1811
entry:

llvm/test/Transforms/JumpThreading/pr62908.ll

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,7 @@
55

66
define i32 @test() {
77
; CHECK-LABEL: define i32 @test() {
8-
; CHECK-NEXT: join.thread:
9-
; CHECK-NEXT: br label [[END:%.*]]
10-
; CHECK: unreachable:
11-
; CHECK-NEXT: [[SH_PROM:%.*]] = zext i32 -1 to i64
12-
; CHECK-NEXT: [[SHL:%.*]] = shl nsw i64 -1, [[SH_PROM]]
13-
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SHL]] to i32
14-
; CHECK-NEXT: br label [[JOIN:%.*]]
15-
; CHECK: join:
16-
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[CONV]], [[UNREACHABLE:%.*]] ]
17-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[PHI]], 0
18-
; CHECK-NEXT: br i1 [[CMP]], label [[END]], label [[END]]
19-
; CHECK: end:
8+
; CHECK-NEXT: end:
209
; CHECK-NEXT: ret i32 0
2110
;
2211
entry:

llvm/test/Transforms/JumpThreading/pr9331.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ define void @func(i8 zeroext %p_44) nounwind {
55
; CHECK-LABEL: @func(
66
; CHECK-NEXT: return:
77
; CHECK-NEXT: ret void
8-
; CHECK: for.inc46:
9-
; CHECK-NEXT: br label [[FOR_INC46:%.*]]
108
;
119
entry:
1210
br i1 false, label %for.cond2, label %if.end50

llvm/test/Transforms/JumpThreading/preserving-debugloc-br.ll

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
23

3-
; @process_block_branch checks that JumpThreading's processBlock() propagates
4+
; @process_block_branch checks that JumpThreading's processBlock() propagates
45
; the debug location to the new branch instruction.
56

67
; @process_threadable_edges_branch checks that JumpThreading's processThreadableEdges()
78
; propagates the debug location to the new branch instruction.
89

910
define i32 @process_block_branch(i32 %action) #0 !dbg !5 {
1011
; CHECK-LABEL: define i32 @process_block_branch(
11-
; CHECK: for.cond:
12-
; CHECK-NEXT: br label %for.cond, !dbg [[DBG10:![0-9]+]]
12+
; CHECK-SAME: i32 [[ACTION:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG5:![0-9]+]] {
13+
; CHECK-NEXT: [[ENTRY:.*:]]
14+
; CHECK-NEXT: switch i32 [[ACTION]], label %[[IF_THEN:.*]] [
15+
; CHECK-NEXT: i32 1, label %[[IF_THEN]]
16+
; CHECK-NEXT: i32 0, label %[[IF_THEN]]
17+
; CHECK-NEXT: ], !dbg [[DBG8:![0-9]+]]
18+
; CHECK: [[IF_THEN]]:
19+
; CHECK-NEXT: ret i32 undef, !dbg [[DBG9:![0-9]+]]
1320
;
1421
entry:
1522
switch i32 %action, label %lor.rhs [
@@ -35,8 +42,18 @@ for.body: ; preds = %for.cond
3542

3643
define void @process_threadable_edges_branch(i32 %value) #0 !dbg !15 {
3744
; CHECK-LABEL: define void @process_threadable_edges_branch(
38-
; CHECK: L0:
39-
; CHECK: br label %L2, !dbg [[DBG17:![0-9]+]]
45+
; CHECK-SAME: i32 [[VALUE:%.*]]) #[[ATTR0]] !dbg [[DBG10:![0-9]+]] {
46+
; CHECK-NEXT: [[ENTRY:.*:]]
47+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VALUE]], 32, !dbg [[DBG11:![0-9]+]]
48+
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[VALUE]], 64, !dbg [[DBG12:![0-9]+]]
49+
; CHECK-NEXT: br i1 [[CMP]], label %[[L0:.*]], label %[[L2:.*]], !dbg [[DBG13:![0-9]+]]
50+
; CHECK: [[L0]]:
51+
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f2(), !dbg [[DBG14:![0-9]+]]
52+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f2(), !dbg [[DBG15:![0-9]+]]
53+
; CHECK-NEXT: br label %[[L2]], !dbg [[DBG16:![0-9]+]]
54+
; CHECK: [[L2]]:
55+
; CHECK-NEXT: call void @f4(i32 [[ADD]]), !dbg [[DBG17:![0-9]+]]
56+
; CHECK-NEXT: ret void, !dbg [[DBG18:![0-9]+]]
4057
;
4158
entry:
4259
%cmp = icmp eq i32 %value, 32, !dbg !16
@@ -78,10 +95,6 @@ attributes #0 = { nounwind }
7895
!llvm.debugify = !{!2, !3}
7996
!llvm.module.flags = !{!4}
8097

81-
;.
82-
; CHECK: [[DBG10]] = !DILocation(line: 6,
83-
; CHECK: [[DBG17]] = !DILocation(line: 13,
84-
;.
8598

8699
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
87100
!1 = !DIFile(filename: "temp.ll", directory: "/")
@@ -111,3 +124,21 @@ attributes #0 = { nounwind }
111124
!25 = !DILocation(line: 17, column: 1, scope: !15)
112125
!26 = !DILocation(line: 18, column: 1, scope: !15)
113126
!27 = !DILocation(line: 19, column: 1, scope: !15)
127+
;.
128+
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
129+
; CHECK: [[META1]] = !DIFile(filename: "temp.ll", directory: {{.*}})
130+
; CHECK: [[DBG5]] = distinct !DISubprogram(name: "process_block_branch", linkageName: "process_block_branch", scope: null, file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]])
131+
; CHECK: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
132+
; CHECK: [[META7]] = !{}
133+
; CHECK: [[DBG8]] = !DILocation(line: 1, column: 1, scope: [[DBG5]])
134+
; CHECK: [[DBG9]] = !DILocation(line: 2, column: 1, scope: [[DBG5]])
135+
; CHECK: [[DBG10]] = distinct !DISubprogram(name: "process_threadable_edges_branch", linkageName: "process_threadable_edges_branch", scope: null, file: [[META1]], line: 8, type: [[META6]], scopeLine: 8, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]])
136+
; CHECK: [[DBG11]] = !DILocation(line: 8, column: 1, scope: [[DBG10]])
137+
; CHECK: [[DBG12]] = !DILocation(line: 9, column: 1, scope: [[DBG10]])
138+
; CHECK: [[DBG13]] = !DILocation(line: 10, column: 1, scope: [[DBG10]])
139+
; CHECK: [[DBG14]] = !DILocation(line: 11, column: 1, scope: [[DBG10]])
140+
; CHECK: [[DBG15]] = !DILocation(line: 12, column: 1, scope: [[DBG10]])
141+
; CHECK: [[DBG16]] = !DILocation(line: 13, column: 1, scope: [[DBG10]])
142+
; CHECK: [[DBG17]] = !DILocation(line: 16, column: 1, scope: [[DBG10]])
143+
; CHECK: [[DBG18]] = !DILocation(line: 17, column: 1, scope: [[DBG10]])
144+
;.

llvm/test/Transforms/JumpThreading/removed-use.ll

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -S < %s -passes=jump-threading | FileCheck %s
2-
; CHECK-LABEL: @foo
3-
; CHECK: bb6:
4-
; CHECK-NEXT: ret void
5-
; CHECK: bb3:
6-
; CHECK: br label %bb3
73
define void @foo() {
4+
; CHECK-LABEL: define void @foo() {
5+
; CHECK-NEXT: [[BB6:.*:]]
6+
; CHECK-NEXT: ret void
7+
;
88
entry:
99
br i1 true, label %bb6, label %bb3
1010

@@ -27,9 +27,13 @@ bb6:
2727
ret void
2828
}
2929

30-
; CHECK-LABEL: @bar
3130
; Just check that we don't crash on this test.
3231
define void @bar(i1 %p) {
32+
; CHECK-LABEL: define void @bar(
33+
; CHECK-SAME: i1 [[P:%.*]]) {
34+
; CHECK-NEXT: [[EXIT:.*:]]
35+
; CHECK-NEXT: ret void
36+
;
3337
entry:
3438
br i1 false, label %bb2, label %exit
3539

@@ -46,7 +50,7 @@ bb4:
4650
bb5:
4751
%x1 = phi i32 [ %x0, %bb3 ], [ 0, %bb4 ]
4852
switch i32 %x1, label %exit [
49-
i32 10, label %bb2
53+
i32 10, label %bb2
5054
]
5155

5256
exit:

llvm/test/Transforms/JumpThreading/unreachable-loops.ll

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ define void @unreachable_single_bb_loop() {
1212
; CHECK-NEXT: [[TMP:%.*]] = call i32 @a()
1313
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 1
1414
; CHECK-NEXT: br i1 [[TMP1]], label [[BB8:%.*]], label [[BB8]]
15-
; CHECK: bb2:
16-
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1
17-
; CHECK-NEXT: switch i1 [[TMP4]], label [[BB2:%.*]] [
18-
; CHECK-NEXT: i1 false, label [[BB8]]
19-
; CHECK-NEXT: i1 true, label [[BB8]]
20-
; CHECK-NEXT: ]
2115
; CHECK: bb8:
2216
; CHECK-NEXT: ret void
2317
;
@@ -52,14 +46,6 @@ define void @unreachable_multi_bbs_loop() {
5246
; CHECK-NEXT: [[TMP:%.*]] = call i32 @a()
5347
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 1
5448
; CHECK-NEXT: br i1 [[TMP1]], label [[BB8:%.*]], label [[BB8]]
55-
; CHECK: bb3:
56-
; CHECK-NEXT: br label [[BB2:%.*]]
57-
; CHECK: bb2:
58-
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1
59-
; CHECK-NEXT: switch i1 [[TMP4]], label [[BB3:%.*]] [
60-
; CHECK-NEXT: i1 false, label [[BB8]]
61-
; CHECK-NEXT: i1 true, label [[BB8]]
62-
; CHECK-NEXT: ]
6349
; CHECK: bb8:
6450
; CHECK-NEXT: ret void
6551
;
@@ -99,10 +85,6 @@ define void @PR48362(i1 %arg) {
9985
; CHECK-LABEL: @PR48362(
10086
; CHECK-NEXT: cleanup.cont1500:
10187
; CHECK-NEXT: unreachable
102-
; CHECK: if.end1733:
103-
; CHECK-NEXT: [[I82:%.*]] = load i32, ptr undef, align 1
104-
; CHECK-NEXT: [[TOBOOL1731_NOT:%.*]] = icmp eq i32 [[I82]], 0
105-
; CHECK-NEXT: br label [[IF_END1733:%.*]]
10688
;
10789
cleanup1491: ; preds = %for.body1140
10890
switch i32 0, label %cleanup2343.loopexit4 [
@@ -189,23 +171,9 @@ cleanup2343.loopexit4: ; preds = %cleanup1491
189171

190172
define i32 @constant_phi_leads_to_self_reference(ptr %ptr) {
191173
; CHECK-LABEL: @constant_phi_leads_to_self_reference(
192-
; CHECK-NEXT: [[A10:%.*]] = alloca i1, align 1
193-
; CHECK-NEXT: br label [[F6:%.*]]
194-
; CHECK: T3:
195-
; CHECK-NEXT: [[L6:%.*]] = phi i1 [ [[C4:%.*]], [[BB6:%.*]] ]
196-
; CHECK-NEXT: br label [[BB5:%.*]]
197-
; CHECK: BB5:
198-
; CHECK-NEXT: [[L10:%.*]] = load i1, ptr [[A10]], align 1
199-
; CHECK-NEXT: br i1 [[L10]], label [[BB6]], label [[F6]]
200-
; CHECK: BB6:
201-
; CHECK-NEXT: [[LGV3:%.*]] = load i1, ptr [[A7:%.*]], align 1
202-
; CHECK-NEXT: [[C4]] = icmp sle i1 [[L6]], true
203-
; CHECK-NEXT: store i1 [[C4]], ptr [[A7]], align 1
204-
; CHECK-NEXT: br i1 [[L6]], label [[F6]], label [[T3:%.*]]
205-
; CHECK: F6:
174+
; CHECK-NEXT: F6:
175+
; CHECK-NEXT: [[A9:%.*]] = alloca i1, align 1
206176
; CHECK-NEXT: ret i32 0
207-
; CHECK: F7:
208-
; CHECK-NEXT: br label [[BB5]]
209177
;
210178
%A9 = alloca i1, align 1
211179
br i1 false, label %BB4, label %F6

0 commit comments

Comments
 (0)