Skip to content

Commit 0637e43

Browse files
committed
[SimplifyCFG] Add predecessor threshold for TryToSimplifyUncondBranchFromEmptyBlock optimization.
In some pathological cases this optimization can spend an unreasonable amount of time. Specifically, there could be a very large number of predecessor blocks of the unconditional branch target. This change adds a threshold bailout to mitigate this. rdar://137063034
1 parent 78ccffc commit 0637e43

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ static cl::opt<unsigned> MaxPhiEntriesIncreaseAfterRemovingEmptyBlock(
122122
// bitreverse idioms.
123123
static const unsigned BitPartRecursionMaxDepth = 48;
124124

125+
static cl::opt<unsigned> MaxNumPredsThreshold(
126+
"simplifycfg-uncondbr-max-num-preds-threshold", cl::init(128), cl::Hidden,
127+
cl::desc("The maximum number of predecessors a block can have to simplify "
128+
"uncond-brs from empty blocks."));
129+
125130
//===----------------------------------------------------------------------===//
126131
// Local constant propagation.
127132
//
@@ -1165,6 +1170,11 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
11651170
if (BB == Succ)
11661171
return false;
11671172

1173+
// Some pathological IR can have extremely high numbers of predecessor blocks.
1174+
// Bail out early if so.
1175+
if (Succ->hasNPredecessorsOrMore(MaxNumPredsThreshold))
1176+
return false;
1177+
11681178
SmallPtrSet<BasicBlock *, 16> BBPreds(pred_begin(BB), pred_end(BB));
11691179
SmallPtrSet<BasicBlock *, 16> SuccPreds(pred_begin(Succ), pred_end(Succ));
11701180

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=simplifycfg -simplifycfg-uncondbr-max-num-preds-threshold=3 -S | FileCheck %s
3+
4+
; This test checks that we don't optimize the edge from Pred -> BB to Pred -> Succ when
5+
; the number of predecessors of Succ is greater than the threshold.
6+
7+
define i8 @succ_has_3_preds(i8 noundef %arg, i1 %c1, i1 %c2) {
8+
; CHECK-LABEL: @succ_has_3_preds(
9+
; CHECK-NEXT: Pred:
10+
; CHECK-NEXT: call void @dummy()
11+
; CHECK-NEXT: br i1 [[C1:%.*]], label [[COMMONPRED:%.*]], label [[EXTRA_BB:%.*]]
12+
; CHECK: extra_bb:
13+
; CHECK-NEXT: br label [[SUCC:%.*]]
14+
; CHECK: CommonPred:
15+
; CHECK-NEXT: call void @dummy()
16+
; CHECK-NEXT: br i1 [[C2:%.*]], label [[SUCC]], label [[BB:%.*]]
17+
; CHECK: BB:
18+
; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ 1, [[COMMONPRED]] ]
19+
; CHECK-NEXT: br label [[SUCC]]
20+
; CHECK: Succ:
21+
; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[PHI1]], [[BB]] ], [ 4, [[COMMONPRED]] ], [ 0, [[EXTRA_BB]] ]
22+
; CHECK-NEXT: ret i8 [[PHI2]]
23+
;
24+
Pred:
25+
call void @dummy()
26+
br i1 %c1, label %CommonPred, label %extra_bb
27+
28+
extra_bb:
29+
br i1 %c1, label %CommonPred, label %Succ
30+
31+
CommonPred:
32+
call void @dummy()
33+
br i1 %c2, label %Succ, label %BB
34+
35+
BB:
36+
%phi1 = phi i8 [1, %CommonPred]
37+
br label %Succ
38+
39+
Succ:
40+
%phi2 = phi i8 [ %phi1, %BB ], [ 4, %CommonPred ], [0, %extra_bb]
41+
ret i8 %phi2
42+
}
43+
44+
declare void @dummy()

0 commit comments

Comments
 (0)