Skip to content

Commit d26df32

Browse files
[SimplifyCFG] Consider preds to switch in simplifyDuplicateSwitchArms
Allow a duplicate basic block with multiple predecessors to the jump table to be simplified, by considering that the same basic block may appear in more switch cases.
1 parent e32c428 commit d26df32

File tree

3 files changed

+22
-30
lines changed

3 files changed

+22
-30
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7474,9 +7474,6 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
74747474
/// IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
74757475
/// of the incoming values.
74767476
struct SwitchSuccWrapper {
7477-
// Keep so we can use SwitchInst::setSuccessor to do the replacement. It won't
7478-
// be important to equality though.
7479-
unsigned SuccNum;
74807477
BasicBlock *Dest;
74817478
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> *PhiPredIVs;
74827479
};
@@ -7563,6 +7560,7 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
75637560
SmallPtrSet<PHINode *, 8> Phis;
75647561
SmallPtrSet<BasicBlock *, 8> Seen;
75657562
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> PhiPredIVs;
7563+
DenseMap<BasicBlock *, SmallVector<unsigned, 4>> BBToSuccessorIndexes;
75667564
SmallVector<SwitchSuccWrapper> Cases;
75677565
Cases.reserve(SI->getNumSuccessors());
75687566

@@ -7575,8 +7573,9 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
75757573
continue;
75767574

75777575
// FIXME: This case needs some extra care because the terminators other than
7578-
// SI need to be updated.
7579-
if (BB->hasNPredecessorsOrMore(2))
7576+
// SI need to be updated. For now, consider only backedges to the SI.
7577+
if (BB->hasNPredecessorsOrMore(4) ||
7578+
BB->getUniquePredecessor() != SI->getParent())
75807579
continue;
75817580

75827581
// FIXME: Relax that the terminator is a BranchInst by checking for equality
@@ -7591,8 +7590,11 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
75917590
for (BasicBlock *Succ : BI->successors())
75927591
for (PHINode &Phi : Succ->phis())
75937592
Phis.insert(&Phi);
7593+
// Add the successor only if not previously visited.
7594+
Cases.emplace_back(SwitchSuccWrapper{BB, &PhiPredIVs});
75947595
}
7595-
Cases.emplace_back(SwitchSuccWrapper{I, BB, &PhiPredIVs});
7596+
7597+
BBToSuccessorIndexes[BB].emplace_back(I);
75967598
}
75977599

75987600
// Precompute a data structure to improve performance of isEqual for
@@ -7627,7 +7629,9 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
76277629
// We know that SI's parent BB no longer dominates the old case successor
76287630
// since we are making it dead.
76297631
Updates.push_back({DominatorTree::Delete, SI->getParent(), SSW.Dest});
7630-
SI->setSuccessor(SSW.SuccNum, (*It)->Dest);
7632+
const auto &Successors = BBToSuccessorIndexes.at(SSW.Dest);
7633+
for (unsigned Idx : Successors)
7634+
SI->setSuccessor(Idx, (*It)->Dest);
76317635
MadeChange = true;
76327636
}
76337637
}

llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,14 @@ define i32 @overflow(i32 %type) {
320320
; CHECK-NEXT: i32 1, label [[IF_END:%.*]]
321321
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
322322
; CHECK-NEXT: ]
323-
; CHECK: sw.bb1:
324-
; CHECK-NEXT: br label [[SW_DEFAULT]]
325323
; CHECK: sw.bb2:
326-
; CHECK-NEXT: br label [[SW_DEFAULT]]
324+
; CHECK-NEXT: br label [[IF_END]]
327325
; CHECK: sw.bb3:
328-
; CHECK-NEXT: br label [[SW_DEFAULT]]
326+
; CHECK-NEXT: br label [[IF_END]]
327+
; CHECK: sw.default:
328+
; CHECK-NEXT: br label [[IF_END]]
329329
; CHECK: if.end:
330-
; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[IF_END]] ], [ 3, [[ENTRY:%.*]] ]
330+
; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 3, [[SW_DEFAULT]] ], [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[ENTRY:%.*]] ]
331331
; CHECK-NEXT: ret i32 [[DIRENT_TYPE_0]]
332332
;
333333
entry:

llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,13 @@ define i32 @switch_dup_exit(i32 %val) {
136136
; SIMPLIFY-CFG-NEXT: i32 1, label %[[EXIT:.*]]
137137
; SIMPLIFY-CFG-NEXT: i32 11, label %[[EXIT]]
138138
; SIMPLIFY-CFG-NEXT: i32 22, label %[[BB1:.*]]
139-
; SIMPLIFY-CFG-NEXT: i32 15, label %[[BB2:.*]]
140-
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB2]]
141139
; SIMPLIFY-CFG-NEXT: ]
142140
; SIMPLIFY-CFG: [[BB1]]:
143141
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
144-
; SIMPLIFY-CFG: [[BB2]]:
145-
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
146142
; SIMPLIFY-CFG: [[DEFAULT]]:
147143
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
148144
; SIMPLIFY-CFG: [[EXIT]]:
149-
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i32 [ 0, %[[DEFAULT]] ], [ 0, %[[BB2]] ], [ 3, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
145+
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i32 [ 0, %[[DEFAULT]] ], [ 3, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
150146
; SIMPLIFY-CFG-NEXT: ret i32 [[RET]]
151147
;
152148
entry:
@@ -175,19 +171,11 @@ exit:
175171
define i64 @switch_dup_exit_2(i32 %val) {
176172
; SIMPLIFY-CFG-LABEL: define i64 @switch_dup_exit_2(
177173
; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) {
178-
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*]]:
179-
; SIMPLIFY-CFG-NEXT: switch i32 [[VAL]], label %[[DEFAULT:.*]] [
180-
; SIMPLIFY-CFG-NEXT: i32 1, label %[[EXIT:.*]]
181-
; SIMPLIFY-CFG-NEXT: i32 11, label %[[EXIT]]
182-
; SIMPLIFY-CFG-NEXT: i32 13, label %[[BB1:.*]]
183-
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB1]]
184-
; SIMPLIFY-CFG-NEXT: ]
185-
; SIMPLIFY-CFG: [[BB1]]:
186-
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
187-
; SIMPLIFY-CFG: [[DEFAULT]]:
188-
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
189-
; SIMPLIFY-CFG: [[EXIT]]:
190-
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i64 [ 0, %[[DEFAULT]] ], [ 0, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
174+
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*:]]
175+
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[VAL]], 1
176+
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[VAL]], 11
177+
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
178+
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 1, i64 0
191179
; SIMPLIFY-CFG-NEXT: ret i64 [[RET]]
192180
;
193181
entry:

0 commit comments

Comments
 (0)