Skip to content

Commit 081d850

Browse files
committed
SimplifyCFG: Delay check for switch-to-lookup option
The option prevents any switch replacements from happening earlier in the compilation pipeline, even though it should only apply to lookup tables. Delay the check until we are sure that we would create a lookup table. If not, continue with the replacement.
1 parent 5003126 commit 081d850

File tree

4 files changed

+42
-94
lines changed

4 files changed

+42
-94
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6923,7 +6923,8 @@ static void reuseTableCompare(
69236923
/// lookup tables.
69246924
static bool simplifySwitchLookup(SwitchInst *SI, IRBuilder<> &Builder,
69256925
DomTreeUpdater *DTU, const DataLayout &DL,
6926-
const TargetTransformInfo &TTI) {
6926+
const TargetTransformInfo &TTI,
6927+
bool ConvertSwitchToLookupTable) {
69276928
assert(SI->getNumCases() > 1 && "Degenerate switch?");
69286929

69296930
BasicBlock *BB = SI->getParent();
@@ -7091,6 +7092,18 @@ static bool simplifySwitchLookup(SwitchInst *SI, IRBuilder<> &Builder,
70917092
PhiToReplacementMap.insert({PHI, Replacement});
70927093
}
70937094

7095+
bool AnyLookupTables = any_of(
7096+
PhiToReplacementMap, [](auto &KV) { return KV.second.isLookupTable(); });
7097+
7098+
// The conversion from switch to lookup tables results in difficult-to-analyze
7099+
// code and makes pruning branches much harder. This is a problem if the
7100+
// switch expression itself can still be restricted as a result of inlining or
7101+
// CVP. Therefore, only apply this transformation during late stages of the
7102+
// optimisation pipeline.
7103+
// However, other switch replacements can be applied much earlier.
7104+
if (AnyLookupTables && !ConvertSwitchToLookupTable)
7105+
return false;
7106+
70947107
Builder.SetInsertPoint(SI);
70957108
// TableIndex is the switch condition - TableIndexOffset if we don't
70967109
// use the condition directly
@@ -7732,13 +7745,8 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
77327745
if (Options.ForwardSwitchCondToPhi && forwardSwitchConditionToPHI(SI))
77337746
return requestResimplify();
77347747

7735-
// The conversion from switch to lookup tables results in difficult-to-analyze
7736-
// code and makes pruning branches much harder. This is a problem if the
7737-
// switch expression itself can still be restricted as a result of inlining or
7738-
// CVP. Therefore, only apply this transformation during late stages of the
7739-
// optimisation pipeline.
7740-
if (Options.ConvertSwitchToLookupTable &&
7741-
simplifySwitchLookup(SI, Builder, DTU, DL, TTI))
7748+
if (simplifySwitchLookup(SI, Builder, DTU, DL, TTI,
7749+
Options.ConvertSwitchToLookupTable))
77427750
return requestResimplify();
77437751

77447752
if (simplifySwitchOfPowersOfTwo(SI, Builder, DL, TTI))

llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ define internal i32 @table_switch(i32 %x) "branch-target-enforcement" {
99
; CHECK-NEXT: cmp r1, #3
1010
; CHECK-NEXT: bhi .LBB0_6
1111
; CHECK-NEXT: @ %bb.1: @ %entry
12+
; CHECK-NEXT: movs r0, #3
1213
; CHECK-NEXT: .LCPI0_0:
1314
; CHECK-NEXT: tbb [pc, r1]
1415
; CHECK-NEXT: @ %bb.2:
@@ -22,7 +23,7 @@ define internal i32 @table_switch(i32 %x) "branch-target-enforcement" {
2223
; CHECK-NEXT: movs r0, #2
2324
; CHECK-NEXT: bx lr
2425
; CHECK-NEXT: .LBB0_4: @ %bb3
25-
; CHECK-NEXT: movs r0, #3
26+
; CHECK-NEXT: movs r0, #1
2627
; CHECK-NEXT: bx lr
2728
; CHECK-NEXT: .LBB0_5: @ %bb4
2829
; CHECK-NEXT: movs r0, #4
@@ -51,7 +52,7 @@ sw.epilog:
5152
br label %return
5253

5354
return:
54-
%ret = phi i32 [ 0, %sw.epilog ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ]
55+
%ret = phi i32 [ 0, %sw.epilog ], [ 3, %bb1 ], [ 2, %bb2 ], [ 1, %bb3 ], [ 4, %bb4 ]
5556
ret i32 %ret
5657
}
5758

llvm/test/Transforms/PhaseOrdering/X86/merge-functions.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ bb3: ; preds = %bb1, %bb2
8989

9090
define i1 @test2(i32 %c) {
9191
; CHECK-LABEL: @test2(
92-
; CHECK-NEXT: [[TMP2:%.*]] = tail call noundef i1 @test1(i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]]
92+
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @test1(i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]]
9393
; CHECK-NEXT: ret i1 [[TMP2]]
9494
;
9595
entry:

llvm/test/Transforms/SimplifyCFG/switch-transformations-no-lut.ll

Lines changed: 22 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
77
define i32 @linear_transform_with_default(i32 %x) {
88
; OPTNOLUT-LABEL: define i32 @linear_transform_with_default(
99
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
10-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
11-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
12-
; OPTNOLUT-NEXT: i32 0, label %[[CASE0:.*]]
13-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
14-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
15-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
16-
; OPTNOLUT-NEXT: ]
17-
; OPTNOLUT: [[CASE0]]:
18-
; OPTNOLUT-NEXT: br label %[[END]]
19-
; OPTNOLUT: [[CASE1]]:
20-
; OPTNOLUT-NEXT: br label %[[END]]
21-
; OPTNOLUT: [[CASE2]]:
22-
; OPTNOLUT-NEXT: br label %[[END]]
23-
; OPTNOLUT: [[CASE3]]:
24-
; OPTNOLUT-NEXT: br label %[[END]]
25-
; OPTNOLUT: [[END]]:
26-
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 1, %[[CASE0]] ], [ 4, %[[CASE1]] ], [ 7, %[[CASE2]] ], [ 10, %[[CASE3]] ], [ 13, %[[ENTRY]] ]
10+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
11+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
12+
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
13+
; OPTNOLUT-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1
14+
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 13
2715
; OPTNOLUT-NEXT: ret i32 [[IDX]]
2816
;
2917
; TTINOLUT-LABEL: define i32 @linear_transform_with_default(
@@ -146,26 +134,8 @@ end:
146134
define i32 @linear_transform_no_default(i32 %x) {
147135
; OPTNOLUT-LABEL: define i32 @linear_transform_no_default(
148136
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
149-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
150-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
151-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
152-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
153-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
154-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
155-
; OPTNOLUT-NEXT: i32 4, label %[[CASE4:.*]]
156-
; OPTNOLUT-NEXT: ]
157-
; OPTNOLUT: [[CASE1]]:
158-
; OPTNOLUT-NEXT: br label %[[END]]
159-
; OPTNOLUT: [[CASE2]]:
160-
; OPTNOLUT-NEXT: br label %[[END]]
161-
; OPTNOLUT: [[CASE3]]:
162-
; OPTNOLUT-NEXT: br label %[[END]]
163-
; OPTNOLUT: [[CASE4]]:
164-
; OPTNOLUT-NEXT: br label %[[END]]
165-
; OPTNOLUT: [[DEFAULT]]:
166-
; OPTNOLUT-NEXT: unreachable
167-
; OPTNOLUT: [[END]]:
168-
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = phi i32 [ 3, %[[CASE1]] ], [ 6, %[[CASE2]] ], [ 9, %[[CASE3]] ], [ 12, %[[CASE4]] ], [ 0, %[[ENTRY]] ]
137+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
138+
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
169139
; OPTNOLUT-NEXT: ret i32 [[SWITCH_IDX_MULT]]
170140
;
171141
; TTINOLUT-LABEL: define i32 @linear_transform_no_default(
@@ -222,23 +192,11 @@ end:
222192
define i4 @bitmap_no_default(i32 %x) {
223193
; OPTNOLUT-LABEL: define i4 @bitmap_no_default(
224194
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
225-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
226-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
227-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
228-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
229-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
230-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
231-
; OPTNOLUT-NEXT: ]
232-
; OPTNOLUT: [[CASE1]]:
233-
; OPTNOLUT-NEXT: br label %[[END]]
234-
; OPTNOLUT: [[CASE2]]:
235-
; OPTNOLUT-NEXT: br label %[[END]]
236-
; OPTNOLUT: [[CASE3]]:
237-
; OPTNOLUT-NEXT: br label %[[END]]
238-
; OPTNOLUT: [[DEFAULT]]:
239-
; OPTNOLUT-NEXT: unreachable
240-
; OPTNOLUT: [[END]]:
241-
; OPTNOLUT-NEXT: [[SWITCH_MASKED:%.*]] = phi i4 [ 2, %[[CASE1]] ], [ 4, %[[CASE2]] ], [ -8, %[[CASE3]] ], [ 0, %[[ENTRY]] ]
195+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
196+
; OPTNOLUT-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i16
197+
; OPTNOLUT-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i16 [[SWITCH_CAST]], 4
198+
; OPTNOLUT-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i16 -31712, [[SWITCH_SHIFTAMT]]
199+
; OPTNOLUT-NEXT: [[SWITCH_MASKED:%.*]] = trunc i16 [[SWITCH_DOWNSHIFT]] to i4
242200
; OPTNOLUT-NEXT: ret i4 [[SWITCH_MASKED]]
243201
;
244202
; TTINOLUT-LABEL: define i4 @bitmap_no_default(
@@ -289,23 +247,13 @@ end:
289247
define i4 @bitmap_with_default(i32 %x) {
290248
; OPTNOLUT-LABEL: define i4 @bitmap_with_default(
291249
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
292-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
293-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
294-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
295-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
296-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
297-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
298-
; OPTNOLUT-NEXT: ]
299-
; OPTNOLUT: [[CASE1]]:
300-
; OPTNOLUT-NEXT: br label %[[END]]
301-
; OPTNOLUT: [[CASE2]]:
302-
; OPTNOLUT-NEXT: br label %[[END]]
303-
; OPTNOLUT: [[CASE3]]:
304-
; OPTNOLUT-NEXT: br label %[[END]]
305-
; OPTNOLUT: [[DEFAULT]]:
306-
; OPTNOLUT-NEXT: br label %[[END]]
307-
; OPTNOLUT: [[END]]:
308-
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i4 [ 2, %[[CASE1]] ], [ 4, %[[CASE2]] ], [ -8, %[[CASE3]] ], [ -1, %[[DEFAULT]] ], [ 0, %[[ENTRY]] ]
250+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
251+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
252+
; OPTNOLUT-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i16
253+
; OPTNOLUT-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i16 [[SWITCH_CAST]], 4
254+
; OPTNOLUT-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i16 -31712, [[SWITCH_SHIFTAMT]]
255+
; OPTNOLUT-NEXT: [[SWITCH_MASKED:%.*]] = trunc i16 [[SWITCH_DOWNSHIFT]] to i4
256+
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i4 [[SWITCH_MASKED]], i4 -1
309257
; OPTNOLUT-NEXT: ret i4 [[IDX]]
310258
;
311259
; TTINOLUT-LABEL: define i4 @bitmap_with_default(
@@ -394,18 +342,9 @@ end:
394342
define i32 @single_value_withdefault(i32 %x) {
395343
; OPTNOLUT-LABEL: define i32 @single_value_withdefault(
396344
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
397-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
398-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
399-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
400-
; OPTNOLUT-NEXT: i32 1, label %[[END]]
401-
; OPTNOLUT-NEXT: i32 2, label %[[END]]
402-
; OPTNOLUT-NEXT: i32 3, label %[[END]]
403-
; OPTNOLUT-NEXT: i32 4, label %[[END]]
404-
; OPTNOLUT-NEXT: ]
405-
; OPTNOLUT: [[DEFAULT]]:
406-
; OPTNOLUT-NEXT: br label %[[END]]
407-
; OPTNOLUT: [[END]]:
408-
; OPTNOLUT-NEXT: [[DOT:%.*]] = phi i32 [ 3, %[[DEFAULT]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ]
345+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
346+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
347+
; OPTNOLUT-NEXT: [[DOT:%.*]] = select i1 [[TMP0]], i32 2, i32 3
409348
; OPTNOLUT-NEXT: ret i32 [[DOT]]
410349
;
411350
; TTINOLUT-LABEL: define i32 @single_value_withdefault(

0 commit comments

Comments
 (0)