Skip to content

Commit 0c56fd0

Browse files
authored
[SimplifyCFG] Forward indirect switch condition value if it can help fold the PHI (#95932)
Fixes #95919.
1 parent 02b57de commit 0c56fd0

File tree

4 files changed

+132
-4
lines changed

4 files changed

+132
-4
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -5818,7 +5818,8 @@ static bool ForwardSwitchConditionToPHI(SwitchInst *SI) {
58185818
for (auto &ForwardingNode : ForwardingNodes) {
58195819
PHINode *Phi = ForwardingNode.first;
58205820
SmallVectorImpl<int> &Indexes = ForwardingNode.second;
5821-
if (Indexes.size() < 2)
5821+
// Check if it helps to fold PHI.
5822+
if (Indexes.size() < 2 && !llvm::is_contained(Phi->incoming_values(), SI->getCondition()))
58225823
continue;
58235824

58245825
for (int Index : Indexes)

llvm/test/CodeGen/AArch64/arm64-jumptable.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ bb3:
1818
bb4:
1919
br label %exit.sink.split
2020
exit.sink.split:
21-
%.sink = phi i32 [ 5, %bb4 ], [ %b, %bb1 ], [ 3, %bb3 ], [ %a, %entry ]
21+
%.sink = phi i32 [ 5, %bb4 ], [ %b, %bb1 ], [ 7, %bb3 ], [ %a, %entry ]
2222
store i32 %.sink, ptr %to
2323
br label %exit
2424
exit:

llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll

+127
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,76 @@ return: ; preds = %entry, %sw.bb4, %sw
5959
ret i32 %retval.0
6060
}
6161

62+
; We should not forward `%m` to 1, as this does not simplify the CFG.
63+
define i32 @forward_one(i32 %m) {
64+
; NO_FWD-LABEL: @forward_one(
65+
; NO_FWD-NEXT: entry:
66+
; NO_FWD-NEXT: switch i32 [[M:%.*]], label [[SW_BB4:%.*]] [
67+
; NO_FWD-NEXT: i32 0, label [[RETURN:%.*]]
68+
; NO_FWD-NEXT: i32 1, label [[SW_BB1:%.*]]
69+
; NO_FWD-NEXT: i32 2, label [[SW_BB2:%.*]]
70+
; NO_FWD-NEXT: i32 3, label [[SW_BB3:%.*]]
71+
; NO_FWD-NEXT: ]
72+
; NO_FWD: sw.bb1:
73+
; NO_FWD-NEXT: br label [[RETURN]]
74+
; NO_FWD: sw.bb2:
75+
; NO_FWD-NEXT: br label [[RETURN]]
76+
; NO_FWD: sw.bb3:
77+
; NO_FWD-NEXT: br label [[RETURN]]
78+
; NO_FWD: sw.bb4:
79+
; NO_FWD-NEXT: br label [[RETURN]]
80+
; NO_FWD: return:
81+
; NO_FWD-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 4, [[SW_BB4]] ], [ 5, [[SW_BB3]] ], [ 6, [[SW_BB2]] ], [ 1, [[SW_BB1]] ], [ 8, [[ENTRY:%.*]] ]
82+
; NO_FWD-NEXT: ret i32 [[RETVAL_0]]
83+
;
84+
; FWD-LABEL: @forward_one(
85+
; FWD-NEXT: entry:
86+
; FWD-NEXT: switch i32 [[M:%.*]], label [[SW_BB4:%.*]] [
87+
; FWD-NEXT: i32 0, label [[RETURN:%.*]]
88+
; FWD-NEXT: i32 1, label [[SW_BB1:%.*]]
89+
; FWD-NEXT: i32 2, label [[SW_BB2:%.*]]
90+
; FWD-NEXT: i32 3, label [[SW_BB3:%.*]]
91+
; FWD-NEXT: ]
92+
; FWD: sw.bb1:
93+
; FWD-NEXT: br label [[RETURN]]
94+
; FWD: sw.bb2:
95+
; FWD-NEXT: br label [[RETURN]]
96+
; FWD: sw.bb3:
97+
; FWD-NEXT: br label [[RETURN]]
98+
; FWD: sw.bb4:
99+
; FWD-NEXT: br label [[RETURN]]
100+
; FWD: return:
101+
; FWD-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 4, [[SW_BB4]] ], [ 5, [[SW_BB3]] ], [ 6, [[SW_BB2]] ], [ 1, [[SW_BB1]] ], [ 8, [[ENTRY:%.*]] ]
102+
; FWD-NEXT: ret i32 [[RETVAL_0]]
103+
;
104+
entry:
105+
switch i32 %m, label %sw.bb4 [
106+
i32 0, label %sw.bb0
107+
i32 1, label %sw.bb1
108+
i32 2, label %sw.bb2
109+
i32 3, label %sw.bb3
110+
]
111+
112+
sw.bb0: ; preds = %entry
113+
br label %return
114+
115+
sw.bb1: ; preds = %entry
116+
br label %return
117+
118+
sw.bb2: ; preds = %entry
119+
br label %return
120+
121+
sw.bb3: ; preds = %entry
122+
br label %return
123+
124+
sw.bb4: ; preds = %entry
125+
br label %return
126+
127+
return: ; preds = %entry, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1
128+
%retval.0 = phi i32 [ 4, %sw.bb4 ], [ 5, %sw.bb3 ], [ 6, %sw.bb2 ], [ 1, %sw.bb1 ], [ 8, %sw.bb0 ]
129+
ret i32 %retval.0
130+
}
131+
62132
; If 1 incoming phi value is a case constant of a switch, convert it to the switch condition:
63133
; https://bugs.llvm.org/show_bug.cgi?id=34471
64134
; This then subsequently should allow squashing of the other trivial case blocks.
@@ -115,3 +185,60 @@ return:
115185
ret i32 %r
116186
}
117187

188+
; We can replace `[ 1, %bb2 ]` with `[ %arg1, %bb2 ]`.
189+
define { i64, i64 } @PR95919(i64 noundef %arg, i64 noundef %arg1) {
190+
; NO_FWD-LABEL: @PR95919(
191+
; NO_FWD-NEXT: bb:
192+
; NO_FWD-NEXT: switch i64 [[ARG1:%.*]], label [[BB3:%.*]] [
193+
; NO_FWD-NEXT: i64 0, label [[BB5:%.*]]
194+
; NO_FWD-NEXT: i64 1, label [[BB2:%.*]]
195+
; NO_FWD-NEXT: ]
196+
; NO_FWD: bb2:
197+
; NO_FWD-NEXT: br label [[BB5]]
198+
; NO_FWD: bb3:
199+
; NO_FWD-NEXT: [[I:%.*]] = udiv i64 [[ARG:%.*]], [[ARG1]]
200+
; NO_FWD-NEXT: [[I4:%.*]] = shl nuw i64 [[I]], 1
201+
; NO_FWD-NEXT: br label [[BB5]]
202+
; NO_FWD: bb5:
203+
; NO_FWD-NEXT: [[I6:%.*]] = phi i64 [ [[I4]], [[BB3]] ], [ [[ARG]], [[BB2]] ], [ undef, [[BB:%.*]] ]
204+
; NO_FWD-NEXT: [[I7:%.*]] = phi i64 [ 1, [[BB3]] ], [ 1, [[BB2]] ], [ [[ARG1]], [[BB]] ]
205+
; NO_FWD-NEXT: [[I8:%.*]] = insertvalue { i64, i64 } poison, i64 [[I7]], 0
206+
; NO_FWD-NEXT: [[I9:%.*]] = insertvalue { i64, i64 } [[I8]], i64 [[I6]], 1
207+
; NO_FWD-NEXT: ret { i64, i64 } [[I9]]
208+
;
209+
; FWD-LABEL: @PR95919(
210+
; FWD-NEXT: bb:
211+
; FWD-NEXT: [[SWITCH:%.*]] = icmp ult i64 [[ARG1:%.*]], 2
212+
; FWD-NEXT: br i1 [[SWITCH]], label [[BB5:%.*]], label [[BB3:%.*]]
213+
; FWD: bb3:
214+
; FWD-NEXT: [[I:%.*]] = udiv i64 [[ARG:%.*]], [[ARG1]]
215+
; FWD-NEXT: [[I4:%.*]] = shl nuw i64 [[I]], 1
216+
; FWD-NEXT: br label [[BB5]]
217+
; FWD: bb5:
218+
; FWD-NEXT: [[I6:%.*]] = phi i64 [ [[I4]], [[BB3]] ], [ [[ARG]], [[BB:%.*]] ]
219+
; FWD-NEXT: [[I7:%.*]] = phi i64 [ 1, [[BB3]] ], [ [[ARG1]], [[BB]] ]
220+
; FWD-NEXT: [[I8:%.*]] = insertvalue { i64, i64 } poison, i64 [[I7]], 0
221+
; FWD-NEXT: [[I9:%.*]] = insertvalue { i64, i64 } [[I8]], i64 [[I6]], 1
222+
; FWD-NEXT: ret { i64, i64 } [[I9]]
223+
;
224+
bb:
225+
switch i64 %arg1, label %bb3 [
226+
i64 0, label %bb5
227+
i64 1, label %bb2
228+
]
229+
230+
bb2: ; preds = %bb
231+
br label %bb5
232+
233+
bb3: ; preds = %bb
234+
%i = udiv i64 %arg, %arg1
235+
%i4 = shl nuw i64 %i, 1
236+
br label %bb5
237+
238+
bb5: ; preds = %bb3, %bb2, %bb
239+
%i6 = phi i64 [ %i4, %bb3 ], [ %arg, %bb2 ], [ undef, %bb ]
240+
%i7 = phi i64 [ 1, %bb3 ], [ 1, %bb2 ], [ %arg1, %bb ]
241+
%i8 = insertvalue { i64, i64 } poison, i64 %i7, 0
242+
%i9 = insertvalue { i64, i64 } %i8, i64 %i6, 1
243+
ret { i64, i64 } %i9
244+
}

llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ define i32 @foo(i32 %x) #0 section ".tcm_text" {
4343
; DISABLE: sw.default:
4444
; DISABLE-NEXT: br label [[RETURN]]
4545
; DISABLE: return:
46-
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 5, [[SW_BB5]] ], [ 12, [[SW_BB4]] ], [ 22, [[SW_BB3]] ], [ 14, [[SW_BB2]] ], [ 20, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ]
46+
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 33, [[SW_BB5]] ], [ 12, [[SW_BB4]] ], [ 22, [[SW_BB3]] ], [ 14, [[SW_BB2]] ], [ 20, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ]
4747
; DISABLE-NEXT: ret i32 [[RETVAL_0]]
4848
;
4949
entry:
@@ -81,7 +81,7 @@ sw.bb4: ; preds = %entry
8181
br label %return
8282

8383
sw.bb5: ; preds = %entry
84-
store i32 5, ptr %retval, align 4
84+
store i32 33, ptr %retval, align 4
8585
br label %return
8686

8787
sw.default: ; preds = %entry

0 commit comments

Comments
 (0)