xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-select.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
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
3
4; Non-trivial loop unswitching of select instruction.
5
6declare i1 @foo()
7declare i1 @bar(i32)
8declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>)
9
10define 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]]
54;
55entry:
56  br label %for.cond
57
58for.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
63
64for.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
69
70for.cond.cleanup:                                 ; preds = %for.cond
71  ret i32 %res
72}
73
74define 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]]
93;
94entry:
95  br label %for.cond
96
97for.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
102
103for.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
109
110for.cond.cleanup:                                 ; preds = %for.cond
111  ret i32 %res
112}
113
114define 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]]
158;
159entry:
160  br label %for.cond
161
162for.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
167
168for.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
173
174for.cond.cleanup:                                 ; preds = %for.cond
175  ret i32 %res
176}
177
178define 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]]
221;
222entry:
223  br label %for.cond
224
225for.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
230
231for.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
236
237for.cond.cleanup:                                 ; preds = %for.cond
238  ret i32 %res
239}
240
241define 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]]
260;
261entry:
262  br label %for.cond
263
264for.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
269
270for.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
276
277for.cond.cleanup:                                 ; preds = %for.cond
278  ret i32 %res
279}
280
281define 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]]
386;
387entry:
388  br label %for.cond
389
390for.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
395
396for.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
402
403for.cond.cleanup:                                 ; preds = %for.cond
404  ret i32 %res
405}
406
407define 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]]
465;
466entry:
467  br label %for.cond
468
469for.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
474
475for.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
479
480for.body.if:                                      ; preds = %for.body
481  %cond1 = select i1 %cond, i32 %i, i32 42
482  br label %for.body.end
483
484for.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
489
490for.cond.cleanup:                                 ; preds = %for.cond
491  ret i32 %res
492}
493
494define 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]]
558;
559entry:
560  br label %for.cond
561
562for.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
567
568for.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
572
573for.body.if:                                      ; preds = %for.body
574  %cond1a = select i1 %cond, i32 %i, i32 42
575  br label %for.body.end
576
577for.body.else:                                    ; preds = %for.body
578  %cond1b = select i1 %cond, i32 24, i32 %i
579  br label %for.body.end
580
581for.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
586
587for.cond.cleanup:                                 ; preds = %for.cond
588  ret i32 %res
589}
590
591define 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
654;
655entry:
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
660
661for.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
664
665for.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
672
673for.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
677
678for.cond.cleanup:                                 ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
679  ret void
680}
681
682define 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
733;
734entry:
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
739
740for.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
745
746for.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
753
754for.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
758
759for.cond.cleanup:                                 ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
760  ret void
761}
762
763; Unswitch %val should look through the trivial select and unswitch on %cond
764define 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]]
804;
805entry:
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
809
810for.cond.cleanup:                                 ; preds = %for.body, %entry
811  ret i32 undef
812
813for.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
820}
821
822; Test unswitch select when the condition is an AND whose LHS is invariant
823define 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]]
867;
868entry:
869  %cmp6 = icmp sgt i32 %num, 0
870  br i1 %cmp6, label %for.body, label %for.cond.cleanup
871
872for.cond.cleanup:                                 ; preds = %for.body, %entry
873  ret i32 undef
874
875for.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
885}
886
887; Test unswitch select when the condition is an AND whose RHS is invariant
888define 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]]
932;
933entry:
934  %cmp6 = icmp sgt i32 %num, 0
935  br i1 %cmp6, label %for.body, label %for.cond.cleanup
936
937for.cond.cleanup:                                 ; preds = %for.body, %entry
938  ret i32 undef
939
940for.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
950}
951
952; Test unswitch select when the condition is an OR whose LHS is invariant
953define 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]]
999;
1000entry:
1001  %cmp6 = icmp sgt i32 %num, 0
1002  br i1 %cmp6, label %for.body, label %for.cond.cleanup
1003
1004for.cond.cleanup:                                 ; preds = %for.body, %entry
1005  ret i32 undef
1006
1007for.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
1017}
1018
1019; Test unswitch select when the condition is an OR whose RHS is invariant
1020define 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]]
1066;
1067entry:
1068  %cmp6 = icmp sgt i32 %num, 0
1069  br i1 %cmp6, label %for.body, label %for.cond.cleanup
1070
1071for.cond.cleanup:                                 ; preds = %for.body, %entry
1072  ret i32 undef
1073
1074for.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
1084}
1085