1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s
4 ; Non-trivial loop unswitching of select instruction.
8 declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>)
10 define i32 @basic(i32 %N, i1 %cond, i32 %select_input) {
11 ; CHECK-LABEL: define i32 @basic
12 ; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i32 [[SELECT_INPUT:%.*]]) {
14 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
15 ; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
16 ; CHECK: entry.split.us:
17 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
19 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ]
20 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ]
21 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
22 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
24 ; CHECK-NEXT: br label [[TMP0:%.*]]
26 ; CHECK-NEXT: br label [[TMP1]]
28 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[SELECT_INPUT]], [[TMP0]] ]
29 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]]
30 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
31 ; CHECK-NEXT: br label [[FOR_COND_US]]
32 ; CHECK: for.cond.cleanup.split.us:
33 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
34 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
36 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
38 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ]
39 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ]
40 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
41 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]]
43 ; CHECK-NEXT: br label [[TMP2]]
45 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]]
46 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
47 ; CHECK-NEXT: br label [[FOR_COND]]
48 ; CHECK: for.cond.cleanup.split:
49 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
50 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
51 ; CHECK: for.cond.cleanup:
52 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
53 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
58 for.cond: ; preds = %for.body, %entry
59 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
60 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
61 %cmp = icmp slt i32 %i, %N
62 br i1 %cmp, label %for.body, label %for.cond.cleanup
64 for.body: ; preds = %for.cond
65 %cond1 = select i1 %cond, i32 %select_input, i32 42
66 %add = add nuw nsw i32 %cond1, %res
67 %inc = add nuw nsw i32 %i, 1
70 for.cond.cleanup: ; preds = %for.cond
74 define i32 @basic_veccond(i32 %N, <2 x i1> %cond, <2 x i32> %select_input) {
75 ; CHECK-LABEL: define i32 @basic_veccond
76 ; CHECK-SAME: (i32 [[N:%.*]], <2 x i1> [[COND:%.*]], <2 x i32> [[SELECT_INPUT:%.*]]) {
78 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
80 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
81 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
82 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
83 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
85 ; CHECK-NEXT: [[COND1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[SELECT_INPUT]], <2 x i32> <i32 42, i32 42>
86 ; CHECK-NEXT: [[VREDUCE:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[COND1]])
87 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[VREDUCE]], [[RES]]
88 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
89 ; CHECK-NEXT: br label [[FOR_COND]]
90 ; CHECK: for.cond.cleanup:
91 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
92 ; CHECK-NEXT: ret i32 [[RES_LCSSA]]
97 for.cond: ; preds = %for.body, %entry
98 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
99 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
100 %cmp = icmp slt i32 %i, %N
101 br i1 %cmp, label %for.body, label %for.cond.cleanup
103 for.body: ; preds = %for.cond
104 %cond1 = select <2 x i1> %cond, <2 x i32> %select_input, <2 x i32> <i32 42, i32 42>
105 %vreduce = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %cond1)
106 %add = add nuw nsw i32 %vreduce, %res
107 %inc = add nuw nsw i32 %i, 1
110 for.cond.cleanup: ; preds = %for.cond
114 define i32 @select_phi_input(i32 %N, i1 %cond) {
115 ; CHECK-LABEL: define i32 @select_phi_input
116 ; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
118 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
119 ; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
120 ; CHECK: entry.split.us:
121 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
122 ; CHECK: for.cond.us:
123 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ]
124 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ]
125 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
126 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
127 ; CHECK: for.body.us:
128 ; CHECK-NEXT: br label [[TMP0:%.*]]
130 ; CHECK-NEXT: br label [[TMP1]]
132 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP0]] ]
133 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]]
134 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
135 ; CHECK-NEXT: br label [[FOR_COND_US]]
136 ; CHECK: for.cond.cleanup.split.us:
137 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
138 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
139 ; CHECK: entry.split:
140 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
142 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ]
143 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ]
144 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
145 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]]
147 ; CHECK-NEXT: br label [[TMP2]]
149 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]]
150 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
151 ; CHECK-NEXT: br label [[FOR_COND]]
152 ; CHECK: for.cond.cleanup.split:
153 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
154 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
155 ; CHECK: for.cond.cleanup:
156 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
157 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
162 for.cond: ; preds = %for.body, %entry
163 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
164 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
165 %cmp = icmp slt i32 %i, %N
166 br i1 %cmp, label %for.body, label %for.cond.cleanup
168 for.body: ; preds = %for.cond
169 %cond1 = select i1 %cond, i32 %i, i32 42
170 %add = add nuw nsw i32 %cond1, %res
171 %inc = add nuw nsw i32 %i, 1
174 for.cond.cleanup: ; preds = %for.cond
178 define i32 @basic_cond_noundef(i32 %N, i1 noundef %cond) {
179 ; CHECK-LABEL: define i32 @basic_cond_noundef
180 ; CHECK-SAME: (i32 [[N:%.*]], i1 noundef [[COND:%.*]]) {
182 ; CHECK-NEXT: br i1 [[COND]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
183 ; CHECK: entry.split.us:
184 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
185 ; CHECK: for.cond.us:
186 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ]
187 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ]
188 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
189 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
190 ; CHECK: for.body.us:
191 ; CHECK-NEXT: br label [[TMP0:%.*]]
193 ; CHECK-NEXT: br label [[TMP1]]
195 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP0]] ]
196 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]]
197 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
198 ; CHECK-NEXT: br label [[FOR_COND_US]]
199 ; CHECK: for.cond.cleanup.split.us:
200 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
201 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
202 ; CHECK: entry.split:
203 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
205 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ]
206 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ]
207 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
208 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]]
210 ; CHECK-NEXT: br label [[TMP2]]
212 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]]
213 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
214 ; CHECK-NEXT: br label [[FOR_COND]]
215 ; CHECK: for.cond.cleanup.split:
216 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
217 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
218 ; CHECK: for.cond.cleanup:
219 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
220 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
225 for.cond: ; preds = %for.body, %entry
226 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
227 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
228 %cmp = icmp slt i32 %i, %N
229 br i1 %cmp, label %for.body, label %for.cond.cleanup
231 for.body: ; preds = %for.cond
232 %cond1 = select i1 %cond, i32 %i, i32 42
233 %add = add nuw nsw i32 %cond1, %res
234 %inc = add nuw nsw i32 %i, 1
237 for.cond.cleanup: ; preds = %for.cond
241 define i32 @cond_invariant(i32 %N) {
242 ; CHECK-LABEL: define i32 @cond_invariant
243 ; CHECK-SAME: (i32 [[N:%.*]]) {
245 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
247 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
248 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
249 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
250 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
252 ; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
253 ; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
254 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]]
255 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
256 ; CHECK-NEXT: br label [[FOR_COND]]
257 ; CHECK: for.cond.cleanup:
258 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
259 ; CHECK-NEXT: ret i32 [[RES_LCSSA]]
264 for.cond: ; preds = %for.body, %entry
265 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
266 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
267 %cmp = icmp slt i32 %i, %N
268 br i1 %cmp, label %for.body, label %for.cond.cleanup
270 for.body: ; preds = %for.cond
271 %cond = call i1 @foo()
272 %cond1 = select i1 %cond, i32 %i, i32 42
273 %add = add nuw nsw i32 %cond1, %res
274 %inc = add nuw nsw i32 %i, 1
277 for.cond.cleanup: ; preds = %for.cond
281 define i32 @chained_select(i32 %N, i1 %cond, i1 %cond2) {
282 ; CHECK-LABEL: define i32 @chained_select
283 ; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i1 [[COND2:%.*]]) {
285 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
286 ; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
287 ; CHECK: entry.split.us:
288 ; CHECK-NEXT: [[COND2_FR13:%.*]] = freeze i1 [[COND2]]
289 ; CHECK-NEXT: br i1 [[COND2_FR13]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]]
290 ; CHECK: entry.split.us.split.us:
291 ; CHECK-NEXT: br label [[FOR_COND_US_US:%.*]]
292 ; CHECK: for.cond.us.us:
293 ; CHECK-NEXT: [[RES_US_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT_US]] ], [ [[ADD_US_US:%.*]], [[TMP3:%.*]] ]
294 ; CHECK-NEXT: [[I_US_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT_US]] ], [ [[INC_US_US:%.*]], [[TMP3]] ]
295 ; CHECK-NEXT: [[CMP_US_US:%.*]] = icmp slt i32 [[I_US_US]], [[N]]
296 ; CHECK-NEXT: br i1 [[CMP_US_US]], label [[FOR_BODY_US_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US_SPLIT_US:%.*]]
297 ; CHECK: for.body.us.us:
298 ; CHECK-NEXT: br label [[TMP0:%.*]]
300 ; CHECK-NEXT: br label [[TMP1:%.*]]
302 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US_US:%.*]] = phi i32 [ [[I_US_US]], [[TMP0]] ]
303 ; CHECK-NEXT: br label [[TMP2:%.*]]
305 ; CHECK-NEXT: br label [[TMP3]]
307 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US11:%.*]] = phi i32 [ [[UNSWITCHED_SELECT_US_US]], [[TMP2]] ]
308 ; CHECK-NEXT: [[ADD_US_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US11]], [[RES_US_US]]
309 ; CHECK-NEXT: [[INC_US_US]] = add nuw nsw i32 [[I_US_US]], 1
310 ; CHECK-NEXT: br label [[FOR_COND_US_US]]
311 ; CHECK: for.cond.cleanup.split.us.split.us:
312 ; CHECK-NEXT: [[RES_LCSSA_US_US:%.*]] = phi i32 [ [[RES_US_US]], [[FOR_COND_US_US]] ]
313 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
314 ; CHECK: entry.split.us.split:
315 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
316 ; CHECK: for.cond.us:
317 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT]] ], [ [[ADD_US:%.*]], [[TMP6:%.*]] ]
318 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP6]] ]
319 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
320 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US_SPLIT:%.*]]
321 ; CHECK: for.body.us:
322 ; CHECK-NEXT: br label [[TMP4:%.*]]
324 ; CHECK-NEXT: br label [[TMP5:%.*]]
326 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP4]] ]
327 ; CHECK-NEXT: br label [[TMP6]]
329 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 24, [[RES_US]]
330 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
331 ; CHECK-NEXT: br label [[FOR_COND_US]]
332 ; CHECK: for.cond.cleanup.split.us.split:
333 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
334 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT_US]]
335 ; CHECK: for.cond.cleanup.split.us:
336 ; CHECK-NEXT: [[DOTUS_PHI12:%.*]] = phi i32 [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US_SPLIT]] ], [ [[RES_LCSSA_US_US]], [[FOR_COND_CLEANUP_SPLIT_US_SPLIT_US]] ]
337 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
338 ; CHECK: entry.split:
339 ; CHECK-NEXT: [[COND2_FR:%.*]] = freeze i1 [[COND2]]
340 ; CHECK-NEXT: br i1 [[COND2_FR]], label [[ENTRY_SPLIT_SPLIT_US:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]]
341 ; CHECK: entry.split.split.us:
342 ; CHECK-NEXT: br label [[FOR_COND_US1:%.*]]
343 ; CHECK: for.cond.us1:
344 ; CHECK-NEXT: [[RES_US2:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT_US]] ], [ [[ADD_US7:%.*]], [[TMP9:%.*]] ]
345 ; CHECK-NEXT: [[I_US3:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT_US]] ], [ [[INC_US8:%.*]], [[TMP9]] ]
346 ; CHECK-NEXT: [[CMP_US4:%.*]] = icmp slt i32 [[I_US3]], [[N]]
347 ; CHECK-NEXT: br i1 [[CMP_US4]], label [[FOR_BODY_US5:%.*]], label [[FOR_COND_CLEANUP_SPLIT_SPLIT_US:%.*]]
348 ; CHECK: for.body.us5:
349 ; CHECK-NEXT: br label [[TMP7:%.*]]
351 ; CHECK-NEXT: br label [[TMP8:%.*]]
353 ; CHECK-NEXT: br label [[TMP9]]
355 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US6:%.*]] = phi i32 [ 42, [[TMP8]] ]
356 ; CHECK-NEXT: [[ADD_US7]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US6]], [[RES_US2]]
357 ; CHECK-NEXT: [[INC_US8]] = add nuw nsw i32 [[I_US3]], 1
358 ; CHECK-NEXT: br label [[FOR_COND_US1]]
359 ; CHECK: for.cond.cleanup.split.split.us:
360 ; CHECK-NEXT: [[RES_LCSSA_US9:%.*]] = phi i32 [ [[RES_US2]], [[FOR_COND_US1]] ]
361 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT:%.*]]
362 ; CHECK: entry.split.split:
363 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
365 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT]] ], [ [[ADD:%.*]], [[TMP11:%.*]] ]
366 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT]] ], [ [[INC:%.*]], [[TMP11]] ]
367 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
368 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT_SPLIT:%.*]]
370 ; CHECK-NEXT: br label [[TMP10:%.*]]
372 ; CHECK-NEXT: br label [[TMP11]]
374 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 24, [[RES]]
375 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
376 ; CHECK-NEXT: br label [[FOR_COND]]
377 ; CHECK: for.cond.cleanup.split.split:
378 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
379 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT]]
380 ; CHECK: for.cond.cleanup.split:
381 ; CHECK-NEXT: [[DOTUS_PHI10:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT_SPLIT]] ], [ [[RES_LCSSA_US9]], [[FOR_COND_CLEANUP_SPLIT_SPLIT_US]] ]
382 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
383 ; CHECK: for.cond.cleanup:
384 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI10]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[DOTUS_PHI12]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
385 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
390 for.cond: ; preds = %for.body, %entry
391 %res = phi i32 [ 0, %entry ], [ %add, %for.body ]
392 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
393 %cmp = icmp slt i32 %i, %N
394 br i1 %cmp, label %for.body, label %for.cond.cleanup
396 for.body: ; preds = %for.cond
397 %select1 = select i1 %cond, i32 %i, i32 42
398 %select2 = select i1 %cond2, i32 %select1, i32 24
399 %add = add nuw nsw i32 %select2, %res
400 %inc = add nuw nsw i32 %i, 1
403 for.cond.cleanup: ; preds = %for.cond
407 define i32 @select_in_if(i32 %N, i1 %cond) {
408 ; CHECK-LABEL: define i32 @select_in_if
409 ; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
411 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
412 ; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
413 ; CHECK: entry.split.us:
414 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
415 ; CHECK: for.cond.us:
416 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[FOR_BODY_END_US:%.*]] ]
417 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[FOR_BODY_END_US]] ]
418 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
419 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
420 ; CHECK: for.body.us:
421 ; CHECK-NEXT: [[UREM_US:%.*]] = urem i32 [[I_US]], 2
422 ; CHECK-NEXT: [[IF_COND_US:%.*]] = icmp eq i32 [[UREM_US]], 0
423 ; CHECK-NEXT: br i1 [[IF_COND_US]], label [[FOR_BODY_IF_US:%.*]], label [[FOR_BODY_END_US]]
424 ; CHECK: for.body.if.us:
425 ; CHECK-NEXT: br label [[TMP0:%.*]]
426 ; CHECK: for.body.end.us:
427 ; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ [[UNSWITCHED_SELECT_US:%.*]], [[TMP1:%.*]] ], [ 24, [[FOR_BODY_US]] ]
428 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[P_US]], [[RES_US]]
429 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
430 ; CHECK-NEXT: br label [[FOR_COND_US]]
432 ; CHECK-NEXT: br label [[TMP1]]
434 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US]] = phi i32 [ [[I_US]], [[TMP0]] ]
435 ; CHECK-NEXT: br label [[FOR_BODY_END_US]]
436 ; CHECK: for.cond.cleanup.split.us:
437 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
438 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
439 ; CHECK: entry.split:
440 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
442 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ]
443 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ]
444 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
445 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]]
447 ; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2
448 ; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0
449 ; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_END]]
450 ; CHECK: for.body.if:
451 ; CHECK-NEXT: br label [[TMP2:%.*]]
453 ; CHECK-NEXT: br label [[FOR_BODY_END]]
454 ; CHECK: for.body.end:
455 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 42, [[TMP2]] ], [ 24, [[FOR_BODY]] ]
456 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]]
457 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
458 ; CHECK-NEXT: br label [[FOR_COND]]
459 ; CHECK: for.cond.cleanup.split:
460 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
461 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
462 ; CHECK: for.cond.cleanup:
463 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
464 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
469 for.cond: ; preds = %for.body.end, %entry
470 %res = phi i32 [ 0, %entry ], [ %add, %for.body.end ]
471 %i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ]
472 %cmp = icmp slt i32 %i, %N
473 br i1 %cmp, label %for.body, label %for.cond.cleanup
475 for.body: ; preds = %for.cond
476 %urem = urem i32 %i, 2
477 %if.cond = icmp eq i32 %urem, 0
478 br i1 %if.cond, label %for.body.if, label %for.body.end
480 for.body.if: ; preds = %for.body
481 %cond1 = select i1 %cond, i32 %i, i32 42
482 br label %for.body.end
484 for.body.end: ; preds = %for.body, %for.body.if
485 %p = phi i32 [ %cond1, %for.body.if ], [ 24, %for.body ]
486 %add = add nuw nsw i32 %p, %res
487 %inc = add nuw nsw i32 %i, 1
490 for.cond.cleanup: ; preds = %for.cond
494 define i32 @select_in_if_else(i32 %N, i1 %cond) {
495 ; CHECK-LABEL: define i32 @select_in_if_else
496 ; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
498 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
499 ; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
500 ; CHECK: entry.split.us:
501 ; CHECK-NEXT: br label [[FOR_COND_US:%.*]]
502 ; CHECK: for.cond.us:
503 ; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[FOR_BODY_END_US:%.*]] ]
504 ; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[FOR_BODY_END_US]] ]
505 ; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]]
506 ; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]]
507 ; CHECK: for.body.us:
508 ; CHECK-NEXT: [[UREM_US:%.*]] = urem i32 [[I_US]], 2
509 ; CHECK-NEXT: [[IF_COND_US:%.*]] = icmp eq i32 [[UREM_US]], 0
510 ; CHECK-NEXT: br i1 [[IF_COND_US]], label [[FOR_BODY_IF_US:%.*]], label [[FOR_BODY_ELSE_US:%.*]]
511 ; CHECK: for.body.else.us:
512 ; CHECK-NEXT: br label [[TMP0:%.*]]
513 ; CHECK: for.body.if.us:
514 ; CHECK-NEXT: [[COND1A_US:%.*]] = select i1 true, i32 [[I_US]], i32 42
515 ; CHECK-NEXT: br label [[FOR_BODY_END_US]]
516 ; CHECK: for.body.end.us:
517 ; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ [[COND1A_US]], [[FOR_BODY_IF_US]] ], [ [[UNSWITCHED_SELECT_US:%.*]], [[TMP1:%.*]] ]
518 ; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[P_US]], [[RES_US]]
519 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1
520 ; CHECK-NEXT: br label [[FOR_COND_US]]
522 ; CHECK-NEXT: br label [[TMP1]]
524 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US]] = phi i32 [ 24, [[TMP0]] ]
525 ; CHECK-NEXT: br label [[FOR_BODY_END_US]]
526 ; CHECK: for.cond.cleanup.split.us:
527 ; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ]
528 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]]
529 ; CHECK: entry.split:
530 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
532 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ]
533 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ]
534 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
535 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]]
537 ; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2
538 ; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0
539 ; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_ELSE:%.*]]
540 ; CHECK: for.body.if:
541 ; CHECK-NEXT: [[COND1A:%.*]] = select i1 false, i32 [[I]], i32 42
542 ; CHECK-NEXT: br label [[FOR_BODY_END]]
543 ; CHECK: for.body.else:
544 ; CHECK-NEXT: br label [[TMP2:%.*]]
546 ; CHECK-NEXT: br label [[FOR_BODY_END]]
547 ; CHECK: for.body.end:
548 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[COND1A]], [[FOR_BODY_IF]] ], [ [[I]], [[TMP2]] ]
549 ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]]
550 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
551 ; CHECK-NEXT: br label [[FOR_COND]]
552 ; CHECK: for.cond.cleanup.split:
553 ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
554 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
555 ; CHECK: for.cond.cleanup:
556 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ]
557 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
562 for.cond: ; preds = %for.body.end, %entry
563 %res = phi i32 [ 0, %entry ], [ %add, %for.body.end ]
564 %i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ]
565 %cmp = icmp slt i32 %i, %N
566 br i1 %cmp, label %for.body, label %for.cond.cleanup
568 for.body: ; preds = %for.cond
569 %urem = urem i32 %i, 2
570 %if.cond = icmp eq i32 %urem, 0
571 br i1 %if.cond, label %for.body.if, label %for.body.else
573 for.body.if: ; preds = %for.body
574 %cond1a = select i1 %cond, i32 %i, i32 42
575 br label %for.body.end
577 for.body.else: ; preds = %for.body
578 %cond1b = select i1 %cond, i32 24, i32 %i
579 br label %for.body.end
581 for.body.end: ; preds = %for.body.if, %for.body.else
582 %p = phi i32 [ %cond1a, %for.body.if ], [ %cond1b, %for.body.else ]
583 %add = add nuw nsw i32 %p, %res
584 %inc = add nuw nsw i32 %i, 1
587 for.cond.cleanup: ; preds = %for.cond
591 define dso_local void @select_nested_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) {
592 ; CHECK-LABEL: define dso_local void @select_nested_loop
593 ; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) {
595 ; CHECK-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N]], 0
596 ; CHECK-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M]], 0
597 ; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP17_NOT]], [[CMP215_NOT]]
598 ; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
599 ; CHECK: for.cond1.preheader.us.preheader:
600 ; CHECK-NEXT: br i1 [[COND]], label [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT:%.*]]
601 ; CHECK: for.cond1.preheader.us.preheader.split.us:
602 ; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_US:%.*]]
603 ; CHECK: for.cond1.preheader.us.us:
604 ; CHECK-NEXT: [[I_018_US_US:%.*]] = phi i32 [ [[INC7_US_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT_US]] ]
605 ; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_SPLIT_US_US:%.*]]
606 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.us:
607 ; CHECK-NEXT: [[INC7_US_US]] = add nuw i32 [[I_018_US_US]], 1
608 ; CHECK-NEXT: [[EXITCOND21_NOT_US:%.*]] = icmp eq i32 [[INC7_US_US]], [[N]]
609 ; CHECK-NEXT: br i1 [[EXITCOND21_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_US]]
610 ; CHECK: for.cond1.preheader.us.split.us.us:
611 ; CHECK-NEXT: br label [[FOR_BODY4_US_US_US:%.*]]
612 ; CHECK: for.body4.us.us.us:
613 ; CHECK-NEXT: [[J_016_US_US_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT_US_US]] ], [ [[INC_US_US_US:%.*]], [[TMP1:%.*]] ]
614 ; CHECK-NEXT: br label [[TMP0:%.*]]
616 ; CHECK-NEXT: br label [[TMP1]]
618 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US_US:%.*]] = phi i32 [ [[I_018_US_US]], [[TMP0]] ]
619 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US_US]])
620 ; CHECK-NEXT: [[INC_US_US_US]] = add nuw i32 [[J_016_US_US_US]], 1
621 ; CHECK-NEXT: [[EXITCOND_NOT_US_US:%.*]] = icmp eq i32 [[INC_US_US_US]], [[M]]
622 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT_US_US:%.*]], label [[FOR_BODY4_US_US_US]]
623 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split.us.us:
624 ; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_US]]
625 ; CHECK: for.cond.cleanup.loopexit.split.us:
626 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
627 ; CHECK: for.cond1.preheader.us.preheader.split:
628 ; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
629 ; CHECK: for.cond1.preheader.us:
630 ; CHECK-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC7_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT]] ]
631 ; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_SPLIT:%.*]]
632 ; CHECK: for.cond1.preheader.us.split:
633 ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
634 ; CHECK: for.body4.us:
635 ; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP2:%.*]] ]
636 ; CHECK-NEXT: br label [[TMP2]]
638 ; CHECK-NEXT: tail call void @bar(i32 noundef [[J_016_US]])
639 ; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_016_US]], 1
640 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]]
641 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT:%.*]], label [[FOR_BODY4_US]]
642 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split:
643 ; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
644 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
645 ; CHECK-NEXT: [[INC7_US]] = add nuw i32 [[I_018_US]], 1
646 ; CHECK-NEXT: [[EXITCOND21_NOT:%.*]] = icmp eq i32 [[INC7_US]], [[N]]
647 ; CHECK-NEXT: br i1 [[EXITCOND21_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_COND1_PREHEADER_US]]
648 ; CHECK: for.cond.cleanup.loopexit.split:
649 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
650 ; CHECK: for.cond.cleanup.loopexit:
651 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
652 ; CHECK: for.cond.cleanup:
653 ; CHECK-NEXT: ret void
656 %cmp17.not = icmp eq i32 %n, 0
657 %cmp215.not = icmp eq i32 %m, 0
658 %or.cond = or i1 %cmp17.not, %cmp215.not
659 br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us
661 for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us
662 %i.018.us = phi i32 [ %inc7.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ]
663 br label %for.body4.us
665 for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us
666 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
667 %cond5.us = select i1 %cond, i32 %i.018.us, i32 %j.016.us
668 tail call void @bar(i32 noundef %cond5.us) #2
669 %inc.us = add nuw i32 %j.016.us, 1
670 %exitcond.not = icmp eq i32 %inc.us, %m
671 br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us
673 for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us
674 %inc7.us = add nuw i32 %i.018.us, 1
675 %exitcond21.not = icmp eq i32 %inc7.us, %n
676 br i1 %exitcond21.not, label %for.cond.cleanup, label %for.cond1.preheader.us
678 for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
682 define dso_local void @select_invariant_outer_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) {
683 ; CHECK-LABEL: define dso_local void @select_invariant_outer_loop
684 ; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) {
686 ; CHECK-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N]], 0
687 ; CHECK-NEXT: [[CMP218_NOT:%.*]] = icmp eq i32 [[M]], 0
688 ; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP20_NOT]], [[CMP218_NOT]]
689 ; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
690 ; CHECK: for.cond1.preheader.us.preheader:
691 ; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
692 ; CHECK: for.cond1.preheader.us:
693 ; CHECK-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC9_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
694 ; CHECK-NEXT: [[REM_US:%.*]] = and i32 [[I_021_US]], 1
695 ; CHECK-NEXT: [[CMP5_US:%.*]] = icmp eq i32 [[REM_US]], 0
696 ; CHECK-NEXT: [[CMP5_US_FR:%.*]] = freeze i1 [[CMP5_US]]
697 ; CHECK-NEXT: br i1 [[CMP5_US_FR]], label [[FOR_COND1_PREHEADER_US_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_SPLIT:%.*]]
698 ; CHECK: for.cond1.preheader.us.split.us:
699 ; CHECK-NEXT: br label [[FOR_BODY4_US_US:%.*]]
700 ; CHECK: for.body4.us.us:
701 ; CHECK-NEXT: [[J_019_US_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT_US]] ], [ [[INC_US_US:%.*]], [[TMP1:%.*]] ]
702 ; CHECK-NEXT: br label [[TMP0:%.*]]
704 ; CHECK-NEXT: br label [[TMP1]]
706 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_021_US]], [[TMP0]] ]
707 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
708 ; CHECK-NEXT: [[INC_US_US]] = add nuw i32 [[J_019_US_US]], 1
709 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US_US]], [[M]]
710 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT_US:%.*]], label [[FOR_BODY4_US_US]]
711 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split.us:
712 ; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
713 ; CHECK: for.cond1.preheader.us.split:
714 ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
715 ; CHECK: for.body4.us:
716 ; CHECK-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP2:%.*]] ]
717 ; CHECK-NEXT: br label [[TMP2]]
719 ; CHECK-NEXT: tail call void @bar(i32 noundef [[J_019_US]])
720 ; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1
721 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]]
722 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT:%.*]], label [[FOR_BODY4_US]]
723 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split:
724 ; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
725 ; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
726 ; CHECK-NEXT: [[INC9_US]] = add nuw i32 [[I_021_US]], 1
727 ; CHECK-NEXT: [[EXITCOND24_NOT:%.*]] = icmp eq i32 [[INC9_US]], [[N]]
728 ; CHECK-NEXT: br i1 [[EXITCOND24_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_COND1_PREHEADER_US]]
729 ; CHECK: for.cond.cleanup.loopexit:
730 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
731 ; CHECK: for.cond.cleanup:
732 ; CHECK-NEXT: ret void
735 %cmp20.not = icmp eq i32 %n, 0
736 %cmp218.not = icmp eq i32 %m, 0
737 %or.cond = or i1 %cmp20.not, %cmp218.not
738 br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us
740 for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us
741 %i.021.us = phi i32 [ %inc9.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ]
742 %rem.us = and i32 %i.021.us, 1
743 %cmp5.us = icmp eq i32 %rem.us, 0
744 br label %for.body4.us
746 for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us
747 %j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
748 %cond7.us = select i1 %cmp5.us, i32 %i.021.us, i32 %j.019.us
749 tail call void @bar(i32 noundef %cond7.us) #2
750 %inc.us = add nuw i32 %j.019.us, 1
751 %exitcond.not = icmp eq i32 %inc.us, %m
752 br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us
754 for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us
755 %inc9.us = add nuw i32 %i.021.us, 1
756 %exitcond24.not = icmp eq i32 %inc9.us, %n
757 br i1 %exitcond24.not, label %for.cond.cleanup, label %for.cond1.preheader.us
759 for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
763 ; Unswitch %val should look through the trivial select and unswitch on %cond
764 define dso_local i32 @trivial_select_cond(i32 noundef %n, i32 noundef %a, i32 noundef %b, i1 noundef %cond) {
765 ; CHECK-LABEL: define dso_local i32 @trivial_select_cond
766 ; CHECK-SAME: (i32 noundef [[N:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i1 noundef [[COND:%.*]]) {
768 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[N]], 0
769 ; CHECK-NEXT: [[TRIVIAL_COND:%.*]] = select i1 [[COND]], i1 true, i1 false
770 ; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
771 ; CHECK: for.body.preheader:
772 ; CHECK-NEXT: br i1 [[COND]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]]
773 ; CHECK: for.body.preheader.split.us:
774 ; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
775 ; CHECK: for.body.us:
776 ; CHECK-NEXT: [[I_03_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ]
777 ; CHECK-NEXT: br label [[TMP0:%.*]]
779 ; CHECK-NEXT: br label [[TMP1]]
781 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[A]], [[TMP0]] ]
782 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
783 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_03_US]], 1
784 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[N]]
785 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]]
786 ; CHECK: for.cond.cleanup.loopexit.split.us:
787 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
788 ; CHECK: for.body.preheader.split:
789 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
790 ; CHECK: for.cond.cleanup.loopexit.split:
791 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
792 ; CHECK: for.cond.cleanup.loopexit:
793 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
794 ; CHECK: for.cond.cleanup:
795 ; CHECK-NEXT: ret i32 undef
797 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ [[INC:%.*]], [[TMP2:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
798 ; CHECK-NEXT: br label [[TMP2]]
800 ; CHECK-NEXT: tail call void @bar(i32 noundef [[B]])
801 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1
802 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
803 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]]
806 %cmp2 = icmp sgt i32 %n, 0
807 %trivial_cond = select i1 %cond, i1 true, i1 false
808 br i1 %cmp2, label %for.body, label %for.cond.cleanup
810 for.cond.cleanup: ; preds = %for.body, %entry
813 for.body: ; preds = %entry, %for.body
814 %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
815 %val = select i1 %trivial_cond, i32 %a, i32 %b
816 tail call void @bar(i32 noundef %val)
817 %inc = add nuw nsw i32 %i.03, 1
818 %exitcond.not = icmp eq i32 %inc, %n
819 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
822 ; Test unswitch select when the condition is an AND whose LHS is invariant
823 define i32 @and_lhs_invariant(i32 %num, i1 %cond) {
824 ; CHECK-LABEL: define i32 @and_lhs_invariant
825 ; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) {
827 ; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0
828 ; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
829 ; CHECK: for.body.preheader:
830 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
831 ; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]]
832 ; CHECK: for.body.preheader.split.us:
833 ; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
834 ; CHECK: for.body.us:
835 ; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP0:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ]
836 ; CHECK-NEXT: br label [[TMP0]]
838 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ 0, [[FOR_BODY_US]] ]
839 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
840 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1
841 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]]
842 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]]
843 ; CHECK: for.cond.cleanup.loopexit.split.us:
844 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
845 ; CHECK: for.body.preheader.split:
846 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
847 ; CHECK: for.cond.cleanup.loopexit.split:
848 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
849 ; CHECK: for.cond.cleanup.loopexit:
850 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
851 ; CHECK: for.cond.cleanup:
852 ; CHECK-NEXT: ret i32 undef
854 ; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP3:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
855 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1
856 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0
857 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[CMP1]]
858 ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3]]
860 ; CHECK-NEXT: br label [[TMP3]]
862 ; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP2]] ], [ 0, [[FOR_BODY]] ]
863 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]])
864 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1
865 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]
866 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]]
869 %cmp6 = icmp sgt i32 %num, 0
870 br i1 %cmp6, label %for.body, label %for.cond.cleanup
872 for.cond.cleanup: ; preds = %for.body, %entry
875 for.body: ; preds = %entry, %for.body
876 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
877 %rem = and i32 %i.07, 1
878 %cmp1 = icmp eq i32 %rem, 0
879 %0 = and i1 %cond, %cmp1
880 %cond2 = select i1 %0, i32 %i.07, i32 0
881 tail call void @bar(i32 noundef %cond2)
882 %inc = add nuw nsw i32 %i.07, 1
883 %exitcond.not = icmp eq i32 %inc, %num
884 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
887 ; Test unswitch select when the condition is an AND whose RHS is invariant
888 define i32 @and_rhs_invariant(i32 %num, i1 %cond) {
889 ; CHECK-LABEL: define i32 @and_rhs_invariant
890 ; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) {
892 ; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0
893 ; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
894 ; CHECK: for.body.preheader:
895 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
896 ; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]]
897 ; CHECK: for.body.preheader.split.us:
898 ; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
899 ; CHECK: for.body.us:
900 ; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP0:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ]
901 ; CHECK-NEXT: br label [[TMP0]]
903 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ 0, [[FOR_BODY_US]] ]
904 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
905 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1
906 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]]
907 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]]
908 ; CHECK: for.cond.cleanup.loopexit.split.us:
909 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
910 ; CHECK: for.body.preheader.split:
911 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
912 ; CHECK: for.cond.cleanup.loopexit.split:
913 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
914 ; CHECK: for.cond.cleanup.loopexit:
915 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
916 ; CHECK: for.cond.cleanup:
917 ; CHECK-NEXT: ret i32 undef
919 ; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP3:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
920 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1
921 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0
922 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CMP1]], true
923 ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3]]
925 ; CHECK-NEXT: br label [[TMP3]]
927 ; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP2]] ], [ 0, [[FOR_BODY]] ]
928 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]])
929 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1
930 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]
931 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]]
934 %cmp6 = icmp sgt i32 %num, 0
935 br i1 %cmp6, label %for.body, label %for.cond.cleanup
937 for.cond.cleanup: ; preds = %for.body, %entry
940 for.body: ; preds = %entry, %for.body
941 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
942 %rem = and i32 %i.07, 1
943 %cmp1 = icmp eq i32 %rem, 0
944 %0 = and i1 %cmp1, %cond
945 %cond2 = select i1 %0, i32 %i.07, i32 0
946 tail call void @bar(i32 noundef %cond2)
947 %inc = add nuw nsw i32 %i.07, 1
948 %exitcond.not = icmp eq i32 %inc, %num
949 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
952 ; Test unswitch select when the condition is an OR whose LHS is invariant
953 define i32 @or_lhs_invariant(i32 %num, i1 %cond) {
954 ; CHECK-LABEL: define i32 @or_lhs_invariant
955 ; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) {
957 ; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0
958 ; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
959 ; CHECK: for.body.preheader:
960 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
961 ; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]]
962 ; CHECK: for.body.preheader.split.us:
963 ; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
964 ; CHECK: for.body.us:
965 ; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ]
966 ; CHECK-NEXT: br label [[TMP0:%.*]]
968 ; CHECK-NEXT: br label [[TMP1]]
970 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_07_US]], [[TMP0]] ]
971 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
972 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1
973 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]]
974 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]]
975 ; CHECK: for.cond.cleanup.loopexit.split.us:
976 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
977 ; CHECK: for.body.preheader.split:
978 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
979 ; CHECK: for.cond.cleanup.loopexit.split:
980 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
981 ; CHECK: for.cond.cleanup.loopexit:
982 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
983 ; CHECK: for.cond.cleanup:
984 ; CHECK-NEXT: ret i32 undef
986 ; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP4:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
987 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1
988 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0
989 ; CHECK-NEXT: [[TMP2:%.*]] = or i1 false, [[CMP1]]
990 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4]]
992 ; CHECK-NEXT: br label [[TMP4]]
994 ; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP3]] ], [ 0, [[FOR_BODY]] ]
995 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]])
996 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1
997 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]
998 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]]
1001 %cmp6 = icmp sgt i32 %num, 0
1002 br i1 %cmp6, label %for.body, label %for.cond.cleanup
1004 for.cond.cleanup: ; preds = %for.body, %entry
1007 for.body: ; preds = %entry, %for.body
1008 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
1009 %rem = and i32 %i.07, 1
1010 %cmp1 = icmp eq i32 %rem, 0
1011 %0 = or i1 %cond, %cmp1
1012 %cond2 = select i1 %0, i32 %i.07, i32 0
1013 tail call void @bar(i32 noundef %cond2)
1014 %inc = add nuw nsw i32 %i.07, 1
1015 %exitcond.not = icmp eq i32 %inc, %num
1016 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1019 ; Test unswitch select when the condition is an OR whose RHS is invariant
1020 define i32 @or_rhs_invariant(i32 %num, i1 %cond) {
1021 ; CHECK-LABEL: define i32 @or_rhs_invariant
1022 ; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) {
1023 ; CHECK-NEXT: entry:
1024 ; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0
1025 ; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
1026 ; CHECK: for.body.preheader:
1027 ; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
1028 ; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]]
1029 ; CHECK: for.body.preheader.split.us:
1030 ; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
1031 ; CHECK: for.body.us:
1032 ; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ]
1033 ; CHECK-NEXT: br label [[TMP0:%.*]]
1035 ; CHECK-NEXT: br label [[TMP1]]
1037 ; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_07_US]], [[TMP0]] ]
1038 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]])
1039 ; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1
1040 ; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]]
1041 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]]
1042 ; CHECK: for.cond.cleanup.loopexit.split.us:
1043 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
1044 ; CHECK: for.body.preheader.split:
1045 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
1046 ; CHECK: for.cond.cleanup.loopexit.split:
1047 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]]
1048 ; CHECK: for.cond.cleanup.loopexit:
1049 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
1050 ; CHECK: for.cond.cleanup:
1051 ; CHECK-NEXT: ret i32 undef
1053 ; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP4:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
1054 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1
1055 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0
1056 ; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[CMP1]], false
1057 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4]]
1059 ; CHECK-NEXT: br label [[TMP4]]
1061 ; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP3]] ], [ 0, [[FOR_BODY]] ]
1062 ; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]])
1063 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1
1064 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]
1065 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]]
1068 %cmp6 = icmp sgt i32 %num, 0
1069 br i1 %cmp6, label %for.body, label %for.cond.cleanup
1071 for.cond.cleanup: ; preds = %for.body, %entry
1074 for.body: ; preds = %entry, %for.body
1075 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
1076 %rem = and i32 %i.07, 1
1077 %cmp1 = icmp eq i32 %rem, 0
1078 %0 = or i1 %cmp1, %cond
1079 %cond2 = select i1 %0, i32 %i.07, i32 0
1080 tail call void @bar(i32 noundef %cond2)
1081 %inc = add nuw nsw i32 %i.07, 1
1082 %exitcond.not = icmp eq i32 %inc, %num
1083 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body