1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -freeze-loop-unswitch-cond -passes='loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
3; RUN: opt -freeze-loop-unswitch-cond -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
4; RUN: opt -freeze-loop-unswitch-cond -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S < %s | FileCheck %s
5
6declare i32 @a()
7declare i32 @b()
8declare i32 @c()
9declare i32 @d()
10
11declare void @sink1(i32)
12declare void @sink2(i32)
13declare void @sink3(i1)
14declare void @sink4(i1)
15
16declare i1 @cond()
17declare i32 @cond.i32()
18
19declare i32 @__CxxFrameHandler3(...)
20
21define i32 @test1_freeze(i1* %ptr0, i1* %ptr1, i1* %ptr2) {
22; CHECK-LABEL: @test1_freeze(
23; CHECK-NEXT:  entry:
24; CHECK-NEXT:    [[COND1:%.*]] = load i1, i1* [[PTR1:%.*]], align 1
25; CHECK-NEXT:    [[COND2:%.*]] = load i1, i1* [[PTR2:%.*]], align 1
26; CHECK-NEXT:    br i1 [[COND1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
27; CHECK:       entry.split.us:
28; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
29; CHECK:       loop_begin.us:
30; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
31; CHECK:       loop_a.us:
32; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @a()
33; CHECK-NEXT:    br label [[LATCH_US:%.*]]
34; CHECK:       latch.us:
35; CHECK-NEXT:    [[V_US:%.*]] = load i1, i1* [[PTR0:%.*]], align 1
36; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
37; CHECK:       loop_exit.split.us:
38; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
39; CHECK:       entry.split:
40; CHECK-NEXT:    [[COND2_FR:%.*]] = freeze i1 [[COND2]]
41; CHECK-NEXT:    br i1 [[COND2_FR]], label [[ENTRY_SPLIT_SPLIT_US:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]]
42; CHECK:       entry.split.split.us:
43; CHECK-NEXT:    br label [[LOOP_BEGIN_US1:%.*]]
44; CHECK:       loop_begin.us1:
45; CHECK-NEXT:    br label [[LOOP_B_US:%.*]]
46; CHECK:       loop_b.us:
47; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @b()
48; CHECK-NEXT:    br label [[LOOP_B_A_US:%.*]]
49; CHECK:       loop_b_a.us:
50; CHECK-NEXT:    call void @sink3(i1 true)
51; CHECK-NEXT:    br label [[LATCH_US2:%.*]]
52; CHECK:       latch.us2:
53; CHECK-NEXT:    [[V_US3:%.*]] = load i1, i1* [[PTR0]], align 1
54; CHECK-NEXT:    br i1 [[V_US3]], label [[LOOP_BEGIN_US1]], label [[LOOP_EXIT_SPLIT_SPLIT_US:%.*]]
55; CHECK:       loop_exit.split.split.us:
56; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]
57; CHECK:       entry.split.split:
58; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
59; CHECK:       loop_begin:
60; CHECK-NEXT:    br label [[LOOP_B:%.*]]
61; CHECK:       loop_b:
62; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @b()
63; CHECK-NEXT:    br label [[LOOP_B_B:%.*]]
64; CHECK:       loop_b_b:
65; CHECK-NEXT:    call void @sink4(i1 false)
66; CHECK-NEXT:    br label [[LATCH:%.*]]
67; CHECK:       latch:
68; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR0]], align 1
69; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT_SPLIT:%.*]]
70; CHECK:       loop_exit.split.split:
71; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]
72; CHECK:       loop_exit.split:
73; CHECK-NEXT:    br label [[LOOP_EXIT]]
74; CHECK:       loop_exit:
75; CHECK-NEXT:    ret i32 0
76;
77entry:
78  %cond1 = load i1, i1* %ptr1
79  %cond2 = load i1, i1* %ptr2
80  br label %loop_begin
81
82loop_begin:
83  br i1 %cond1, label %loop_a, label %loop_b
84
85loop_a:
86  call i32 @a()
87  br label %latch
88; The 'loop_a' unswitched loop.
89
90loop_b:
91  call i32 @b()
92  br i1 %cond2, label %loop_b_a, label %loop_b_b
93; The second unswitched condition.
94
95loop_b_a:
96  call void @sink3(i1 %cond2)
97  br label %latch
98; The 'loop_b_a' unswitched loop.
99; %cond2 is replaced to true
100
101loop_b_b:
102  call void @sink4(i1 %cond2)
103  br label %latch
104; The 'loop_b_b' unswitched loop.
105; %cond2 is replaced to false
106
107latch:
108  %v = load i1, i1* %ptr0
109  br i1 %v, label %loop_begin, label %loop_exit
110
111loop_exit:
112  ret i32 0
113}
114
115; Test that when unswitching a deeply nested loop condition in a way that
116; produces a non-loop clone that can reach multiple exit blocks which are part
117; of different outer loops we correctly divide the cloned loop blocks between
118; the outer loops based on reachability.
119define i32 @test7a(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
120; CHECK-LABEL: @test7a(
121; CHECK-NEXT:  entry:
122; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
123; CHECK:       loop_begin:
124; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
125; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
126; CHECK:       inner_loop_begin:
127; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]
128; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
129; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
130; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
131; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]
132; CHECK:       inner_loop_begin.split.us:
133; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
134; CHECK:       inner_inner_loop_begin.us:
135; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
136; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]
137; CHECK:       inner_inner_loop_b.us:
138; CHECK-NEXT:    [[V3_US:%.*]] = load i1, i1* [[PTR]], align 1
139; CHECK-NEXT:    br i1 [[V3_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US_LOOPEXIT:%.*]]
140; CHECK:       inner_inner_loop_a.us:
141; CHECK-NEXT:    [[A_PHI_LCSSA10:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_BEGIN_US]] ]
142; CHECK-NEXT:    [[B_LCSSA6:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_BEGIN_US]] ]
143; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
144; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US:%.*]]
145; CHECK:       inner_inner_loop_c.us.loopexit:
146; CHECK-NEXT:    br label [[INNER_INNER_LOOP_C_US]]
147; CHECK:       inner_inner_loop_c.us:
148; CHECK-NEXT:    [[V4_US:%.*]] = load i1, i1* [[PTR]], align 1
149; CHECK-NEXT:    br i1 [[V4_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_D_US:%.*]]
150; CHECK:       inner_inner_loop_d.us:
151; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]]
152; CHECK:       inner_inner_loop_exit.split.us:
153; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
154; CHECK:       loop_exit.split.us:
155; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_PHI_LCSSA10]], [[INNER_INNER_LOOP_A_US]] ]
156; CHECK-NEXT:    [[B_LCSSA_US:%.*]] = phi i32 [ [[B_LCSSA6]], [[INNER_INNER_LOOP_A_US]] ]
157; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
158; CHECK:       inner_loop_exit.loopexit.split.us:
159; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
160; CHECK:       inner_loop_begin.split:
161; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
162; CHECK:       inner_inner_loop_begin:
163; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
164; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]
165; CHECK:       inner_inner_loop_a:
166; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
167; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C:%.*]]
168; CHECK:       inner_inner_loop_b:
169; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
170; CHECK-NEXT:    br i1 [[V3]], label [[INNER_INNER_LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C]]
171; CHECK:       inner_inner_loop_c:
172; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
173; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_D:%.*]]
174; CHECK:       inner_inner_loop_d:
175; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]
176; CHECK:       inner_inner_loop_exit.split:
177; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
178; CHECK:       inner_inner_loop_exit:
179; CHECK-NEXT:    [[A2]] = load i32, i32* [[A_PTR]], align 4
180; CHECK-NEXT:    [[V5:%.*]] = load i1, i1* [[PTR]], align 1
181; CHECK-NEXT:    br i1 [[V5]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]
182; CHECK:       inner_loop_exit.loopexit.split:
183; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]
184; CHECK:       inner_loop_exit.loopexit:
185; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
186; CHECK:       inner_loop_exit.loopexit1:
187; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
188; CHECK:       inner_loop_exit:
189; CHECK-NEXT:    br label [[LOOP_BEGIN]]
190; CHECK:       loop_exit.split:
191; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A]] ]
192; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_A]] ]
193; CHECK-NEXT:    br label [[LOOP_EXIT]]
194; CHECK:       loop_exit:
195; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
196; CHECK-NEXT:    [[DOTUS_PHI2:%.*]] = phi i32 [ [[B_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[B_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
197; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[DOTUS_PHI]], [[DOTUS_PHI2]]
198; CHECK-NEXT:    ret i32 [[RESULT]]
199;
200entry:
201  br label %loop_begin
202
203loop_begin:
204  %a = load i32, i32* %a.ptr
205  br label %inner_loop_begin
206
207inner_loop_begin:
208  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]
209  %cond = load i1, i1* %cond.ptr
210  %b = load i32, i32* %b.ptr
211  br label %inner_inner_loop_begin
212
213inner_inner_loop_begin:
214  %v1 = load i1, i1* %ptr
215  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b
216
217inner_inner_loop_a:
218  %v2 = load i1, i1* %ptr
219  br i1 %v2, label %loop_exit, label %inner_inner_loop_c
220
221inner_inner_loop_b:
222  %v3 = load i1, i1* %ptr
223  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c
224
225inner_inner_loop_c:
226  %v4 = load i1, i1* %ptr
227  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d
228
229inner_inner_loop_d:
230  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_begin
231; The cloned copy that always exits with the adjustments required to fix up
232; loop exits.
233; The original copy that continues to loop.
234
235inner_inner_loop_exit:
236  %a2 = load i32, i32* %a.ptr
237  %v5 = load i1, i1* %ptr
238  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin
239
240inner_loop_exit:
241  br label %loop_begin
242
243loop_exit:
244  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]
245  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]
246  %result = add i32 %a.lcssa, %b.lcssa
247  ret i32 %result
248}
249
250; Same pattern as @test7a but here the original loop becomes a non-loop that
251; can reach multiple exit blocks which are part of different outer loops.
252define i32 @test7b(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
253; CHECK-LABEL: @test7b(
254; CHECK-NEXT:  entry:
255; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
256; CHECK:       loop_begin:
257; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
258; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
259; CHECK:       inner_loop_begin:
260; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]
261; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
262; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
263; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
264; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]
265; CHECK:       inner_loop_begin.split.us:
266; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
267; CHECK:       inner_inner_loop_begin.us:
268; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
269; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]
270; CHECK:       inner_inner_loop_b.us:
271; CHECK-NEXT:    [[V3_US:%.*]] = load i1, i1* [[PTR]], align 1
272; CHECK-NEXT:    br i1 [[V3_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US:%.*]]
273; CHECK:       inner_inner_loop_a.us:
274; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
275; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US]]
276; CHECK:       inner_inner_loop_c.us:
277; CHECK-NEXT:    [[V4_US:%.*]] = load i1, i1* [[PTR]], align 1
278; CHECK-NEXT:    br i1 [[V4_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_D_US:%.*]]
279; CHECK:       inner_inner_loop_d.us:
280; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]
281; CHECK:       inner_inner_loop_exit.split.us:
282; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
283; CHECK:       loop_exit.split.us:
284; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A_US]] ]
285; CHECK-NEXT:    [[B_LCSSA_US:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_A_US]] ]
286; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
287; CHECK:       inner_loop_exit.loopexit.split.us:
288; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
289; CHECK:       inner_loop_begin.split:
290; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
291; CHECK:       inner_inner_loop_begin:
292; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
293; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]
294; CHECK:       inner_inner_loop_a:
295; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_BEGIN]] ]
296; CHECK-NEXT:    [[B_LCSSA3:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_BEGIN]] ]
297; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
298; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C:%.*]]
299; CHECK:       inner_inner_loop_b:
300; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
301; CHECK-NEXT:    br i1 [[V3]], label [[INNER_INNER_LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C_LOOPEXIT:%.*]]
302; CHECK:       inner_inner_loop_c.loopexit:
303; CHECK-NEXT:    br label [[INNER_INNER_LOOP_C]]
304; CHECK:       inner_inner_loop_c:
305; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
306; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_D:%.*]]
307; CHECK:       inner_inner_loop_d:
308; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]]
309; CHECK:       inner_inner_loop_exit.split:
310; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
311; CHECK:       inner_inner_loop_exit:
312; CHECK-NEXT:    [[A2]] = load i32, i32* [[A_PTR]], align 4
313; CHECK-NEXT:    [[V5:%.*]] = load i1, i1* [[PTR]], align 1
314; CHECK-NEXT:    br i1 [[V5]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]
315; CHECK:       inner_loop_exit.loopexit.split:
316; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]
317; CHECK:       inner_loop_exit.loopexit:
318; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
319; CHECK:       inner_loop_exit.loopexit1:
320; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
321; CHECK:       inner_loop_exit:
322; CHECK-NEXT:    br label [[LOOP_BEGIN]]
323; CHECK:       loop_exit.split:
324; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_INNER_LOOP_A]] ]
325; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B_LCSSA3]], [[INNER_INNER_LOOP_A]] ]
326; CHECK-NEXT:    br label [[LOOP_EXIT]]
327; CHECK:       loop_exit:
328; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
329; CHECK-NEXT:    [[DOTUS_PHI2:%.*]] = phi i32 [ [[B_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[B_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
330; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[DOTUS_PHI]], [[DOTUS_PHI2]]
331; CHECK-NEXT:    ret i32 [[RESULT]]
332;
333entry:
334  br label %loop_begin
335
336loop_begin:
337  %a = load i32, i32* %a.ptr
338  br label %inner_loop_begin
339
340inner_loop_begin:
341  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]
342  %cond = load i1, i1* %cond.ptr
343  %b = load i32, i32* %b.ptr
344  br label %inner_inner_loop_begin
345
346inner_inner_loop_begin:
347  %v1 = load i1, i1* %ptr
348  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b
349
350inner_inner_loop_a:
351  %v2 = load i1, i1* %ptr
352  br i1 %v2, label %loop_exit, label %inner_inner_loop_c
353
354inner_inner_loop_b:
355  %v3 = load i1, i1* %ptr
356  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c
357
358inner_inner_loop_c:
359  %v4 = load i1, i1* %ptr
360  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d
361
362inner_inner_loop_d:
363  br i1 %cond, label %inner_inner_loop_begin, label %inner_loop_exit
364; The cloned copy that continues looping.
365; The original copy that now always exits and needs adjustments for exit
366; blocks.
367
368inner_inner_loop_exit:
369  %a2 = load i32, i32* %a.ptr
370  %v5 = load i1, i1* %ptr
371  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin
372
373inner_loop_exit:
374  br label %loop_begin
375
376loop_exit:
377  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]
378  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]
379  %result = add i32 %a.lcssa, %b.lcssa
380  ret i32 %result
381}
382
383; Test that when the exit block set of an inner loop changes to start at a less
384; high level of the loop nest we correctly hoist the loop up the nest.
385define i32 @test8a(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
386; CHECK-LABEL: @test8a(
387; CHECK-NEXT:  entry:
388; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
389; CHECK:       loop_begin:
390; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
391; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
392; CHECK:       inner_loop_begin:
393; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]
394; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
395; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
396; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
397; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]
398; CHECK:       inner_loop_begin.split.us:
399; CHECK-NEXT:    [[A_PHI_LCSSA4:%.*]] = phi i32 [ [[A_PHI]], [[INNER_LOOP_BEGIN]] ]
400; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
401; CHECK:       inner_inner_loop_begin.us:
402; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
403; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]
404; CHECK:       inner_inner_loop_b.us:
405; CHECK-NEXT:    br label [[INNER_INNER_LOOP_LATCH_US:%.*]]
406; CHECK:       inner_inner_loop_a.us:
407; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
408; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_LATCH_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]
409; CHECK:       inner_inner_loop_latch.us:
410; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]
411; CHECK:       inner_loop_exit.loopexit.split.us:
412; CHECK-NEXT:    [[A_PHI_LCSSA2_US:%.*]] = phi i32 [ [[A_PHI_LCSSA4]], [[INNER_INNER_LOOP_A_US]] ]
413; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
414; CHECK:       inner_loop_begin.split:
415; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
416; CHECK:       inner_inner_loop_begin:
417; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
418; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]
419; CHECK:       inner_inner_loop_a:
420; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
421; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_LATCH:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]]
422; CHECK:       inner_inner_loop_b:
423; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
424; CHECK:       inner_inner_loop_latch:
425; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]
426; CHECK:       inner_inner_loop_exit:
427; CHECK-NEXT:    [[A2]] = load i32, i32* [[A_PTR]], align 4
428; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
429; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]
430; CHECK:       inner_loop_exit.loopexit.split:
431; CHECK-NEXT:    [[A_PHI_LCSSA2:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A]] ]
432; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]
433; CHECK:       inner_loop_exit.loopexit:
434; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_PHI_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]] ], [ [[A_PHI_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]] ]
435; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
436; CHECK:       inner_loop_exit.loopexit1:
437; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_EXIT]] ]
438; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
439; CHECK:       inner_loop_exit:
440; CHECK-NEXT:    [[A_PHI3:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ], [ [[DOTUS_PHI]], [[INNER_LOOP_EXIT_LOOPEXIT]] ]
441; CHECK-NEXT:    [[V5:%.*]] = load i1, i1* [[PTR]], align 1
442; CHECK-NEXT:    br i1 [[V5]], label [[LOOP_EXIT:%.*]], label [[LOOP_BEGIN]]
443; CHECK:       loop_exit:
444; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI3]], [[INNER_LOOP_EXIT]] ]
445; CHECK-NEXT:    ret i32 [[A_LCSSA]]
446;
447entry:
448  br label %loop_begin
449
450loop_begin:
451  %a = load i32, i32* %a.ptr
452  br label %inner_loop_begin
453
454inner_loop_begin:
455  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]
456  %cond = load i1, i1* %cond.ptr
457  %b = load i32, i32* %b.ptr
458  br label %inner_inner_loop_begin
459
460inner_inner_loop_begin:
461  %v1 = load i1, i1* %ptr
462  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b
463
464inner_inner_loop_a:
465  %v2 = load i1, i1* %ptr
466  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit
467
468inner_inner_loop_b:
469  br i1 %cond, label %inner_inner_loop_latch, label %inner_inner_loop_exit
470
471inner_inner_loop_latch:
472  br label %inner_inner_loop_begin
473; The cloned region is now an exit from the inner loop.
474; The original region exits the loop earlier.
475
476inner_inner_loop_exit:
477  %a2 = load i32, i32* %a.ptr
478  %v4 = load i1, i1* %ptr
479  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin
480
481inner_loop_exit:
482  %v5 = load i1, i1* %ptr
483  br i1 %v5, label %loop_exit, label %loop_begin
484
485loop_exit:
486  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]
487  ret i32 %a.lcssa
488}
489
490; Same pattern as @test8a but where the original loop looses an exit block and
491; needs to be hoisted up the nest.
492define i32 @test8b(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
493; CHECK-LABEL: @test8b(
494; CHECK-NEXT:  entry:
495; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
496; CHECK:       loop_begin:
497; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
498; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
499; CHECK:       inner_loop_begin:
500; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]
501; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
502; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
503; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
504; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]
505; CHECK:       inner_loop_begin.split.us:
506; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
507; CHECK:       inner_inner_loop_begin.us:
508; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
509; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]
510; CHECK:       inner_inner_loop_b.us:
511; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]]
512; CHECK:       inner_inner_loop_a.us:
513; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
514; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_LATCH_US:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]
515; CHECK:       inner_inner_loop_latch.us:
516; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]
517; CHECK:       inner_inner_loop_exit.split.us:
518; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]
519; CHECK:       inner_loop_exit.loopexit.split.us:
520; CHECK-NEXT:    [[A_PHI_LCSSA2_US:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A_US]] ]
521; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
522; CHECK:       inner_loop_begin.split:
523; CHECK-NEXT:    [[A_PHI_LCSSA4:%.*]] = phi i32 [ [[A_PHI]], [[INNER_LOOP_BEGIN]] ]
524; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
525; CHECK:       inner_inner_loop_begin:
526; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
527; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]
528; CHECK:       inner_inner_loop_a:
529; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
530; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_LATCH:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]]
531; CHECK:       inner_inner_loop_b:
532; CHECK-NEXT:    br label [[INNER_INNER_LOOP_LATCH]]
533; CHECK:       inner_inner_loop_latch:
534; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]
535; CHECK:       inner_inner_loop_exit:
536; CHECK-NEXT:    [[A2]] = load i32, i32* [[A_PTR]], align 4
537; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
538; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]
539; CHECK:       inner_loop_exit.loopexit.split:
540; CHECK-NEXT:    [[A_PHI_LCSSA2:%.*]] = phi i32 [ [[A_PHI_LCSSA4]], [[INNER_INNER_LOOP_A]] ]
541; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]
542; CHECK:       inner_loop_exit.loopexit:
543; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_PHI_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]] ], [ [[A_PHI_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]] ]
544; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
545; CHECK:       inner_loop_exit.loopexit1:
546; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_EXIT]] ]
547; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
548; CHECK:       inner_loop_exit:
549; CHECK-NEXT:    [[A_PHI3:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ], [ [[DOTUS_PHI]], [[INNER_LOOP_EXIT_LOOPEXIT]] ]
550; CHECK-NEXT:    [[V5:%.*]] = load i1, i1* [[PTR]], align 1
551; CHECK-NEXT:    br i1 [[V5]], label [[LOOP_EXIT:%.*]], label [[LOOP_BEGIN]]
552; CHECK:       loop_exit:
553; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI3]], [[INNER_LOOP_EXIT]] ]
554; CHECK-NEXT:    ret i32 [[A_LCSSA]]
555;
556entry:
557  br label %loop_begin
558
559loop_begin:
560  %a = load i32, i32* %a.ptr
561  br label %inner_loop_begin
562
563inner_loop_begin:
564  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]
565  %cond = load i1, i1* %cond.ptr
566  %b = load i32, i32* %b.ptr
567  br label %inner_inner_loop_begin
568
569inner_inner_loop_begin:
570  %v1 = load i1, i1* %ptr
571  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b
572
573inner_inner_loop_a:
574  %v2 = load i1, i1* %ptr
575  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit
576
577inner_inner_loop_b:
578  br i1 %cond, label %inner_inner_loop_exit, label %inner_inner_loop_latch
579
580inner_inner_loop_latch:
581  br label %inner_inner_loop_begin
582; The cloned region is similar to before but with one earlier exit.
583; The original region is now an exit in the preheader.
584
585inner_inner_loop_exit:
586  %a2 = load i32, i32* %a.ptr
587  %v4 = load i1, i1* %ptr
588  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin
589
590inner_loop_exit:
591  %v5 = load i1, i1* %ptr
592  br i1 %v5, label %loop_exit, label %loop_begin
593
594loop_exit:
595  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]
596  ret i32 %a.lcssa
597}
598
599; Test that requires re-forming dedicated exits for the cloned loop.
600define i32 @test10a(i1* %ptr, i1 %cond, i32* %a.ptr) {
601; CHECK-LABEL: @test10a(
602; CHECK-NEXT:  entry:
603; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
604; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
605; CHECK:       entry.split.us:
606; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
607; CHECK:       loop_begin.us:
608; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
609; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
610; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]
611; CHECK:       loop_b.us:
612; CHECK-NEXT:    [[A_US_LCSSA:%.*]] = phi i32 [ [[A_US]], [[LOOP_BEGIN_US]] ]
613; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US:%.*]]
614; CHECK:       loop_a.us:
615; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
616; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US_LOOPEXIT:%.*]], label [[LOOP_BEGIN_BACKEDGE_US:%.*]]
617; CHECK:       loop_begin.backedge.us:
618; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]
619; CHECK:       loop_exit.split.us.loopexit:
620; CHECK-NEXT:    [[A_LCSSA_US_PH:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]
621; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US]]
622; CHECK:       loop_exit.split.us:
623; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_US_LCSSA]], [[LOOP_B_US]] ], [ [[A_LCSSA_US_PH]], [[LOOP_EXIT_SPLIT_US_LOOPEXIT]] ]
624; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
625; CHECK:       entry.split:
626; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
627; CHECK:       loop_begin:
628; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
629; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
630; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
631; CHECK:       loop_a:
632; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
633; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[LOOP_BEGIN_BACKEDGE:%.*]]
634; CHECK:       loop_begin.backedge:
635; CHECK-NEXT:    br label [[LOOP_BEGIN]]
636; CHECK:       loop_b:
637; CHECK-NEXT:    br label [[LOOP_BEGIN_BACKEDGE]]
638; CHECK:       loop_exit.split:
639; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]
640; CHECK-NEXT:    br label [[LOOP_EXIT]]
641; CHECK:       loop_exit:
642; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
643; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
644;
645entry:
646  br label %loop_begin
647
648loop_begin:
649  %a = load i32, i32* %a.ptr
650  %v1 = load i1, i1* %ptr
651  br i1 %v1, label %loop_a, label %loop_b
652
653loop_a:
654  %v2 = load i1, i1* %ptr
655  br i1 %v2, label %loop_exit, label %loop_begin
656
657loop_b:
658  br i1 %cond, label %loop_exit, label %loop_begin
659; The cloned loop with one edge as a direct exit.
660
661; The original loop without one 'loop_exit' edge.
662
663loop_exit:
664  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]
665  ret i32 %a.lcssa
666}
667
668; Test that requires re-forming dedicated exits for the original loop.
669define i32 @test10b(i1* %ptr, i1 %cond, i32* %a.ptr) {
670; CHECK-LABEL: @test10b(
671; CHECK-NEXT:  entry:
672; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
673; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
674; CHECK:       entry.split.us:
675; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
676; CHECK:       loop_begin.us:
677; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
678; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
679; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]
680; CHECK:       loop_b.us:
681; CHECK-NEXT:    br label [[LOOP_BEGIN_BACKEDGE_US:%.*]]
682; CHECK:       loop_a.us:
683; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
684; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_BEGIN_BACKEDGE_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
685; CHECK:       loop_begin.backedge.us:
686; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]
687; CHECK:       loop_exit.split.us:
688; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]
689; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
690; CHECK:       entry.split:
691; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
692; CHECK:       loop_begin:
693; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
694; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
695; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
696; CHECK:       loop_a:
697; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
698; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_BEGIN_BACKEDGE:%.*]], label [[LOOP_EXIT_SPLIT_LOOPEXIT:%.*]]
699; CHECK:       loop_begin.backedge:
700; CHECK-NEXT:    br label [[LOOP_BEGIN]]
701; CHECK:       loop_b:
702; CHECK-NEXT:    [[A_LCSSA1:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ]
703; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]
704; CHECK:       loop_exit.split.loopexit:
705; CHECK-NEXT:    [[A_LCSSA_PH:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]
706; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]
707; CHECK:       loop_exit.split:
708; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA1]], [[LOOP_B]] ], [ [[A_LCSSA_PH]], [[LOOP_EXIT_SPLIT_LOOPEXIT]] ]
709; CHECK-NEXT:    br label [[LOOP_EXIT]]
710; CHECK:       loop_exit:
711; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
712; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
713;
714entry:
715  br label %loop_begin
716
717loop_begin:
718  %a = load i32, i32* %a.ptr
719  %v1 = load i1, i1* %ptr
720  br i1 %v1, label %loop_a, label %loop_b
721
722loop_a:
723  %v2 = load i1, i1* %ptr
724  br i1 %v2, label %loop_begin, label %loop_exit
725
726loop_b:
727  br i1 %cond, label %loop_begin, label %loop_exit
728; The cloned loop without one of the exits.
729
730; The original loop without one 'loop_exit' edge.
731
732loop_exit:
733  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]
734  ret i32 %a.lcssa
735}
736
737; Check that if a cloned inner loop after unswitching doesn't loop and directly
738; exits even an outer loop, we don't add the cloned preheader to the outer
739; loop and do add the needed LCSSA phi nodes for the new exit block from the
740; outer loop.
741define i32 @test11a(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
742; CHECK-LABEL: @test11a(
743; CHECK-NEXT:  entry:
744; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
745; CHECK:       loop_begin:
746; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
747; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
748; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_LATCH:%.*]], label [[INNER_LOOP_PH:%.*]]
749; CHECK:       inner_loop_ph:
750; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
751; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
752; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_LOOP_PH_SPLIT:%.*]]
753; CHECK:       inner_loop_ph.split.us:
754; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_LOOP_PH]] ]
755; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN_US:%.*]]
756; CHECK:       inner_loop_begin.us:
757; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])
758; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
759; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]
760; CHECK:       loop_exit.loopexit.split.us:
761; CHECK-NEXT:    [[A_LCSSA2_US:%.*]] = phi i32 [ [[A_US]], [[INNER_LOOP_BEGIN_US]] ]
762; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT:%.*]]
763; CHECK:       inner_loop_ph.split:
764; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
765; CHECK:       inner_loop_begin:
766; CHECK-NEXT:    call void @sink1(i32 [[B]])
767; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
768; CHECK-NEXT:    br label [[INNER_LOOP_A:%.*]]
769; CHECK:       inner_loop_a:
770; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
771; CHECK-NEXT:    br i1 [[V2]], label [[INNER_LOOP_EXIT:%.*]], label [[INNER_LOOP_BEGIN]]
772; CHECK:       inner_loop_exit:
773; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A]], [[INNER_LOOP_A]] ]
774; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
775; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_LATCH]], label [[LOOP_EXIT_LOOPEXIT1:%.*]]
776; CHECK:       loop_latch:
777; CHECK-NEXT:    br label [[LOOP_BEGIN]]
778; CHECK:       loop_exit.loopexit:
779; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
780; CHECK:       loop_exit.loopexit1:
781; CHECK-NEXT:    [[A_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]
782; CHECK-NEXT:    br label [[LOOP_EXIT]]
783; CHECK:       loop_exit:
784; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2_US]], [[LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_LCSSA_LCSSA]], [[LOOP_EXIT_LOOPEXIT1]] ]
785; CHECK-NEXT:    ret i32 [[A_LCSSA]]
786;
787entry:
788  br label %loop_begin
789
790loop_begin:
791  %b = load i32, i32* %b.ptr
792  %v1 = load i1, i1* %ptr
793  br i1 %v1, label %loop_latch, label %inner_loop_ph
794
795inner_loop_ph:
796  %cond = load i1, i1* %cond.ptr
797  br label %inner_loop_begin
798
799inner_loop_begin:
800  call void @sink1(i32 %b)
801  %a = load i32, i32* %a.ptr
802  br i1 %cond, label %loop_exit, label %inner_loop_a
803
804inner_loop_a:
805  %v2 = load i1, i1* %ptr
806  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin
807; The cloned path doesn't actually loop and is an exit from the outer loop as
808; well.
809; The original remains a loop losing the exit edge.
810
811inner_loop_exit:
812  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]
813  %v3 = load i1, i1* %ptr
814  br i1 %v3, label %loop_latch, label %loop_exit
815
816loop_latch:
817  br label %loop_begin
818
819loop_exit:
820  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]
821  ret i32 %a.lcssa
822}
823
824; Check that if the original inner loop after unswitching doesn't loop and
825; directly exits even an outer loop, we remove the original preheader from the
826; outer loop and add needed LCSSA phi nodes for the new exit block from the
827; outer loop.
828define i32 @test11b(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
829; CHECK-LABEL: @test11b(
830; CHECK-NEXT:  entry:
831; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
832; CHECK:       loop_begin:
833; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
834; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
835; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_LATCH:%.*]], label [[INNER_LOOP_PH:%.*]]
836; CHECK:       inner_loop_ph:
837; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
838; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
839; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_LOOP_PH_SPLIT:%.*]]
840; CHECK:       inner_loop_ph.split.us:
841; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN_US:%.*]]
842; CHECK:       inner_loop_begin.us:
843; CHECK-NEXT:    call void @sink1(i32 [[B]])
844; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
845; CHECK-NEXT:    br label [[INNER_LOOP_A_US:%.*]]
846; CHECK:       inner_loop_a.us:
847; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
848; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_US]]
849; CHECK:       inner_loop_exit.split.us:
850; CHECK-NEXT:    [[A_INNER_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[INNER_LOOP_A_US]] ]
851; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
852; CHECK:       inner_loop_ph.split:
853; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_LOOP_PH]] ]
854; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
855; CHECK:       inner_loop_begin:
856; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])
857; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
858; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT:%.*]]
859; CHECK:       inner_loop_exit:
860; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
861; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_LATCH]], label [[LOOP_EXIT_LOOPEXIT1:%.*]]
862; CHECK:       loop_latch:
863; CHECK-NEXT:    br label [[LOOP_BEGIN]]
864; CHECK:       loop_exit.loopexit:
865; CHECK-NEXT:    [[A_LCSSA2:%.*]] = phi i32 [ [[A]], [[INNER_LOOP_BEGIN]] ]
866; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
867; CHECK:       loop_exit.loopexit1:
868; CHECK-NEXT:    [[A_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA_US]], [[INNER_LOOP_EXIT]] ]
869; CHECK-NEXT:    br label [[LOOP_EXIT]]
870; CHECK:       loop_exit:
871; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2]], [[LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_LCSSA_LCSSA]], [[LOOP_EXIT_LOOPEXIT1]] ]
872; CHECK-NEXT:    ret i32 [[A_LCSSA]]
873;
874entry:
875  br label %loop_begin
876
877loop_begin:
878  %b = load i32, i32* %b.ptr
879  %v1 = load i1, i1* %ptr
880  br i1 %v1, label %loop_latch, label %inner_loop_ph
881
882inner_loop_ph:
883  %cond = load i1, i1* %cond.ptr
884  br label %inner_loop_begin
885
886inner_loop_begin:
887  call void @sink1(i32 %b)
888  %a = load i32, i32* %a.ptr
889  br i1 %cond, label %inner_loop_a, label %loop_exit
890
891inner_loop_a:
892  %v2 = load i1, i1* %ptr
893  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin
894; The cloned path continues to loop without the exit out of the entire nest.
895; The original remains a loop losing the exit edge.
896
897inner_loop_exit:
898  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]
899  %v3 = load i1, i1* %ptr
900  br i1 %v3, label %loop_latch, label %loop_exit
901
902loop_latch:
903  br label %loop_begin
904
905loop_exit:
906  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]
907  ret i32 %a.lcssa
908}
909
910; Like test11a, but checking that when the whole thing is wrapped in yet
911; another loop, we correctly attribute the cloned preheader to that outermost
912; loop rather than only handling the case where the preheader is not in any loop
913; at all.
914define i32 @test12a(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
915; CHECK-LABEL: @test12a(
916; CHECK-NEXT:  entry:
917; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
918; CHECK:       loop_begin:
919; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
920; CHECK:       inner_loop_begin:
921; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
922; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
923; CHECK-NEXT:    br i1 [[V1]], label [[INNER_LOOP_LATCH:%.*]], label [[INNER_INNER_LOOP_PH:%.*]]
924; CHECK:       inner_inner_loop_ph:
925; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
926; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
927; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_PH_SPLIT:%.*]]
928; CHECK:       inner_inner_loop_ph.split.us:
929; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_PH]] ]
930; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
931; CHECK:       inner_inner_loop_begin.us:
932; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])
933; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
934; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]
935; CHECK:       inner_loop_exit.loopexit.split.us:
936; CHECK-NEXT:    [[A_LCSSA2_US:%.*]] = phi i32 [ [[A_US]], [[INNER_INNER_LOOP_BEGIN_US]] ]
937; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
938; CHECK:       inner_inner_loop_ph.split:
939; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
940; CHECK:       inner_inner_loop_begin:
941; CHECK-NEXT:    call void @sink1(i32 [[B]])
942; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
943; CHECK-NEXT:    br label [[INNER_INNER_LOOP_A:%.*]]
944; CHECK:       inner_inner_loop_a:
945; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
946; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_EXIT:%.*]], label [[INNER_INNER_LOOP_BEGIN]]
947; CHECK:       inner_inner_loop_exit:
948; CHECK-NEXT:    [[A_INNER_INNER_LCSSA:%.*]] = phi i32 [ [[A]], [[INNER_INNER_LOOP_A]] ]
949; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
950; CHECK-NEXT:    br i1 [[V3]], label [[INNER_LOOP_LATCH]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]]
951; CHECK:       inner_loop_latch:
952; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN]]
953; CHECK:       inner_loop_exit.loopexit:
954; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
955; CHECK:       inner_loop_exit.loopexit1:
956; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_INNER_LCSSA]], [[INNER_INNER_LOOP_EXIT]] ]
957; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
958; CHECK:       inner_loop_exit:
959; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_INNER_LCSSA_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ]
960; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
961; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
962; CHECK:       loop_exit:
963; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]
964; CHECK-NEXT:    ret i32 [[A_LCSSA]]
965;
966entry:
967  br label %loop_begin
968
969loop_begin:
970  br label %inner_loop_begin
971
972inner_loop_begin:
973  %b = load i32, i32* %b.ptr
974  %v1 = load i1, i1* %ptr
975  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph
976
977inner_inner_loop_ph:
978  %cond = load i1, i1* %cond.ptr
979  br label %inner_inner_loop_begin
980
981inner_inner_loop_begin:
982  call void @sink1(i32 %b)
983  %a = load i32, i32* %a.ptr
984  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_a
985
986inner_inner_loop_a:
987  %v2 = load i1, i1* %ptr
988  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin
989; The cloned path doesn't actually loop and is an exit from the outer loop as
990; well.
991; The original remains a loop losing the exit edge.
992
993inner_inner_loop_exit:
994  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]
995  %v3 = load i1, i1* %ptr
996  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit
997
998inner_loop_latch:
999  br label %inner_loop_begin
1000
1001inner_loop_exit:
1002  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]
1003  %v4 = load i1, i1* %ptr
1004  br i1 %v4, label %loop_begin, label %loop_exit
1005
1006loop_exit:
1007  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]
1008  ret i32 %a.lcssa
1009}
1010
1011; Like test11b, but checking that when the whole thing is wrapped in yet
1012; another loop, we correctly sink the preheader to the outermost loop rather
1013; than only handling the case where the preheader is completely removed from
1014; a loop.
1015define i32 @test12b(i1* %ptr, i1* %cond.ptr, i32* %a.ptr, i32* %b.ptr) {
1016; CHECK-LABEL: @test12b(
1017; CHECK-NEXT:  entry:
1018; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
1019; CHECK:       loop_begin:
1020; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]
1021; CHECK:       inner_loop_begin:
1022; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
1023; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
1024; CHECK-NEXT:    br i1 [[V1]], label [[INNER_LOOP_LATCH:%.*]], label [[INNER_INNER_LOOP_PH:%.*]]
1025; CHECK:       inner_inner_loop_ph:
1026; CHECK-NEXT:    [[COND:%.*]] = load i1, i1* [[COND_PTR:%.*]], align 1
1027; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
1028; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_PH_SPLIT:%.*]]
1029; CHECK:       inner_inner_loop_ph.split.us:
1030; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]
1031; CHECK:       inner_inner_loop_begin.us:
1032; CHECK-NEXT:    call void @sink1(i32 [[B]])
1033; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
1034; CHECK-NEXT:    br label [[INNER_INNER_LOOP_A_US:%.*]]
1035; CHECK:       inner_inner_loop_a.us:
1036; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
1037; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_BEGIN_US]]
1038; CHECK:       inner_inner_loop_exit.split.us:
1039; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[INNER_INNER_LOOP_A_US]] ]
1040; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT:%.*]]
1041; CHECK:       inner_inner_loop_ph.split:
1042; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_PH]] ]
1043; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]
1044; CHECK:       inner_inner_loop_begin:
1045; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])
1046; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
1047; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]
1048; CHECK:       inner_inner_loop_exit:
1049; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
1050; CHECK-NEXT:    br i1 [[V3]], label [[INNER_LOOP_LATCH]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]]
1051; CHECK:       inner_loop_latch:
1052; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN]]
1053; CHECK:       inner_loop_exit.loopexit:
1054; CHECK-NEXT:    [[A_LCSSA2:%.*]] = phi i32 [ [[A]], [[INNER_INNER_LOOP_BEGIN]] ]
1055; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]
1056; CHECK:       inner_loop_exit.loopexit1:
1057; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_INNER_LCSSA_US]], [[INNER_INNER_LOOP_EXIT]] ]
1058; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]
1059; CHECK:       inner_loop_exit:
1060; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_INNER_LCSSA_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ]
1061; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
1062; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
1063; CHECK:       loop_exit:
1064; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]
1065; CHECK-NEXT:    ret i32 [[A_LCSSA]]
1066;
1067entry:
1068  br label %loop_begin
1069
1070loop_begin:
1071  br label %inner_loop_begin
1072
1073inner_loop_begin:
1074  %b = load i32, i32* %b.ptr
1075  %v1 = load i1, i1* %ptr
1076  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph
1077
1078inner_inner_loop_ph:
1079  %cond = load i1, i1* %cond.ptr
1080  br label %inner_inner_loop_begin
1081
1082inner_inner_loop_begin:
1083  call void @sink1(i32 %b)
1084  %a = load i32, i32* %a.ptr
1085  br i1 %cond, label %inner_inner_loop_a, label %inner_loop_exit
1086
1087inner_inner_loop_a:
1088  %v2 = load i1, i1* %ptr
1089  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin
1090; The cloned path continues to loop without the exit out of the entire nest.
1091; The original remains a loop losing the exit edge.
1092
1093inner_inner_loop_exit:
1094  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]
1095  %v3 = load i1, i1* %ptr
1096  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit
1097
1098inner_loop_latch:
1099  br label %inner_loop_begin
1100
1101inner_loop_exit:
1102  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]
1103  %v4 = load i1, i1* %ptr
1104  br i1 %v4, label %loop_begin, label %loop_exit
1105
1106loop_exit:
1107  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]
1108  ret i32 %a.lcssa
1109}
1110
1111; Test where the cloned loop has an inner loop that has to be traversed to form
1112; the cloned loop, and where this inner loop has multiple blocks, and where the
1113; exiting block that connects the inner loop to the cloned loop is not the header
1114; block. This ensures that we correctly handle interesting corner cases of
1115; traversing back to the header when establishing the cloned loop.
1116define i32 @test13a(i1* %ptr, i1 %cond, i32* %a.ptr, i32* %b.ptr) {
1117; CHECK-LABEL: @test13a(
1118; CHECK-NEXT:  entry:
1119; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
1120; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1121; CHECK:       entry.split.us:
1122; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
1123; CHECK:       loop_begin.us:
1124; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
1125; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
1126; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]
1127; CHECK:       loop_b.us:
1128; CHECK-NEXT:    [[B_US:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
1129; CHECK-NEXT:    br label [[LOOP_B_INNER_PH_US:%.*]]
1130; CHECK:       loop_b_inner_ph.us:
1131; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER_US:%.*]]
1132; CHECK:       loop_b_inner_header.us:
1133; CHECK-NEXT:    [[V3_US:%.*]] = load i1, i1* [[PTR]], align 1
1134; CHECK-NEXT:    br i1 [[V3_US]], label [[LOOP_B_INNER_LATCH_US:%.*]], label [[LOOP_B_INNER_BODY_US:%.*]]
1135; CHECK:       loop_b_inner_body.us:
1136; CHECK-NEXT:    [[V4_US:%.*]] = load i1, i1* [[PTR]], align 1
1137; CHECK-NEXT:    br i1 [[V4_US]], label [[LOOP_B_INNER_LATCH_US]], label [[LOOP_B_INNER_EXIT_US:%.*]]
1138; CHECK:       loop_b_inner_exit.us:
1139; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
1140; CHECK:       loop_b_inner_latch.us:
1141; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER_US]]
1142; CHECK:       loop_a.us:
1143; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
1144; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[LOOP_LATCH_US]]
1145; CHECK:       loop_latch.us:
1146; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]
1147; CHECK:       loop_exit.split.us:
1148; CHECK-NEXT:    [[LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]
1149; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
1150; CHECK:       entry.split:
1151; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
1152; CHECK:       loop_begin:
1153; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
1154; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
1155; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
1156; CHECK:       loop_a:
1157; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
1158; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT_LOOPEXIT:%.*]], label [[LOOP_LATCH:%.*]]
1159; CHECK:       loop_b:
1160; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR]], align 4
1161; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]
1162; CHECK:       loop_latch:
1163; CHECK-NEXT:    br label [[LOOP_BEGIN]]
1164; CHECK:       loop_exit.split.loopexit:
1165; CHECK-NEXT:    [[LCSSA_PH:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]
1166; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]
1167; CHECK:       loop_exit.split:
1168; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ [[B]], [[LOOP_B]] ], [ [[LCSSA_PH]], [[LOOP_EXIT_SPLIT_LOOPEXIT]] ]
1169; CHECK-NEXT:    br label [[LOOP_EXIT]]
1170; CHECK:       loop_exit:
1171; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
1172; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
1173;
1174entry:
1175  br label %loop_begin
1176
1177loop_begin:
1178  %a = load i32, i32* %a.ptr
1179  %v1 = load i1, i1* %ptr
1180  br i1 %v1, label %loop_a, label %loop_b
1181
1182loop_a:
1183  %v2 = load i1, i1* %ptr
1184  br i1 %v2, label %loop_exit, label %loop_latch
1185
1186loop_b:
1187  %b = load i32, i32* %b.ptr
1188  br i1 %cond, label %loop_b_inner_ph, label %loop_exit
1189
1190loop_b_inner_ph:
1191  br label %loop_b_inner_header
1192
1193loop_b_inner_header:
1194  %v3 = load i1, i1* %ptr
1195  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body
1196
1197loop_b_inner_body:
1198  %v4 = load i1, i1* %ptr
1199  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit
1200
1201loop_b_inner_latch:
1202  br label %loop_b_inner_header
1203
1204loop_b_inner_exit:
1205  br label %loop_latch
1206
1207loop_latch:
1208  br label %loop_begin
1209; The cloned loop contains an inner loop within it.
1210; And the original loop no longer contains an inner loop.
1211
1212loop_exit:
1213  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]
1214  ret i32 %lcssa
1215}
1216
1217; Test where the original loop has an inner loop that has to be traversed to
1218; rebuild the loop, and where this inner loop has multiple blocks, and where
1219; the exiting block that connects the inner loop to the original loop is not
1220; the header block. This ensures that we correctly handle interesting corner
1221; cases of traversing back to the header when re-establishing the original loop
1222; still exists after unswitching.
1223define i32 @test13b(i1* %ptr, i1 %cond, i32* %a.ptr, i32* %b.ptr) {
1224; CHECK-LABEL: @test13b(
1225; CHECK-NEXT:  entry:
1226; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
1227; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1228; CHECK:       entry.split.us:
1229; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
1230; CHECK:       loop_begin.us:
1231; CHECK-NEXT:    [[A_US:%.*]] = load i32, i32* [[A_PTR:%.*]], align 4
1232; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
1233; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]
1234; CHECK:       loop_b.us:
1235; CHECK-NEXT:    [[B_US:%.*]] = load i32, i32* [[B_PTR:%.*]], align 4
1236; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US:%.*]]
1237; CHECK:       loop_a.us:
1238; CHECK-NEXT:    [[V2_US:%.*]] = load i1, i1* [[PTR]], align 1
1239; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US_LOOPEXIT:%.*]], label [[LOOP_LATCH_US:%.*]]
1240; CHECK:       loop_latch.us:
1241; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]
1242; CHECK:       loop_exit.split.us.loopexit:
1243; CHECK-NEXT:    [[LCSSA_US_PH:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]
1244; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US]]
1245; CHECK:       loop_exit.split.us:
1246; CHECK-NEXT:    [[LCSSA_US:%.*]] = phi i32 [ [[B_US]], [[LOOP_B_US]] ], [ [[LCSSA_US_PH]], [[LOOP_EXIT_SPLIT_US_LOOPEXIT]] ]
1247; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
1248; CHECK:       entry.split:
1249; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
1250; CHECK:       loop_begin:
1251; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[A_PTR]], align 4
1252; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR]], align 1
1253; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
1254; CHECK:       loop_a:
1255; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
1256; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[LOOP_LATCH:%.*]]
1257; CHECK:       loop_b:
1258; CHECK-NEXT:    [[B:%.*]] = load i32, i32* [[B_PTR]], align 4
1259; CHECK-NEXT:    br label [[LOOP_B_INNER_PH:%.*]]
1260; CHECK:       loop_b_inner_ph:
1261; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER:%.*]]
1262; CHECK:       loop_b_inner_header:
1263; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
1264; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_B_INNER_LATCH:%.*]], label [[LOOP_B_INNER_BODY:%.*]]
1265; CHECK:       loop_b_inner_body:
1266; CHECK-NEXT:    [[V4:%.*]] = load i1, i1* [[PTR]], align 1
1267; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_B_INNER_LATCH]], label [[LOOP_B_INNER_EXIT:%.*]]
1268; CHECK:       loop_b_inner_latch:
1269; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER]]
1270; CHECK:       loop_b_inner_exit:
1271; CHECK-NEXT:    br label [[LOOP_LATCH]]
1272; CHECK:       loop_latch:
1273; CHECK-NEXT:    br label [[LOOP_BEGIN]]
1274; CHECK:       loop_exit.split:
1275; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]
1276; CHECK-NEXT:    br label [[LOOP_EXIT]]
1277; CHECK:       loop_exit:
1278; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]
1279; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
1280;
1281entry:
1282  br label %loop_begin
1283
1284loop_begin:
1285  %a = load i32, i32* %a.ptr
1286  %v1 = load i1, i1* %ptr
1287  br i1 %v1, label %loop_a, label %loop_b
1288
1289loop_a:
1290  %v2 = load i1, i1* %ptr
1291  br i1 %v2, label %loop_exit, label %loop_latch
1292
1293loop_b:
1294  %b = load i32, i32* %b.ptr
1295  br i1 %cond, label %loop_exit, label %loop_b_inner_ph
1296
1297loop_b_inner_ph:
1298  br label %loop_b_inner_header
1299
1300loop_b_inner_header:
1301  %v3 = load i1, i1* %ptr
1302  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body
1303
1304loop_b_inner_body:
1305  %v4 = load i1, i1* %ptr
1306  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit
1307
1308loop_b_inner_latch:
1309  br label %loop_b_inner_header
1310
1311loop_b_inner_exit:
1312  br label %loop_latch
1313
1314loop_latch:
1315  br label %loop_begin
1316; The cloned loop doesn't contain an inner loop.
1317; But the original loop contains an inner loop that must be traversed.;
1318
1319loop_exit:
1320  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]
1321  ret i32 %lcssa
1322}
1323
1324; A test reduced out of 400.perlbench that when unswitching the `%stop`
1325; condition clones a loop nest outside of a containing loop. This excercises a
1326; different cloning path from our other test cases and in turn verifying the
1327; resulting structure can catch any failures to correctly clone these nested
1328; loops.
1329declare void @f()
1330declare void @g()
1331declare i32 @h(i32 %arg)
1332
1333; Test that when we are unswitching and need to rebuild the loop block set we
1334; correctly skip past inner loops. We want to use the inner loop to efficiently
1335; skip whole subregions of the outer loop blocks but just because the header of
1336; the outer loop is also the preheader of an inner loop shouldn't confuse this
1337; walk.
1338define void @test23(i1 %arg, i1* %ptr) {
1339; CHECK-LABEL: @test23(
1340; CHECK-NEXT:  entry:
1341; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i1 [[ARG:%.*]]
1342; CHECK-NEXT:    br i1 [[ARG_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1343; CHECK:       entry.split.us:
1344; CHECK-NEXT:    br label [[OUTER_HEADER_US:%.*]]
1345; CHECK:       outer.header.us:
1346; CHECK-NEXT:    br label [[INNER_HEADER_US:%.*]]
1347; CHECK:       inner.header.us:
1348; CHECK-NEXT:    call void @f()
1349; CHECK-NEXT:    br label [[INNER_LATCH_US:%.*]]
1350; CHECK:       inner.latch.us:
1351; CHECK-NEXT:    [[INNER_COND_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
1352; CHECK-NEXT:    br i1 [[INNER_COND_US]], label [[INNER_HEADER_US]], label [[OUTER_BODY_US:%.*]]
1353; CHECK:       outer.body.us:
1354; CHECK-NEXT:    br label [[OUTER_BODY_LEFT_US:%.*]]
1355; CHECK:       outer.body.left.us:
1356; CHECK-NEXT:    call void @f()
1357; CHECK-NEXT:    br label [[OUTER_LATCH_US:%.*]]
1358; CHECK:       outer.latch.us:
1359; CHECK-NEXT:    [[OUTER_COND_US:%.*]] = load i1, i1* [[PTR]], align 1
1360; CHECK-NEXT:    br i1 [[OUTER_COND_US]], label [[OUTER_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1361; CHECK:       exit.split.us:
1362; CHECK-NEXT:    br label [[EXIT:%.*]]
1363; CHECK:       entry.split:
1364; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1365; CHECK:       outer.header:
1366; CHECK-NEXT:    br label [[INNER_HEADER:%.*]]
1367; CHECK:       inner.header:
1368; CHECK-NEXT:    call void @f()
1369; CHECK-NEXT:    br label [[INNER_LATCH:%.*]]
1370; CHECK:       inner.latch:
1371; CHECK-NEXT:    [[INNER_COND:%.*]] = load i1, i1* [[PTR]], align 1
1372; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_HEADER]], label [[OUTER_BODY:%.*]]
1373; CHECK:       outer.body:
1374; CHECK-NEXT:    br label [[OUTER_BODY_RIGHT:%.*]]
1375; CHECK:       outer.body.right:
1376; CHECK-NEXT:    call void @g()
1377; CHECK-NEXT:    br label [[OUTER_LATCH:%.*]]
1378; CHECK:       outer.latch:
1379; CHECK-NEXT:    [[OUTER_COND:%.*]] = load i1, i1* [[PTR]], align 1
1380; CHECK-NEXT:    br i1 [[OUTER_COND]], label [[OUTER_HEADER]], label [[EXIT_SPLIT:%.*]]
1381; CHECK:       exit.split:
1382; CHECK-NEXT:    br label [[EXIT]]
1383; CHECK:       exit:
1384; CHECK-NEXT:    ret void
1385;
1386entry:
1387  br label %outer.header
1388; Just verify that we unswitched the correct bits. We should call `@f` twice in
1389; one unswitch and `@f` and then `@g` in the other.
1390
1391outer.header:
1392  br label %inner.header
1393
1394inner.header:
1395  call void @f()
1396  br label %inner.latch
1397
1398inner.latch:
1399  %inner.cond = load i1, i1* %ptr
1400  br i1 %inner.cond, label %inner.header, label %outer.body
1401
1402outer.body:
1403  br i1 %arg, label %outer.body.left, label %outer.body.right
1404
1405outer.body.left:
1406  call void @f()
1407  br label %outer.latch
1408
1409outer.body.right:
1410  call void @g()
1411  br label %outer.latch
1412
1413outer.latch:
1414  %outer.cond = load i1, i1* %ptr
1415  br i1 %outer.cond, label %outer.header, label %exit
1416
1417exit:
1418  ret void
1419}
1420
1421; A test case designed to exercise unusual properties of switches: they
1422; can introduce multiple edges to successors. These need lots of special case
1423; handling as they get collapsed in many cases (domtree, the unswitch itself)
1424; but not in all cases (the PHI node operands).
1425define i32 @test29(i32 %arg) {
1426; CHECK-LABEL: @test29(
1427; CHECK-NEXT:  entry:
1428; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i32 [[ARG:%.*]]
1429; CHECK-NEXT:    switch i32 [[ARG_FR]], label [[ENTRY_SPLIT:%.*]] [
1430; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT_US:%.*]]
1431; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT_US]]
1432; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT_US1:%.*]]
1433; CHECK-NEXT:    i32 3, label [[ENTRY_SPLIT]]
1434; CHECK-NEXT:    ]
1435; CHECK:       entry.split.us:
1436; CHECK-NEXT:    br label [[HEADER_US:%.*]]
1437; CHECK:       header.us:
1438; CHECK-NEXT:    [[TMP_US:%.*]] = call i32 @d()
1439; CHECK-NEXT:    [[CMP1_US:%.*]] = icmp eq i32 [[TMP_US]], 0
1440; CHECK-NEXT:    br i1 [[CMP1_US]], label [[BODY_A_US:%.*]], label [[DISPATCH_US:%.*]]
1441; CHECK:       dispatch.us:
1442; CHECK-NEXT:    br label [[BODY_A_US]]
1443; CHECK:       body.a.us:
1444; CHECK-NEXT:    [[TMP_A_PHI_US:%.*]] = phi i32 [ 0, [[HEADER_US]] ], [ [[TMP_US]], [[DISPATCH_US]] ]
1445; CHECK-NEXT:    [[TMP_A_US:%.*]] = call i32 @a()
1446; CHECK-NEXT:    [[TMP_A_SUM_US:%.*]] = add i32 [[TMP_A_PHI_US]], [[TMP_A_US]]
1447; CHECK-NEXT:    br label [[BODY_B_US:%.*]]
1448; CHECK:       body.b.us:
1449; CHECK-NEXT:    [[TMP_B_PHI_US:%.*]] = phi i32 [ [[TMP_A_SUM_US]], [[BODY_A_US]] ]
1450; CHECK-NEXT:    [[TMP_B_US:%.*]] = call i32 @b()
1451; CHECK-NEXT:    [[TMP_B_SUM_US:%.*]] = add i32 [[TMP_B_PHI_US]], [[TMP_B_US]]
1452; CHECK-NEXT:    br label [[BODY_C_US:%.*]]
1453; CHECK:       body.c.us:
1454; CHECK-NEXT:    [[TMP_C_PHI_US:%.*]] = phi i32 [ [[TMP_B_SUM_US]], [[BODY_B_US]] ]
1455; CHECK-NEXT:    [[TMP_C_US:%.*]] = call i32 @c()
1456; CHECK-NEXT:    [[TMP_C_SUM_US:%.*]] = add i32 [[TMP_C_PHI_US]], [[TMP_C_US]]
1457; CHECK-NEXT:    br label [[LATCH_US:%.*]]
1458; CHECK:       latch.us:
1459; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[TMP_C_SUM_US]], 42
1460; CHECK-NEXT:    br i1 [[CMP2_US]], label [[HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1461; CHECK:       exit.split.us:
1462; CHECK-NEXT:    [[LCSSA_PHI_US:%.*]] = phi i32 [ [[TMP_C_SUM_US]], [[LATCH_US]] ]
1463; CHECK-NEXT:    br label [[EXIT:%.*]]
1464; CHECK:       entry.split.us1:
1465; CHECK-NEXT:    br label [[HEADER_US2:%.*]]
1466; CHECK:       header.us2:
1467; CHECK-NEXT:    [[TMP_US3:%.*]] = call i32 @d()
1468; CHECK-NEXT:    [[CMP1_US4:%.*]] = icmp eq i32 [[TMP_US3]], 0
1469; CHECK-NEXT:    br i1 [[CMP1_US4]], label [[BODY_A_US6:%.*]], label [[DISPATCH_US5:%.*]]
1470; CHECK:       dispatch.us5:
1471; CHECK-NEXT:    br label [[BODY_B_US10:%.*]]
1472; CHECK:       body.a.us6:
1473; CHECK-NEXT:    [[TMP_A_PHI_US7:%.*]] = phi i32 [ 0, [[HEADER_US2]] ]
1474; CHECK-NEXT:    [[TMP_A_US8:%.*]] = call i32 @a()
1475; CHECK-NEXT:    [[TMP_A_SUM_US9:%.*]] = add i32 [[TMP_A_PHI_US7]], [[TMP_A_US8]]
1476; CHECK-NEXT:    br label [[BODY_B_US10]]
1477; CHECK:       body.b.us10:
1478; CHECK-NEXT:    [[TMP_B_PHI_US11:%.*]] = phi i32 [ [[TMP_US3]], [[DISPATCH_US5]] ], [ [[TMP_A_SUM_US9]], [[BODY_A_US6]] ]
1479; CHECK-NEXT:    [[TMP_B_US12:%.*]] = call i32 @b()
1480; CHECK-NEXT:    [[TMP_B_SUM_US13:%.*]] = add i32 [[TMP_B_PHI_US11]], [[TMP_B_US12]]
1481; CHECK-NEXT:    br label [[BODY_C_US14:%.*]]
1482; CHECK:       body.c.us14:
1483; CHECK-NEXT:    [[TMP_C_PHI_US15:%.*]] = phi i32 [ [[TMP_B_SUM_US13]], [[BODY_B_US10]] ]
1484; CHECK-NEXT:    [[TMP_C_US16:%.*]] = call i32 @c()
1485; CHECK-NEXT:    [[TMP_C_SUM_US17:%.*]] = add i32 [[TMP_C_PHI_US15]], [[TMP_C_US16]]
1486; CHECK-NEXT:    br label [[LATCH_US18:%.*]]
1487; CHECK:       latch.us18:
1488; CHECK-NEXT:    [[CMP2_US19:%.*]] = icmp slt i32 [[TMP_C_SUM_US17]], 42
1489; CHECK-NEXT:    br i1 [[CMP2_US19]], label [[HEADER_US2]], label [[EXIT_SPLIT_SPLIT_US:%.*]]
1490; CHECK:       exit.split.split.us:
1491; CHECK-NEXT:    [[LCSSA_PHI_US20:%.*]] = phi i32 [ [[TMP_C_SUM_US17]], [[LATCH_US18]] ]
1492; CHECK-NEXT:    br label [[EXIT_SPLIT:%.*]]
1493; CHECK:       entry.split:
1494; CHECK-NEXT:    br label [[HEADER:%.*]]
1495; CHECK:       header:
1496; CHECK-NEXT:    [[TMP:%.*]] = call i32 @d()
1497; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP]], 0
1498; CHECK-NEXT:    br i1 [[CMP1]], label [[BODY_A:%.*]], label [[DISPATCH:%.*]]
1499; CHECK:       dispatch:
1500; CHECK-NEXT:    br label [[BODY_C:%.*]]
1501; CHECK:       body.a:
1502; CHECK-NEXT:    [[TMP_A_PHI:%.*]] = phi i32 [ 0, [[HEADER]] ]
1503; CHECK-NEXT:    [[TMP_A:%.*]] = call i32 @a()
1504; CHECK-NEXT:    [[TMP_A_SUM:%.*]] = add i32 [[TMP_A_PHI]], [[TMP_A]]
1505; CHECK-NEXT:    br label [[BODY_B:%.*]]
1506; CHECK:       body.b:
1507; CHECK-NEXT:    [[TMP_B_PHI:%.*]] = phi i32 [ [[TMP_A_SUM]], [[BODY_A]] ]
1508; CHECK-NEXT:    [[TMP_B:%.*]] = call i32 @b()
1509; CHECK-NEXT:    [[TMP_B_SUM:%.*]] = add i32 [[TMP_B_PHI]], [[TMP_B]]
1510; CHECK-NEXT:    br label [[BODY_C]]
1511; CHECK:       body.c:
1512; CHECK-NEXT:    [[TMP_C_PHI:%.*]] = phi i32 [ [[TMP]], [[DISPATCH]] ], [ [[TMP_B_SUM]], [[BODY_B]] ]
1513; CHECK-NEXT:    [[TMP_C:%.*]] = call i32 @c()
1514; CHECK-NEXT:    [[TMP_C_SUM:%.*]] = add i32 [[TMP_C_PHI]], [[TMP_C]]
1515; CHECK-NEXT:    br label [[LATCH:%.*]]
1516; CHECK:       latch:
1517; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP_C_SUM]], 42
1518; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[EXIT_SPLIT_SPLIT:%.*]]
1519; CHECK:       exit.split.split:
1520; CHECK-NEXT:    [[LCSSA_PHI:%.*]] = phi i32 [ [[TMP_C_SUM]], [[LATCH]] ]
1521; CHECK-NEXT:    br label [[EXIT_SPLIT]]
1522; CHECK:       exit.split:
1523; CHECK-NEXT:    [[DOTUS_PHI21:%.*]] = phi i32 [ [[LCSSA_PHI]], [[EXIT_SPLIT_SPLIT]] ], [ [[LCSSA_PHI_US20]], [[EXIT_SPLIT_SPLIT_US]] ]
1524; CHECK-NEXT:    br label [[EXIT]]
1525; CHECK:       exit:
1526; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI21]], [[EXIT_SPLIT]] ], [ [[LCSSA_PHI_US]], [[EXIT_SPLIT_US]] ]
1527; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
1528;
1529entry:
1530  br label %header
1531
1532header:
1533  %tmp = call i32 @d()
1534  %cmp1 = icmp eq i32 %tmp, 0
1535  ; We set up a chain through all the successors of the switch that doesn't
1536  ; involve the switch so that we can have interesting PHI nodes in them.
1537  br i1 %cmp1, label %body.a, label %dispatch
1538
1539dispatch:
1540  ; Switch with multiple successors. We arrange the last successor to be the
1541  ; default to make the test case easier to read. This has a duplicate edge
1542  ; both to the default destination (which is completely superfluous but
1543  ; technically valid IR) and to a regular successor.
1544  switch i32 %arg, label %body.c [
1545  i32 0, label %body.a
1546  i32 1, label %body.a
1547  i32 2, label %body.b
1548  i32 3, label %body.c
1549  ]
1550
1551body.a:
1552  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ], [ %tmp, %dispatch ]
1553  %tmp.a = call i32 @a()
1554  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a
1555  br label %body.b
1556; Unswitched 'a' loop.
1557
1558body.b:
1559  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]
1560  %tmp.b = call i32 @b()
1561  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b
1562  br label %body.c
1563; Unswitched 'b' loop.
1564
1565body.c:
1566  %tmp.c.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.b.sum, %body.b ]
1567  %tmp.c = call i32 @c()
1568  %tmp.c.sum = add i32 %tmp.c.phi, %tmp.c
1569  br label %latch
1570; Unswitched 'c' loop.
1571
1572latch:
1573  %cmp2 = icmp slt i32 %tmp.c.sum, 42
1574  br i1 %cmp2, label %header, label %exit
1575
1576exit:
1577  %lcssa.phi = phi i32 [ %tmp.c.sum, %latch ]
1578  ret i32 %lcssa.phi
1579
1580}
1581
1582; Similar to @test29 but designed to have one of the duplicate edges be
1583; a loop exit edge as those can in some cases be special. Among other things,
1584; this includes an LCSSA phi with multiple entries despite being a dedicated
1585; exit block.
1586define i32 @test30(i32 %arg) {
1587; CHECK-LABEL: @test30(
1588; CHECK-NEXT:  entry:
1589; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i32 [[ARG:%.*]]
1590; CHECK-NEXT:    switch i32 [[ARG_FR]], label [[ENTRY_SPLIT:%.*]] [
1591; CHECK-NEXT:    i32 -1, label [[ENTRY_SPLIT]]
1592; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT_US:%.*]]
1593; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT_US1:%.*]]
1594; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT_US1]]
1595; CHECK-NEXT:    ]
1596; CHECK:       entry.split.us:
1597; CHECK-NEXT:    br label [[HEADER_US:%.*]]
1598; CHECK:       header.us:
1599; CHECK-NEXT:    [[TMP_US:%.*]] = call i32 @d()
1600; CHECK-NEXT:    [[CMP1_US:%.*]] = icmp eq i32 [[TMP_US]], 0
1601; CHECK-NEXT:    br i1 [[CMP1_US]], label [[BODY_A_US:%.*]], label [[DISPATCH_US:%.*]]
1602; CHECK:       dispatch.us:
1603; CHECK-NEXT:    br label [[BODY_A_US]]
1604; CHECK:       body.a.us:
1605; CHECK-NEXT:    [[TMP_A_PHI_US:%.*]] = phi i32 [ 0, [[HEADER_US]] ], [ [[TMP_US]], [[DISPATCH_US]] ]
1606; CHECK-NEXT:    [[TMP_A_US:%.*]] = call i32 @a()
1607; CHECK-NEXT:    [[TMP_A_SUM_US:%.*]] = add i32 [[TMP_A_PHI_US]], [[TMP_A_US]]
1608; CHECK-NEXT:    br label [[BODY_B_US:%.*]]
1609; CHECK:       body.b.us:
1610; CHECK-NEXT:    [[TMP_B_PHI_US:%.*]] = phi i32 [ [[TMP_A_SUM_US]], [[BODY_A_US]] ]
1611; CHECK-NEXT:    [[TMP_B_US:%.*]] = call i32 @b()
1612; CHECK-NEXT:    [[TMP_B_SUM_US:%.*]] = add i32 [[TMP_B_PHI_US]], [[TMP_B_US]]
1613; CHECK-NEXT:    br label [[LATCH_US:%.*]]
1614; CHECK:       latch.us:
1615; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[TMP_B_SUM_US]], 42
1616; CHECK-NEXT:    br i1 [[CMP2_US]], label [[HEADER_US]], label [[LOOP_EXIT2_SPLIT_US:%.*]]
1617; CHECK:       loop.exit2.split.us:
1618; CHECK-NEXT:    [[L2_PHI_US:%.*]] = phi i32 [ [[TMP_B_SUM_US]], [[LATCH_US]] ]
1619; CHECK-NEXT:    br label [[LOOP_EXIT2:%.*]]
1620; CHECK:       entry.split.us1:
1621; CHECK-NEXT:    br label [[HEADER_US2:%.*]]
1622; CHECK:       header.us2:
1623; CHECK-NEXT:    [[TMP_US3:%.*]] = call i32 @d()
1624; CHECK-NEXT:    [[CMP1_US4:%.*]] = icmp eq i32 [[TMP_US3]], 0
1625; CHECK-NEXT:    br i1 [[CMP1_US4]], label [[BODY_A_US6:%.*]], label [[DISPATCH_US5:%.*]]
1626; CHECK:       dispatch.us5:
1627; CHECK-NEXT:    br label [[BODY_B_US10:%.*]]
1628; CHECK:       body.a.us6:
1629; CHECK-NEXT:    [[TMP_A_PHI_US7:%.*]] = phi i32 [ 0, [[HEADER_US2]] ]
1630; CHECK-NEXT:    [[TMP_A_US8:%.*]] = call i32 @a()
1631; CHECK-NEXT:    [[TMP_A_SUM_US9:%.*]] = add i32 [[TMP_A_PHI_US7]], [[TMP_A_US8]]
1632; CHECK-NEXT:    br label [[BODY_B_US10]]
1633; CHECK:       body.b.us10:
1634; CHECK-NEXT:    [[TMP_B_PHI_US11:%.*]] = phi i32 [ [[TMP_US3]], [[DISPATCH_US5]] ], [ [[TMP_A_SUM_US9]], [[BODY_A_US6]] ]
1635; CHECK-NEXT:    [[TMP_B_US12:%.*]] = call i32 @b()
1636; CHECK-NEXT:    [[TMP_B_SUM_US13:%.*]] = add i32 [[TMP_B_PHI_US11]], [[TMP_B_US12]]
1637; CHECK-NEXT:    br label [[LATCH_US14:%.*]]
1638; CHECK:       latch.us14:
1639; CHECK-NEXT:    [[CMP2_US15:%.*]] = icmp slt i32 [[TMP_B_SUM_US13]], 42
1640; CHECK-NEXT:    br i1 [[CMP2_US15]], label [[HEADER_US2]], label [[LOOP_EXIT2_SPLIT_SPLIT_US:%.*]]
1641; CHECK:       loop.exit2.split.split.us:
1642; CHECK-NEXT:    [[L2_PHI_US16:%.*]] = phi i32 [ [[TMP_B_SUM_US13]], [[LATCH_US14]] ]
1643; CHECK-NEXT:    br label [[LOOP_EXIT2_SPLIT:%.*]]
1644; CHECK:       entry.split:
1645; CHECK-NEXT:    br label [[HEADER:%.*]]
1646; CHECK:       header:
1647; CHECK-NEXT:    [[TMP:%.*]] = call i32 @d()
1648; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP]], 0
1649; CHECK-NEXT:    br i1 [[CMP1]], label [[BODY_A:%.*]], label [[DISPATCH:%.*]]
1650; CHECK:       dispatch:
1651; CHECK-NEXT:    [[TMP_LCSSA:%.*]] = phi i32 [ [[TMP]], [[HEADER]] ]
1652; CHECK-NEXT:    br label [[LOOP_EXIT1:%.*]]
1653; CHECK:       body.a:
1654; CHECK-NEXT:    [[TMP_A_PHI:%.*]] = phi i32 [ 0, [[HEADER]] ]
1655; CHECK-NEXT:    [[TMP_A:%.*]] = call i32 @a()
1656; CHECK-NEXT:    [[TMP_A_SUM:%.*]] = add i32 [[TMP_A_PHI]], [[TMP_A]]
1657; CHECK-NEXT:    br label [[BODY_B:%.*]]
1658; CHECK:       body.b:
1659; CHECK-NEXT:    [[TMP_B_PHI:%.*]] = phi i32 [ [[TMP_A_SUM]], [[BODY_A]] ]
1660; CHECK-NEXT:    [[TMP_B:%.*]] = call i32 @b()
1661; CHECK-NEXT:    [[TMP_B_SUM:%.*]] = add i32 [[TMP_B_PHI]], [[TMP_B]]
1662; CHECK-NEXT:    br label [[LATCH:%.*]]
1663; CHECK:       latch:
1664; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP_B_SUM]], 42
1665; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[LOOP_EXIT2_SPLIT_SPLIT:%.*]]
1666; CHECK:       loop.exit1:
1667; CHECK-NEXT:    [[L1_PHI:%.*]] = phi i32 [ [[TMP_LCSSA]], [[DISPATCH]] ]
1668; CHECK-NEXT:    br label [[EXIT:%.*]]
1669; CHECK:       loop.exit2.split.split:
1670; CHECK-NEXT:    [[L2_PHI:%.*]] = phi i32 [ [[TMP_B_SUM]], [[LATCH]] ]
1671; CHECK-NEXT:    br label [[LOOP_EXIT2_SPLIT]]
1672; CHECK:       loop.exit2.split:
1673; CHECK-NEXT:    [[DOTUS_PHI17:%.*]] = phi i32 [ [[L2_PHI]], [[LOOP_EXIT2_SPLIT_SPLIT]] ], [ [[L2_PHI_US16]], [[LOOP_EXIT2_SPLIT_SPLIT_US]] ]
1674; CHECK-NEXT:    br label [[LOOP_EXIT2]]
1675; CHECK:       loop.exit2:
1676; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI17]], [[LOOP_EXIT2_SPLIT]] ], [ [[L2_PHI_US]], [[LOOP_EXIT2_SPLIT_US]] ]
1677; CHECK-NEXT:    br label [[EXIT]]
1678; CHECK:       exit:
1679; CHECK-NEXT:    [[L_PHI:%.*]] = phi i32 [ [[L1_PHI]], [[LOOP_EXIT1]] ], [ [[DOTUS_PHI]], [[LOOP_EXIT2]] ]
1680; CHECK-NEXT:    ret i32 [[L_PHI]]
1681;
1682entry:
1683  br label %header
1684
1685header:
1686  %tmp = call i32 @d()
1687  %cmp1 = icmp eq i32 %tmp, 0
1688  br i1 %cmp1, label %body.a, label %dispatch
1689
1690dispatch:
1691  switch i32 %arg, label %loop.exit1 [
1692  i32 -1, label %loop.exit1
1693  i32 0, label %body.a
1694  i32 1, label %body.b
1695  i32 2, label %body.b
1696  ]
1697
1698body.a:
1699  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ]
1700  %tmp.a = call i32 @a()
1701  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a
1702  br label %body.b
1703; Unswitched 'a' loop.
1704
1705body.b:
1706  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]
1707  %tmp.b = call i32 @b()
1708  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b
1709  br label %latch
1710; Unswitched 'b' loop.
1711
1712latch:
1713  %cmp2 = icmp slt i32 %tmp.b.sum, 42
1714  br i1 %cmp2, label %header, label %loop.exit2
1715
1716loop.exit1:
1717  %l1.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ]
1718  br label %exit
1719; Unswitched 'exit' loop.
1720
1721loop.exit2:
1722  %l2.phi = phi i32 [ %tmp.b.sum, %latch ]
1723  br label %exit
1724
1725exit:
1726  %l.phi = phi i32 [ %l1.phi, %loop.exit1 ], [ %l2.phi, %loop.exit2 ]
1727  ret i32 %l.phi
1728}
1729
1730; Unswitch will not actually change the loop nest from:
1731;   A < B < C
1732define void @hoist_inner_loop0() {
1733; CHECK-LABEL: @hoist_inner_loop0(
1734; CHECK-NEXT:  entry:
1735; CHECK-NEXT:    br label [[A_HEADER:%.*]]
1736; CHECK:       a.header:
1737; CHECK-NEXT:    br label [[B_HEADER:%.*]]
1738; CHECK:       b.header:
1739; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
1740; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
1741; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]
1742; CHECK:       b.header.split.us:
1743; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]
1744; CHECK:       c.header.us:
1745; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()
1746; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]
1747; CHECK:       b.latch.split.us:
1748; CHECK-NEXT:    br label [[B_LATCH:%.*]]
1749; CHECK:       b.header.split:
1750; CHECK-NEXT:    br label [[C_HEADER:%.*]]
1751; CHECK:       c.header:
1752; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()
1753; CHECK-NEXT:    br label [[C_LATCH:%.*]]
1754; CHECK:       c.latch:
1755; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
1756; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[B_LATCH_SPLIT:%.*]]
1757; CHECK:       b.latch.split:
1758; CHECK-NEXT:    br label [[B_LATCH]]
1759; CHECK:       b.latch:
1760; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
1761; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]
1762; CHECK:       a.latch:
1763; CHECK-NEXT:    br label [[A_HEADER]]
1764; CHECK:       exit:
1765; CHECK-NEXT:    ret void
1766;
1767entry:
1768  br label %a.header
1769
1770a.header:
1771  br label %b.header
1772
1773b.header:
1774  %v1 = call i1 @cond()
1775  br label %c.header
1776
1777c.header:
1778  call i32 @c()
1779  br i1 %v1, label %b.latch, label %c.latch
1780
1781c.latch:
1782  %v2 = call i1 @cond()
1783  br i1 %v2, label %c.header, label %b.latch
1784
1785b.latch:
1786  %v3 = call i1 @cond()
1787  br i1 %v3, label %b.header, label %a.latch
1788
1789a.latch:
1790  br label %a.header
1791
1792exit:
1793  ret void
1794}
1795
1796; Unswitch will transform the loop nest from:
1797;   A < B < C
1798; into
1799;   A < (B, C)
1800define void @hoist_inner_loop1(i32* %ptr) {
1801; CHECK-LABEL: @hoist_inner_loop1(
1802; CHECK-NEXT:  entry:
1803; CHECK-NEXT:    br label [[A_HEADER:%.*]]
1804; CHECK:       a.header:
1805; CHECK-NEXT:    [[X_A:%.*]] = load i32, i32* [[PTR:%.*]], align 4
1806; CHECK-NEXT:    br label [[B_HEADER:%.*]]
1807; CHECK:       b.header:
1808; CHECK-NEXT:    [[X_B:%.*]] = load i32, i32* [[PTR]], align 4
1809; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
1810; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
1811; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]
1812; CHECK:       b.header.split.us:
1813; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]
1814; CHECK:       c.header.us:
1815; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()
1816; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]
1817; CHECK:       b.latch.split.us:
1818; CHECK-NEXT:    br label [[B_LATCH:%.*]]
1819; CHECK:       b.header.split:
1820; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]
1821; CHECK-NEXT:    br label [[C_HEADER:%.*]]
1822; CHECK:       c.header:
1823; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()
1824; CHECK-NEXT:    br label [[C_LATCH:%.*]]
1825; CHECK:       c.latch:
1826; CHECK-NEXT:    store i32 [[X_A]], i32* [[PTR]], align 4
1827; CHECK-NEXT:    store i32 [[X_B_LCSSA]], i32* [[PTR]], align 4
1828; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
1829; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[A_EXIT_C:%.*]]
1830; CHECK:       b.latch:
1831; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
1832; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_EXIT_B:%.*]]
1833; CHECK:       a.exit.c:
1834; CHECK-NEXT:    br label [[A_LATCH:%.*]]
1835; CHECK:       a.exit.b:
1836; CHECK-NEXT:    br label [[A_LATCH]]
1837; CHECK:       a.latch:
1838; CHECK-NEXT:    br label [[A_HEADER]]
1839; CHECK:       exit:
1840; CHECK-NEXT:    ret void
1841;
1842entry:
1843  br label %a.header
1844
1845a.header:
1846  %x.a = load i32, i32* %ptr
1847  br label %b.header
1848
1849b.header:
1850  %x.b = load i32, i32* %ptr
1851  %v1 = call i1 @cond()
1852  br label %c.header
1853
1854c.header:
1855  call i32 @c()
1856  br i1 %v1, label %b.latch, label %c.latch
1857
1858c.latch:
1859  ; Use values from other loops to check LCSSA form.
1860  store i32 %x.a, i32* %ptr
1861  store i32 %x.b, i32* %ptr
1862  %v2 = call i1 @cond()
1863  br i1 %v2, label %c.header, label %a.exit.c
1864
1865b.latch:
1866  %v3 = call i1 @cond()
1867  br i1 %v3, label %b.header, label %a.exit.b
1868
1869a.exit.c:
1870  br label %a.latch
1871
1872a.exit.b:
1873  br label %a.latch
1874
1875a.latch:
1876  br label %a.header
1877
1878exit:
1879  ret void
1880}
1881
1882; Unswitch will transform the loop nest from:
1883;   A < B < C
1884; into
1885;   (A < B), C
1886define void @hoist_inner_loop2(i32* %ptr) {
1887; CHECK-LABEL: @hoist_inner_loop2(
1888; CHECK-NEXT:  entry:
1889; CHECK-NEXT:    br label [[A_HEADER:%.*]]
1890; CHECK:       a.header:
1891; CHECK-NEXT:    [[X_A:%.*]] = load i32, i32* [[PTR:%.*]], align 4
1892; CHECK-NEXT:    br label [[B_HEADER:%.*]]
1893; CHECK:       b.header:
1894; CHECK-NEXT:    [[X_B:%.*]] = load i32, i32* [[PTR]], align 4
1895; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
1896; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
1897; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]
1898; CHECK:       b.header.split.us:
1899; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]
1900; CHECK:       c.header.us:
1901; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()
1902; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]
1903; CHECK:       b.latch.split.us:
1904; CHECK-NEXT:    br label [[B_LATCH:%.*]]
1905; CHECK:       b.header.split:
1906; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]
1907; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]
1908; CHECK-NEXT:    br label [[C_HEADER:%.*]]
1909; CHECK:       c.header:
1910; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()
1911; CHECK-NEXT:    br label [[C_LATCH:%.*]]
1912; CHECK:       c.latch:
1913; CHECK-NEXT:    store i32 [[X_A_LCSSA]], i32* [[PTR]], align 4
1914; CHECK-NEXT:    store i32 [[X_B_LCSSA]], i32* [[PTR]], align 4
1915; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
1916; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[EXIT:%.*]]
1917; CHECK:       b.latch:
1918; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
1919; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]
1920; CHECK:       a.latch:
1921; CHECK-NEXT:    br label [[A_HEADER]]
1922; CHECK:       exit:
1923; CHECK-NEXT:    ret void
1924;
1925entry:
1926  br label %a.header
1927
1928a.header:
1929  %x.a = load i32, i32* %ptr
1930  br label %b.header
1931
1932b.header:
1933  %x.b = load i32, i32* %ptr
1934  %v1 = call i1 @cond()
1935  br label %c.header
1936
1937c.header:
1938  call i32 @c()
1939  br i1 %v1, label %b.latch, label %c.latch
1940
1941c.latch:
1942  ; Use values from other loops to check LCSSA form.
1943  store i32 %x.a, i32* %ptr
1944  store i32 %x.b, i32* %ptr
1945  %v2 = call i1 @cond()
1946  br i1 %v2, label %c.header, label %exit
1947
1948b.latch:
1949  %v3 = call i1 @cond()
1950  br i1 %v3, label %b.header, label %a.latch
1951
1952a.latch:
1953  br label %a.header
1954
1955exit:
1956  ret void
1957}
1958
1959; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.
1960; Unswitch will transform the loop nest from:
1961;   A < B < C < D
1962; into
1963;   (A < B), (C < D)
1964define void @hoist_inner_loop3(i32* %ptr) {
1965; CHECK-LABEL: @hoist_inner_loop3(
1966; CHECK-NEXT:  entry:
1967; CHECK-NEXT:    br label [[A_HEADER:%.*]]
1968; CHECK:       a.header:
1969; CHECK-NEXT:    [[X_A:%.*]] = load i32, i32* [[PTR:%.*]], align 4
1970; CHECK-NEXT:    br label [[B_HEADER:%.*]]
1971; CHECK:       b.header:
1972; CHECK-NEXT:    [[X_B:%.*]] = load i32, i32* [[PTR]], align 4
1973; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
1974; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
1975; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]
1976; CHECK:       b.header.split.us:
1977; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]
1978; CHECK:       c.header.us:
1979; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()
1980; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]
1981; CHECK:       b.latch.split.us:
1982; CHECK-NEXT:    br label [[B_LATCH:%.*]]
1983; CHECK:       b.header.split:
1984; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]
1985; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]
1986; CHECK-NEXT:    br label [[C_HEADER:%.*]]
1987; CHECK:       c.header:
1988; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()
1989; CHECK-NEXT:    br label [[C_BODY:%.*]]
1990; CHECK:       c.body:
1991; CHECK-NEXT:    [[X_C:%.*]] = load i32, i32* [[PTR]], align 4
1992; CHECK-NEXT:    br label [[D_HEADER:%.*]]
1993; CHECK:       d.header:
1994; CHECK-NEXT:    store i32 [[X_A_LCSSA]], i32* [[PTR]], align 4
1995; CHECK-NEXT:    store i32 [[X_B_LCSSA]], i32* [[PTR]], align 4
1996; CHECK-NEXT:    store i32 [[X_C]], i32* [[PTR]], align 4
1997; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
1998; CHECK-NEXT:    br i1 [[V2]], label [[D_HEADER]], label [[C_LATCH:%.*]]
1999; CHECK:       c.latch:
2000; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
2001; CHECK-NEXT:    br i1 [[V3]], label [[C_HEADER]], label [[EXIT:%.*]]
2002; CHECK:       b.latch:
2003; CHECK-NEXT:    [[V4:%.*]] = call i1 @cond()
2004; CHECK-NEXT:    br i1 [[V4]], label [[B_HEADER]], label [[A_LATCH:%.*]]
2005; CHECK:       a.latch:
2006; CHECK-NEXT:    br label [[A_HEADER]]
2007; CHECK:       exit:
2008; CHECK-NEXT:    ret void
2009;
2010entry:
2011  br label %a.header
2012
2013a.header:
2014  %x.a = load i32, i32* %ptr
2015  br label %b.header
2016
2017b.header:
2018  %x.b = load i32, i32* %ptr
2019  %v1 = call i1 @cond()
2020  br label %c.header
2021
2022c.header:
2023  call i32 @c()
2024  br i1 %v1, label %b.latch, label %c.body
2025
2026c.body:
2027  %x.c = load i32, i32* %ptr
2028  br label %d.header
2029
2030d.header:
2031  ; Use values from other loops to check LCSSA form.
2032  store i32 %x.a, i32* %ptr
2033  store i32 %x.b, i32* %ptr
2034  store i32 %x.c, i32* %ptr
2035  %v2 = call i1 @cond()
2036  br i1 %v2, label %d.header, label %c.latch
2037
2038c.latch:
2039  %v3 = call i1 @cond()
2040  br i1 %v3, label %c.header, label %exit
2041
2042b.latch:
2043  %v4 = call i1 @cond()
2044  br i1 %v4, label %b.header, label %a.latch
2045
2046a.latch:
2047  br label %a.header
2048
2049exit:
2050  ret void
2051}
2052
2053; This test is designed to exercise checking multiple remaining exits from the
2054; loop being unswitched.
2055; Unswitch will transform the loop nest from:
2056;   A < B < C < D
2057; into
2058;   A < B < (C, D)
2059define void @hoist_inner_loop4() {
2060; CHECK-LABEL: @hoist_inner_loop4(
2061; CHECK-NEXT:  entry:
2062; CHECK-NEXT:    br label [[A_HEADER:%.*]]
2063; CHECK:       a.header:
2064; CHECK-NEXT:    br label [[B_HEADER:%.*]]
2065; CHECK:       b.header:
2066; CHECK-NEXT:    br label [[C_HEADER:%.*]]
2067; CHECK:       c.header:
2068; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
2069; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
2070; CHECK-NEXT:    br i1 [[V1_FR]], label [[C_HEADER_SPLIT_US:%.*]], label [[C_HEADER_SPLIT:%.*]]
2071; CHECK:       c.header.split.us:
2072; CHECK-NEXT:    br label [[D_HEADER_US:%.*]]
2073; CHECK:       d.header.us:
2074; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @d()
2075; CHECK-NEXT:    br label [[C_LATCH_SPLIT_US:%.*]]
2076; CHECK:       c.latch.split.us:
2077; CHECK-NEXT:    br label [[C_LATCH:%.*]]
2078; CHECK:       c.header.split:
2079; CHECK-NEXT:    br label [[D_HEADER:%.*]]
2080; CHECK:       d.header:
2081; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @d()
2082; CHECK-NEXT:    br label [[D_EXITING1:%.*]]
2083; CHECK:       d.exiting1:
2084; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
2085; CHECK-NEXT:    br i1 [[V2]], label [[D_EXITING2:%.*]], label [[A_LATCH:%.*]]
2086; CHECK:       d.exiting2:
2087; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
2088; CHECK-NEXT:    br i1 [[V3]], label [[D_EXITING3:%.*]], label [[LOOPEXIT_D:%.*]]
2089; CHECK:       d.exiting3:
2090; CHECK-NEXT:    [[V4:%.*]] = call i1 @cond()
2091; CHECK-NEXT:    br i1 [[V4]], label [[D_LATCH:%.*]], label [[B_LATCH:%.*]]
2092; CHECK:       d.latch:
2093; CHECK-NEXT:    br label [[D_HEADER]]
2094; CHECK:       c.latch:
2095; CHECK-NEXT:    [[V5:%.*]] = call i1 @cond()
2096; CHECK-NEXT:    br i1 [[V5]], label [[C_HEADER]], label [[LOOPEXIT_C:%.*]]
2097; CHECK:       b.latch:
2098; CHECK-NEXT:    br label [[B_HEADER]]
2099; CHECK:       a.latch:
2100; CHECK-NEXT:    br label [[A_HEADER]]
2101; CHECK:       loopexit.d:
2102; CHECK-NEXT:    br label [[EXIT:%.*]]
2103; CHECK:       loopexit.c:
2104; CHECK-NEXT:    br label [[EXIT]]
2105; CHECK:       exit:
2106; CHECK-NEXT:    ret void
2107;
2108entry:
2109  br label %a.header
2110
2111a.header:
2112  br label %b.header
2113
2114b.header:
2115  br label %c.header
2116
2117c.header:
2118  %v1 = call i1 @cond()
2119  br label %d.header
2120
2121d.header:
2122  call i32 @d()
2123  br i1 %v1, label %c.latch, label %d.exiting1
2124
2125d.exiting1:
2126  %v2 = call i1 @cond()
2127  br i1 %v2, label %d.exiting2, label %a.latch
2128
2129d.exiting2:
2130  %v3 = call i1 @cond()
2131  br i1 %v3, label %d.exiting3, label %loopexit.d
2132
2133d.exiting3:
2134  %v4 = call i1 @cond()
2135  br i1 %v4, label %d.latch, label %b.latch
2136
2137d.latch:
2138  br label %d.header
2139
2140c.latch:
2141  %v5 = call i1 @cond()
2142  br i1 %v5, label %c.header, label %loopexit.c
2143
2144b.latch:
2145  br label %b.header
2146
2147a.latch:
2148  br label %a.header
2149
2150loopexit.d:
2151  br label %exit
2152
2153loopexit.c:
2154  br label %exit
2155
2156exit:
2157  ret void
2158}
2159
2160; Unswitch will transform the loop nest from:
2161;   A < B < C < D
2162; into
2163;   A < ((B < C), D)
2164define void @hoist_inner_loop5(i32* %ptr) {
2165; CHECK-LABEL: @hoist_inner_loop5(
2166; CHECK-NEXT:  entry:
2167; CHECK-NEXT:    br label [[A_HEADER:%.*]]
2168; CHECK:       a.header:
2169; CHECK-NEXT:    [[X_A:%.*]] = load i32, i32* [[PTR:%.*]], align 4
2170; CHECK-NEXT:    br label [[B_HEADER:%.*]]
2171; CHECK:       b.header:
2172; CHECK-NEXT:    [[X_B:%.*]] = load i32, i32* [[PTR]], align 4
2173; CHECK-NEXT:    br label [[C_HEADER:%.*]]
2174; CHECK:       c.header:
2175; CHECK-NEXT:    [[X_C:%.*]] = load i32, i32* [[PTR]], align 4
2176; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()
2177; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
2178; CHECK-NEXT:    br i1 [[V1_FR]], label [[C_HEADER_SPLIT_US:%.*]], label [[C_HEADER_SPLIT:%.*]]
2179; CHECK:       c.header.split.us:
2180; CHECK-NEXT:    br label [[D_HEADER_US:%.*]]
2181; CHECK:       d.header.us:
2182; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @d()
2183; CHECK-NEXT:    br label [[C_LATCH_SPLIT_US:%.*]]
2184; CHECK:       c.latch.split.us:
2185; CHECK-NEXT:    br label [[C_LATCH:%.*]]
2186; CHECK:       c.header.split:
2187; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[C_HEADER]] ]
2188; CHECK-NEXT:    [[X_C_LCSSA:%.*]] = phi i32 [ [[X_C]], [[C_HEADER]] ]
2189; CHECK-NEXT:    br label [[D_HEADER:%.*]]
2190; CHECK:       d.header:
2191; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @d()
2192; CHECK-NEXT:    br label [[D_LATCH:%.*]]
2193; CHECK:       d.latch:
2194; CHECK-NEXT:    store i32 [[X_A]], i32* [[PTR]], align 4
2195; CHECK-NEXT:    store i32 [[X_B_LCSSA]], i32* [[PTR]], align 4
2196; CHECK-NEXT:    store i32 [[X_C_LCSSA]], i32* [[PTR]], align 4
2197; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
2198; CHECK-NEXT:    br i1 [[V2]], label [[D_HEADER]], label [[A_LATCH:%.*]]
2199; CHECK:       c.latch:
2200; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
2201; CHECK-NEXT:    br i1 [[V3]], label [[C_HEADER]], label [[B_LATCH:%.*]]
2202; CHECK:       b.latch:
2203; CHECK-NEXT:    br label [[B_HEADER]]
2204; CHECK:       a.latch:
2205; CHECK-NEXT:    br label [[A_HEADER]]
2206; CHECK:       exit:
2207; CHECK-NEXT:    ret void
2208;
2209entry:
2210  br label %a.header
2211
2212a.header:
2213  %x.a = load i32, i32* %ptr
2214  br label %b.header
2215
2216b.header:
2217  %x.b = load i32, i32* %ptr
2218  br label %c.header
2219
2220c.header:
2221  %x.c = load i32, i32* %ptr
2222  %v1 = call i1 @cond()
2223  br label %d.header
2224
2225d.header:
2226  call i32 @d()
2227  br i1 %v1, label %c.latch, label %d.latch
2228
2229d.latch:
2230  ; Use values from other loops to check LCSSA form.
2231  store i32 %x.a, i32* %ptr
2232  store i32 %x.b, i32* %ptr
2233  store i32 %x.c, i32* %ptr
2234  %v2 = call i1 @cond()
2235  br i1 %v2, label %d.header, label %a.latch
2236
2237c.latch:
2238  %v3 = call i1 @cond()
2239  br i1 %v3, label %c.header, label %b.latch
2240
2241b.latch:
2242  br label %b.header
2243
2244a.latch:
2245  br label %a.header
2246
2247exit:
2248  ret void
2249}
2250
2251define void @hoist_inner_loop_switch(i32* %ptr) {
2252; CHECK-LABEL: @hoist_inner_loop_switch(
2253; CHECK-NEXT:  entry:
2254; CHECK-NEXT:    br label [[A_HEADER:%.*]]
2255; CHECK:       a.header:
2256; CHECK-NEXT:    [[X_A:%.*]] = load i32, i32* [[PTR:%.*]], align 4
2257; CHECK-NEXT:    br label [[B_HEADER:%.*]]
2258; CHECK:       b.header:
2259; CHECK-NEXT:    [[X_B:%.*]] = load i32, i32* [[PTR]], align 4
2260; CHECK-NEXT:    [[V1:%.*]] = call i32 @cond.i32()
2261; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i32 [[V1]]
2262; CHECK-NEXT:    switch i32 [[V1_FR]], label [[B_HEADER_SPLIT:%.*]] [
2263; CHECK-NEXT:    i32 1, label [[B_HEADER_SPLIT_US:%.*]]
2264; CHECK-NEXT:    i32 2, label [[B_HEADER_SPLIT_US]]
2265; CHECK-NEXT:    i32 3, label [[B_HEADER_SPLIT_US]]
2266; CHECK-NEXT:    ]
2267; CHECK:       b.header.split.us:
2268; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]
2269; CHECK:       c.header.us:
2270; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()
2271; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]
2272; CHECK:       b.latch.split.us:
2273; CHECK-NEXT:    br label [[B_LATCH:%.*]]
2274; CHECK:       b.header.split:
2275; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]
2276; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]
2277; CHECK-NEXT:    br label [[C_HEADER:%.*]]
2278; CHECK:       c.header:
2279; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()
2280; CHECK-NEXT:    br label [[C_LATCH:%.*]]
2281; CHECK:       c.latch:
2282; CHECK-NEXT:    store i32 [[X_A_LCSSA]], i32* [[PTR]], align 4
2283; CHECK-NEXT:    store i32 [[X_B_LCSSA]], i32* [[PTR]], align 4
2284; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()
2285; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[EXIT:%.*]]
2286; CHECK:       b.latch:
2287; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()
2288; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]
2289; CHECK:       a.latch:
2290; CHECK-NEXT:    br label [[A_HEADER]]
2291; CHECK:       exit:
2292; CHECK-NEXT:    ret void
2293;
2294entry:
2295  br label %a.header
2296
2297a.header:
2298  %x.a = load i32, i32* %ptr
2299  br label %b.header
2300
2301b.header:
2302  %x.b = load i32, i32* %ptr
2303  %v1 = call i32 @cond.i32()
2304  br label %c.header
2305
2306c.header:
2307  call i32 @c()
2308  switch i32 %v1, label %c.latch [
2309  i32 1, label %b.latch
2310  i32 2, label %b.latch
2311  i32 3, label %b.latch
2312  ]
2313
2314c.latch:
2315  ; Use values from other loops to check LCSSA form.
2316  store i32 %x.a, i32* %ptr
2317  store i32 %x.b, i32* %ptr
2318  %v2 = call i1 @cond()
2319  br i1 %v2, label %c.header, label %exit
2320
2321b.latch:
2322  %v3 = call i1 @cond()
2323  br i1 %v3, label %b.header, label %a.latch
2324
2325a.latch:
2326  br label %a.header
2327
2328exit:
2329  ret void
2330}
2331
2332define i32 @test_partial_unswitch_all_conds_guaranteed_non_poison(i1 noundef %c.1, i1 noundef %c.2) {
2333; CHECK-LABEL: @test_partial_unswitch_all_conds_guaranteed_non_poison(
2334; CHECK-NEXT:  entry:
2335; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[C_1:%.*]], [[C_2:%.*]]
2336; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
2337; CHECK:       entry.split.us:
2338; CHECK-NEXT:    br label [[LOOP_US:%.*]]
2339; CHECK:       loop.us:
2340; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @a()
2341; CHECK-NEXT:    br label [[EXIT_SPLIT_US:%.*]]
2342; CHECK:       exit.split.us:
2343; CHECK-NEXT:    br label [[EXIT:%.*]]
2344; CHECK:       entry.split:
2345; CHECK-NEXT:    br label [[LOOP:%.*]]
2346; CHECK:       loop:
2347; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @a()
2348; CHECK-NEXT:    [[SEL:%.*]] = select i1 true, i1 true, i1 false
2349; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT_SPLIT:%.*]]
2350; CHECK:       exit.split:
2351; CHECK-NEXT:    br label [[EXIT]]
2352; CHECK:       exit:
2353; CHECK-NEXT:    ret i32 0
2354;
2355entry:
2356  br label %loop
2357
2358loop:
2359  call i32 @a()
2360  %sel = select i1 %c.1, i1 %c.2, i1 false
2361  br i1 %sel, label %loop, label %exit
2362
2363exit:
2364  ret i32 0
2365}
2366