[memprof] Move YAML support to MemProfYAML.h (NFC) (#119515)
[llvm-project.git] / llvm / test / Transforms / SimpleLoopUnswitch / nontrivial-unswitch-select.ll
blobc86fa349200c540648813d9c40dc98d8b38aa383
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.
6 declare i1 @foo()
7 declare i1 @bar(i32)
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:%.*]]) {
13 ; CHECK-NEXT:  entry:
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:%.*]]
18 ; CHECK:       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:%.*]]
23 ; CHECK:       for.body.us:
24 ; CHECK-NEXT:    br label [[TMP0:%.*]]
25 ; CHECK:       0:
26 ; CHECK-NEXT:    br label [[TMP1]]
27 ; CHECK:       1:
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:%.*]]
35 ; CHECK:       entry.split:
36 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
37 ; CHECK:       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:%.*]]
42 ; CHECK:       for.body:
43 ; CHECK-NEXT:    br label [[TMP2]]
44 ; CHECK:       2:
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]]
55 entry:
56   br label %for.cond
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
68   br label %for.cond
70 for.cond.cleanup:                                 ; preds = %for.cond
71   ret i32 %res
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:%.*]]) {
77 ; CHECK-NEXT:  entry:
78 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
79 ; CHECK:       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:%.*]]
84 ; CHECK:       for.body:
85 ; CHECK-NEXT:    [[COND1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[SELECT_INPUT]], <2 x i32> splat (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]]
94 entry:
95   br label %for.cond
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
108   br label %for.cond
110 for.cond.cleanup:                                 ; preds = %for.cond
111   ret i32 %res
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:%.*]]) {
117 ; CHECK-NEXT:  entry:
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:%.*]]
129 ; CHECK:       0:
130 ; CHECK-NEXT:    br label [[TMP1]]
131 ; CHECK:       1:
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:%.*]]
141 ; CHECK:       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:%.*]]
146 ; CHECK:       for.body:
147 ; CHECK-NEXT:    br label [[TMP2]]
148 ; CHECK:       2:
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]]
159 entry:
160   br label %for.cond
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
172   br label %for.cond
174 for.cond.cleanup:                                 ; preds = %for.cond
175   ret i32 %res
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:%.*]]) {
181 ; CHECK-NEXT:  entry:
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:%.*]]
192 ; CHECK:       0:
193 ; CHECK-NEXT:    br label [[TMP1]]
194 ; CHECK:       1:
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:%.*]]
204 ; CHECK:       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:%.*]]
209 ; CHECK:       for.body:
210 ; CHECK-NEXT:    br label [[TMP2]]
211 ; CHECK:       2:
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]]
222 entry:
223   br label %for.cond
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
235   br label %for.cond
237 for.cond.cleanup:                                 ; preds = %for.cond
238   ret i32 %res
241 define i32 @cond_invariant(i32 %N) {
242 ; CHECK-LABEL: define i32 @cond_invariant
243 ; CHECK-SAME: (i32 [[N:%.*]]) {
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
246 ; CHECK:       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:%.*]]
251 ; CHECK:       for.body:
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]]
261 entry:
262   br label %for.cond
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
275   br label %for.cond
277 for.cond.cleanup:                                 ; preds = %for.cond
278   ret i32 %res
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:%.*]]) {
284 ; CHECK-NEXT:  entry:
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:%.*]]
299 ; CHECK:       0:
300 ; CHECK-NEXT:    br label [[TMP1:%.*]]
301 ; CHECK:       1:
302 ; CHECK-NEXT:    [[UNSWITCHED_SELECT_US_US:%.*]] = phi i32 [ [[I_US_US]], [[TMP0]] ]
303 ; CHECK-NEXT:    br label [[TMP2:%.*]]
304 ; CHECK:       2:
305 ; CHECK-NEXT:    br label [[TMP3]]
306 ; CHECK:       3:
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:%.*]]
323 ; CHECK:       4:
324 ; CHECK-NEXT:    br label [[TMP5:%.*]]
325 ; CHECK:       5:
326 ; CHECK-NEXT:    [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP4]] ]
327 ; CHECK-NEXT:    br label [[TMP6]]
328 ; CHECK:       6:
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:%.*]]
350 ; CHECK:       7:
351 ; CHECK-NEXT:    br label [[TMP8:%.*]]
352 ; CHECK:       8:
353 ; CHECK-NEXT:    br label [[TMP9]]
354 ; CHECK:       9:
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:%.*]]
364 ; CHECK:       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:%.*]]
369 ; CHECK:       for.body:
370 ; CHECK-NEXT:    br label [[TMP10:%.*]]
371 ; CHECK:       10:
372 ; CHECK-NEXT:    br label [[TMP11]]
373 ; CHECK:       11:
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]]
387 entry:
388   br label %for.cond
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
401   br label %for.cond
403 for.cond.cleanup:                                 ; preds = %for.cond
404   ret i32 %res
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:%.*]]) {
410 ; CHECK-NEXT:  entry:
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]]
431 ; CHECK:       0:
432 ; CHECK-NEXT:    br label [[TMP1]]
433 ; CHECK:       1:
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:%.*]]
441 ; CHECK:       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:%.*]]
446 ; CHECK:       for.body:
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:%.*]]
452 ; CHECK:       2:
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]]
466 entry:
467   br label %for.cond
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
488   br label %for.cond
490 for.cond.cleanup:                                 ; preds = %for.cond
491   ret i32 %res
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:%.*]]) {
497 ; CHECK-NEXT:  entry:
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]]
521 ; CHECK:       0:
522 ; CHECK-NEXT:    br label [[TMP1]]
523 ; CHECK:       1:
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:%.*]]
531 ; CHECK:       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:%.*]]
536 ; CHECK:       for.body:
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:%.*]]
545 ; CHECK:       2:
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]]
559 entry:
560   br label %for.cond
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
585   br label %for.cond
587 for.cond.cleanup:                                 ; preds = %for.cond
588   ret i32 %res
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:%.*]]) {
594 ; CHECK-NEXT:  entry:
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:%.*]]
615 ; CHECK:       0:
616 ; CHECK-NEXT:    br label [[TMP1]]
617 ; CHECK:       1:
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]]
637 ; CHECK:       2:
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
655 entry:
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
679   ret void
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:%.*]]) {
685 ; CHECK-NEXT:  entry:
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:%.*]]
703 ; CHECK:       0:
704 ; CHECK-NEXT:    br label [[TMP1]]
705 ; CHECK:       1:
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]]
718 ; CHECK:       2:
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
734 entry:
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
760   ret void
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:%.*]]) {
767 ; CHECK-NEXT:  entry:
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:%.*]]
778 ; CHECK:       0:
779 ; CHECK-NEXT:    br label [[TMP1]]
780 ; CHECK:       1:
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
796 ; CHECK:       for.body:
797 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ [[INC:%.*]], [[TMP2:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ]
798 ; CHECK-NEXT:    br label [[TMP2]]
799 ; CHECK:       2:
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]]
805 entry:
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
811   ret i32 undef
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:%.*]]) {
826 ; CHECK-NEXT:  entry:
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]]
837 ; CHECK:       0:
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
853 ; CHECK:       for.body:
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]]
859 ; CHECK:       2:
860 ; CHECK-NEXT:    br label [[TMP3]]
861 ; CHECK:       3:
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]]
868 entry:
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
873   ret i32 undef
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:%.*]]) {
891 ; CHECK-NEXT:  entry:
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]]
902 ; CHECK:       0:
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
918 ; CHECK:       for.body:
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]]
924 ; CHECK:       2:
925 ; CHECK-NEXT:    br label [[TMP3]]
926 ; CHECK:       3:
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]]
933 entry:
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
938   ret i32 undef
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:%.*]]) {
956 ; CHECK-NEXT:  entry:
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:%.*]]
967 ; CHECK:       0:
968 ; CHECK-NEXT:    br label [[TMP1]]
969 ; CHECK:       1:
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
985 ; CHECK:       for.body:
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]]
991 ; CHECK:       3:
992 ; CHECK-NEXT:    br label [[TMP4]]
993 ; CHECK:       4:
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]]
1000 entry:
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
1005   ret i32 undef
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:%.*]]
1034 ; CHECK:       0:
1035 ; CHECK-NEXT:    br label [[TMP1]]
1036 ; CHECK:       1:
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
1052 ; CHECK:       for.body:
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]]
1058 ; CHECK:       3:
1059 ; CHECK-NEXT:    br label [[TMP4]]
1060 ; CHECK:       4:
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]]
1067 entry:
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
1072   ret i32 undef
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