Skip to content

Commit c12b109

Browse files
committed
[SCCP] Check whether the default case is reachable
1 parent 688480b commit c12b109

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ bool SCCPSolver::removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
310310
new UnreachableInst(DefaultDest->getContext(), NewUnreachableBB);
311311
}
312312

313+
DefaultDest->removePredecessor(BB);
313314
SI->setDefaultDest(NewUnreachableBB);
314315
Updates.push_back({DominatorTree::Delete, BB, DefaultDest});
315316
Updates.push_back({DominatorTree::Insert, BB, NewUnreachableBB});
@@ -1063,14 +1064,17 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
10631064
// is ready.
10641065
if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
10651066
const ConstantRange &Range = SCValue.getConstantRange();
1067+
unsigned ReachableCaseCount = 0;
10661068
for (const auto &Case : SI->cases()) {
10671069
const APInt &CaseValue = Case.getCaseValue()->getValue();
1068-
if (Range.contains(CaseValue))
1070+
if (Range.contains(CaseValue)) {
10691071
Succs[Case.getSuccessorIndex()] = true;
1072+
++ReachableCaseCount;
1073+
}
10701074
}
10711075

1072-
// TODO: Determine whether default case is reachable.
1073-
Succs[SI->case_default()->getSuccessorIndex()] = true;
1076+
Succs[SI->case_default()->getSuccessorIndex()] =
1077+
Range.isSizeLargerThan(ReachableCaseCount);
10741078
return;
10751079
}
10761080

llvm/test/Transforms/SCCP/switch.ll

+15-17
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,16 @@ switch.1:
117117
ret i32 %phi
118118
}
119119

120-
; TODO: Determine that the default destination is dead.
121120
define i32 @test_local_range(ptr %p) {
122121
; CHECK-LABEL: @test_local_range(
123122
; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]]
124-
; CHECK-NEXT: switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [
123+
; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT_UNREACHABLE:%.*]] [
125124
; CHECK-NEXT: i32 0, label [[SWITCH_0:%.*]]
126125
; CHECK-NEXT: i32 1, label [[SWITCH_1:%.*]]
127126
; CHECK-NEXT: i32 2, label [[SWITCH_2:%.*]]
128127
; CHECK-NEXT: ]
129-
; CHECK: switch.default:
130-
; CHECK-NEXT: ret i32 -1
128+
; CHECK: default.unreachable:
129+
; CHECK-NEXT: unreachable
131130
; CHECK: switch.0:
132131
; CHECK-NEXT: ret i32 0
133132
; CHECK: switch.1:
@@ -163,14 +162,14 @@ switch.3:
163162
define i32 @test_duplicate_successors(ptr %p) {
164163
; CHECK-LABEL: @test_duplicate_successors(
165164
; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]]
166-
; CHECK-NEXT: switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [
165+
; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT_UNREACHABLE:%.*]] [
167166
; CHECK-NEXT: i32 0, label [[SWITCH_0:%.*]]
168167
; CHECK-NEXT: i32 1, label [[SWITCH_0]]
169168
; CHECK-NEXT: i32 2, label [[SWITCH_1:%.*]]
170169
; CHECK-NEXT: i32 3, label [[SWITCH_1]]
171170
; CHECK-NEXT: ]
172-
; CHECK: switch.default:
173-
; CHECK-NEXT: ret i32 -1
171+
; CHECK: default.unreachable:
172+
; CHECK-NEXT: unreachable
174173
; CHECK: switch.0:
175174
; CHECK-NEXT: ret i32 0
176175
; CHECK: switch.1:
@@ -203,13 +202,13 @@ switch.2:
203202
; range information.
204203
define internal i32 @test_ip_range(i32 %x) {
205204
; CHECK-LABEL: @test_ip_range(
206-
; CHECK-NEXT: switch i32 [[X:%.*]], label [[SWITCH_DEFAULT:%.*]] [
205+
; CHECK-NEXT: switch i32 [[X:%.*]], label [[DEFAULT_UNREACHABLE:%.*]] [
207206
; CHECK-NEXT: i32 3, label [[SWITCH_3:%.*]]
208207
; CHECK-NEXT: i32 1, label [[SWITCH_1:%.*]]
209208
; CHECK-NEXT: i32 2, label [[SWITCH_2:%.*]]
210209
; CHECK-NEXT: ], !prof [[PROF1:![0-9]+]]
211-
; CHECK: switch.default:
212-
; CHECK-NEXT: ret i32 -1
210+
; CHECK: default.unreachable:
211+
; CHECK-NEXT: unreachable
213212
; CHECK: switch.1:
214213
; CHECK-NEXT: ret i32 1
215214
; CHECK: switch.2:
@@ -242,8 +241,8 @@ switch.3:
242241

243242
define void @call_test_ip_range() {
244243
; CHECK-LABEL: @call_test_ip_range(
245-
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_ip_range(i32 1)
246-
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test_ip_range(i32 3)
244+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_ip_range(i32 1), !range [[RNG2:![0-9]+]]
245+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test_ip_range(i32 3), !range [[RNG2]]
247246
; CHECK-NEXT: ret void
248247
;
249248
call i32 @test_ip_range(i32 1)
@@ -309,7 +308,7 @@ define i32 @test_default_unreachable_by_dom_cond(i32 %x) {
309308
; CHECK-NEXT: [[OR_COND:%.*]] = icmp ult i32 [[X:%.*]], 4
310309
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
311310
; CHECK: if.then:
312-
; CHECK-NEXT: switch i32 [[X]], label [[SW_EPILOG:%.*]] [
311+
; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT_UNREACHABLE:%.*]] [
313312
; CHECK-NEXT: i32 0, label [[SW_BB:%.*]]
314313
; CHECK-NEXT: i32 1, label [[SW_BB2:%.*]]
315314
; CHECK-NEXT: i32 2, label [[SW_BB4:%.*]]
@@ -327,11 +326,10 @@ define i32 @test_default_unreachable_by_dom_cond(i32 %x) {
327326
; CHECK: sw.bb6:
328327
; CHECK-NEXT: [[CALL7:%.*]] = tail call i32 @g(i32 5)
329328
; CHECK-NEXT: br label [[RETURN]]
330-
; CHECK: sw.epilog:
331-
; CHECK-NEXT: call void @foo()
332-
; CHECK-NEXT: br label [[RETURN]]
329+
; CHECK: default.unreachable:
330+
; CHECK-NEXT: unreachable
333331
; CHECK: return:
334-
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL7]], [[SW_BB6]] ], [ [[CALL5]], [[SW_BB4]] ], [ [[CALL3]], [[SW_BB2]] ], [ [[CALL]], [[SW_BB]] ], [ -23, [[SW_EPILOG]] ], [ -23, [[ENTRY:%.*]] ]
332+
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL7]], [[SW_BB6]] ], [ [[CALL5]], [[SW_BB4]] ], [ [[CALL3]], [[SW_BB2]] ], [ [[CALL]], [[SW_BB]] ], [ -23, [[ENTRY:%.*]] ]
335333
; CHECK-NEXT: ret i32 [[RETVAL_0]]
336334
;
337335
entry:

0 commit comments

Comments
 (0)