1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=dfa-jump-threading %s | FileCheck %s
4 ; These tests check that the DFA jump threading transformation is applied
5 ; properly to two CFGs. It checks that blocks are cloned, branches are updated,
6 ; and SSA form is restored.
7 define i32 @test1(i32 %num) {
10 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
12 ; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
13 ; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ poison, [[FOR_INC]] ]
14 ; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC_JT1:%.*]] [
15 ; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
16 ; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
18 ; CHECK: for.body.jt2:
19 ; CHECK-NEXT: [[COUNT_JT2:%.*]] = phi i32 [ [[INC_JT2:%.*]], [[FOR_INC_JT2:%.*]] ]
20 ; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_NEXT_JT2:%.*]], [[FOR_INC_JT2]] ]
21 ; CHECK-NEXT: br label [[CASE2]]
22 ; CHECK: for.body.jt1:
23 ; CHECK-NEXT: [[COUNT_JT1:%.*]] = phi i32 [ [[INC_JT1:%.*]], [[FOR_INC_JT1]] ]
24 ; CHECK-NEXT: [[STATE_JT1:%.*]] = phi i32 [ [[STATE_NEXT_JT1:%.*]], [[FOR_INC_JT1]] ]
25 ; CHECK-NEXT: br label [[CASE1]]
27 ; CHECK-NEXT: [[COUNT2:%.*]] = phi i32 [ [[COUNT_JT1]], [[FOR_BODY_JT1:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
28 ; CHECK-NEXT: br label [[FOR_INC_JT2]]
30 ; CHECK-NEXT: [[COUNT1:%.*]] = phi i32 [ [[COUNT_JT2]], [[FOR_BODY_JT2:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
31 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[COUNT1]], 50
32 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_INC_JT1]], label [[SI_UNFOLD_FALSE:%.*]]
33 ; CHECK: si.unfold.false:
34 ; CHECK-NEXT: br label [[FOR_INC_JT2]]
36 ; CHECK-NEXT: [[INC]] = add nsw i32 undef, 1
37 ; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]]
38 ; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
40 ; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SI_UNFOLD_FALSE]] ], [ [[COUNT2]], [[CASE1]] ]
41 ; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ 2, [[SI_UNFOLD_FALSE]] ]
42 ; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1
43 ; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
44 ; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
46 ; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT1]], [[CASE2]] ], [ [[COUNT]], [[FOR_BODY]] ]
47 ; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[CASE2]] ], [ 1, [[FOR_BODY]] ]
48 ; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT3]], 1
49 ; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
50 ; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
52 ; CHECK-NEXT: ret i32 0
58 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
59 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ]
60 switch i32 %state, label %for.inc [
69 %cmp = icmp eq i32 %count, 50
70 %sel = select i1 %cmp, i32 1, i32 2
74 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ]
75 %inc = add nsw i32 %count, 1
76 %cmp.exit = icmp slt i32 %inc, %num
77 br i1 %cmp.exit, label %for.body, label %for.end
84 define i32 @test2(i32 %init) {
85 ; CHECK-LABEL: @test2(
87 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[INIT:%.*]], 0
88 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_1:%.*]], label [[SI_UNFOLD_FALSE1:%.*]]
89 ; CHECK: si.unfold.false:
90 ; CHECK-NEXT: br label [[LOOP_1]]
91 ; CHECK: si.unfold.false.jt2:
92 ; CHECK-NEXT: br label [[LOOP_1_JT2:%.*]]
93 ; CHECK: si.unfold.false.jt4:
94 ; CHECK-NEXT: br label [[LOOP_1_JT4:%.*]]
95 ; CHECK: si.unfold.false1:
96 ; CHECK-NEXT: br label [[LOOP_1]]
98 ; CHECK-NEXT: [[STATE_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ undef, [[SI_UNFOLD_FALSE:%.*]] ], [ 2, [[SI_UNFOLD_FALSE1]] ]
99 ; CHECK-NEXT: br label [[LOOP_2:%.*]]
101 ; CHECK-NEXT: [[STATE_1_JT2:%.*]] = phi i32 [ [[STATE_1_BE_JT2:%.*]], [[SI_UNFOLD_FALSE_JT2:%.*]] ]
102 ; CHECK-NEXT: br label [[LOOP_2_JT2:%.*]]
104 ; CHECK-NEXT: [[STATE_1_JT4:%.*]] = phi i32 [ [[STATE_1_BE_JT4:%.*]], [[SI_UNFOLD_FALSE_JT4:%.*]] ]
105 ; CHECK-NEXT: br label [[LOOP_2_JT4:%.*]]
107 ; CHECK-NEXT: [[STATE_1_JT1:%.*]] = phi i32 [ 1, [[LOOP_1_BACKEDGE:%.*]] ], [ 1, [[LOOP_1_BACKEDGE_JT4:%.*]] ], [ 1, [[LOOP_1_BACKEDGE_JT2:%.*]] ]
108 ; CHECK-NEXT: br label [[LOOP_2_JT1:%.*]]
110 ; CHECK-NEXT: [[STATE_2:%.*]] = phi i32 [ [[STATE_1]], [[LOOP_1]] ], [ poison, [[LOOP_2_BACKEDGE:%.*]] ]
111 ; CHECK-NEXT: br label [[LOOP_3:%.*]]
113 ; CHECK-NEXT: [[STATE_2_JT2:%.*]] = phi i32 [ [[STATE_1_JT2]], [[LOOP_1_JT2]] ]
114 ; CHECK-NEXT: br label [[LOOP_3_JT2:%.*]]
116 ; CHECK-NEXT: [[STATE_2_JT3:%.*]] = phi i32 [ [[STATE_2_BE_JT3:%.*]], [[LOOP_2_BACKEDGE_JT3:%.*]] ]
117 ; CHECK-NEXT: br label [[LOOP_3_JT3:%.*]]
119 ; CHECK-NEXT: [[STATE_2_JT0:%.*]] = phi i32 [ [[STATE_2_BE_JT0:%.*]], [[LOOP_2_BACKEDGE_JT0:%.*]] ]
120 ; CHECK-NEXT: br label [[LOOP_3_JT0:%.*]]
122 ; CHECK-NEXT: [[STATE_2_JT4:%.*]] = phi i32 [ [[STATE_1_JT4]], [[LOOP_1_JT4]] ]
123 ; CHECK-NEXT: br label [[LOOP_3_JT4:%.*]]
125 ; CHECK-NEXT: [[STATE_2_JT1:%.*]] = phi i32 [ [[STATE_1_JT1]], [[LOOP_1_JT1:%.*]] ]
126 ; CHECK-NEXT: br label [[LOOP_3_JT1:%.*]]
128 ; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ [[STATE_2]], [[LOOP_2]] ]
129 ; CHECK-NEXT: switch i32 [[STATE]], label [[INFLOOP_I:%.*]] [
130 ; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
131 ; CHECK-NEXT: i32 3, label [[CASE3:%.*]]
132 ; CHECK-NEXT: i32 4, label [[CASE4:%.*]]
133 ; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
134 ; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
137 ; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_2_JT2]], [[LOOP_2_JT2]] ]
138 ; CHECK-NEXT: br label [[CASE2]]
140 ; CHECK-NEXT: [[STATE_JT0:%.*]] = phi i32 [ [[STATE_2_JT0]], [[LOOP_2_JT0:%.*]] ]
141 ; CHECK-NEXT: br label [[CASE0]]
143 ; CHECK-NEXT: [[STATE_JT4:%.*]] = phi i32 [ [[STATE_2_JT4]], [[LOOP_2_JT4]] ]
144 ; CHECK-NEXT: br label [[CASE4]]
146 ; CHECK-NEXT: [[STATE_JT1:%.*]] = phi i32 [ [[STATE_2_JT1]], [[LOOP_2_JT1]] ]
147 ; CHECK-NEXT: br label [[CASE1]]
149 ; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ 3, [[CASE2]] ], [ [[STATE_2_JT3]], [[LOOP_2_JT3:%.*]] ]
150 ; CHECK-NEXT: br label [[CASE3]]
152 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_3_JT3]], label [[LOOP_1_BACKEDGE_JT4]]
154 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_2_BACKEDGE_JT0]], label [[CASE4]]
156 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_2_BACKEDGE_JT3]], label [[LOOP_1_BACKEDGE_JT2]]
157 ; CHECK: loop.1.backedge:
158 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_1_JT1]], label [[SI_UNFOLD_FALSE]]
159 ; CHECK: loop.1.backedge.jt2:
160 ; CHECK-NEXT: [[STATE_1_BE_JT2]] = phi i32 [ 2, [[CASE4]] ]
161 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_1_JT1]], label [[SI_UNFOLD_FALSE_JT2]]
162 ; CHECK: loop.1.backedge.jt4:
163 ; CHECK-NEXT: [[STATE_1_BE_JT4]] = phi i32 [ 4, [[CASE2]] ]
164 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_1_JT1]], label [[SI_UNFOLD_FALSE_JT4]]
165 ; CHECK: loop.2.backedge:
166 ; CHECK-NEXT: br label [[LOOP_2]]
167 ; CHECK: loop.2.backedge.jt3:
168 ; CHECK-NEXT: [[STATE_2_BE_JT3]] = phi i32 [ 3, [[CASE4]] ]
169 ; CHECK-NEXT: br label [[LOOP_2_JT3]]
170 ; CHECK: loop.2.backedge.jt0:
171 ; CHECK-NEXT: [[STATE_2_BE_JT0]] = phi i32 [ 0, [[CASE3]] ]
172 ; CHECK-NEXT: br label [[LOOP_2_JT0]]
174 ; CHECK-NEXT: br label [[EXIT:%.*]]
176 ; CHECK-NEXT: br label [[EXIT]]
178 ; CHECK-NEXT: br label [[INFLOOP_I]]
180 ; CHECK-NEXT: ret i32 0
183 %cmp = icmp eq i32 %init, 0
184 %sel = select i1 %cmp, i32 0, i32 2
188 %state.1 = phi i32 [ %sel, %entry ], [ %state.1.be2, %loop.1.backedge ]
192 %state.2 = phi i32 [ %state.1, %loop.1 ], [ %state.2.be, %loop.2.backedge ]
196 %state = phi i32 [ %state.2, %loop.2 ], [ 3, %case2 ]
197 switch i32 %state, label %infloop.i [
206 br i1 %cmp, label %loop.3, label %loop.1.backedge
209 br i1 %cmp, label %loop.2.backedge, label %case4
212 br i1 %cmp, label %loop.2.backedge, label %loop.1.backedge
215 %state.1.be = phi i32 [ 2, %case4 ], [ 4, %case2 ]
216 %state.1.be2 = select i1 %cmp, i32 1, i32 %state.1.be
220 %state.2.be = phi i32 [ 3, %case4 ], [ 0, %case3 ]
236 define void @pr78059_bitwidth() {
237 ; CHECK-LABEL: @pr78059_bitwidth(
238 ; CHECK-NEXT: .split.preheader:
239 ; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
241 ; CHECK-NEXT: [[TMP0:%.*]] = phi i128 [ 0, [[DOTSPLIT_PREHEADER:%.*]] ]
242 ; CHECK-NEXT: switch i128 [[TMP0]], label [[END:%.*]] [
243 ; CHECK-NEXT: i128 -1, label [[END]]
244 ; CHECK-NEXT: i128 0, label [[DOTSPLIT_JT18446744073709551615:%.*]]
246 ; CHECK: .split.jt18446744073709551615:
247 ; CHECK-NEXT: [[TMP1:%.*]] = phi i128 [ -1, [[DOTSPLIT]] ]
248 ; CHECK-NEXT: br label [[END]]
250 ; CHECK-NEXT: ret void
256 %0 = phi i128 [ 0, %.split.preheader ], [ -1, %.split ]
257 switch i128 %0, label %end [
259 i128 0, label %.split
266 define void @self-reference() {
267 ; CHECK-LABEL: @self-reference(
268 ; CHECK-NEXT: .split.preheader:
269 ; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
271 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[DOTSPLIT_PREHEADER:%.*]] ]
272 ; CHECK-NEXT: switch i32 [[TMP0]], label [[END:%.*]] [
273 ; CHECK-NEXT: i32 -1, label [[END]]
274 ; CHECK-NEXT: i32 0, label [[DOTSPLIT_JT4294967295:%.*]]
276 ; CHECK: .split.jt4294967295:
277 ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ -1, [[DOTSPLIT]] ]
278 ; CHECK-NEXT: br label [[END]]
280 ; CHECK-NEXT: ret void
286 %0 = phi i32 [ 0, %.split.preheader ], [ -1, %.split ]
287 switch i32 %0, label %end [