xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/partial-unswitch.ll (revision 6561fa3d02b746743139212f31f24c4a81e5138c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
3
4declare void @clobber()
5
6define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) {
7; CHECK-LABEL: @partial_unswitch_true_successor(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
10; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
11; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
12; CHECK:       entry.split.us:
13; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
14; CHECK:       loop.header.us:
15; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
16; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
17; CHECK:       noclobber.us:
18; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
19; CHECK:       loop.latch.us:
20; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
21; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
22; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
23; CHECK:       exit.split.us:
24; CHECK-NEXT:    br label [[EXIT:%.*]]
25; CHECK:       entry.split:
26; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
27; CHECK:       loop.header:
28; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
29; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
30; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
31; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
32; CHECK:       noclobber:
33; CHECK-NEXT:    br label [[LOOP_LATCH]]
34; CHECK:       clobber:
35; CHECK-NEXT:    call void @clobber()
36; CHECK-NEXT:    br label [[LOOP_LATCH]]
37; CHECK:       loop.latch:
38; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
39; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
40; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
41; CHECK:       exit.split:
42; CHECK-NEXT:    br label [[EXIT]]
43; CHECK:       exit:
44; CHECK-NEXT:    ret i32 10
45;
46entry:
47  br label %loop.header
48
49loop.header:
50  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
51  %lv = load i32, ptr %ptr
52  %sc = icmp eq i32 %lv, 100
53  br i1 %sc, label %noclobber, label %clobber
54
55noclobber:
56  br label %loop.latch
57
58clobber:
59  call void @clobber()
60  br label %loop.latch
61
62loop.latch:
63  %c = icmp ult i32 %iv, %N
64  %iv.next = add i32 %iv, 1
65  br i1 %c, label %loop.header, label %exit
66
67exit:
68  ret i32 10
69}
70
71define i32 @partial_unswitch_false_successor(ptr %ptr, i32 %N) {
72; CHECK-LABEL: @partial_unswitch_false_successor(
73; CHECK-NEXT:  entry:
74; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
75; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
76; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
77; CHECK:       entry.split.us:
78; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
79; CHECK:       loop.header.us:
80; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
81; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
82; CHECK:       noclobber.us:
83; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
84; CHECK:       loop.latch.us:
85; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
86; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
87; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
88; CHECK:       exit.split.us:
89; CHECK-NEXT:    br label [[EXIT:%.*]]
90; CHECK:       entry.split:
91; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
92; CHECK:       loop.header:
93; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
94; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
95; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
96; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
97; CHECK:       clobber:
98; CHECK-NEXT:    call void @clobber()
99; CHECK-NEXT:    br label [[LOOP_LATCH]]
100; CHECK:       noclobber:
101; CHECK-NEXT:    br label [[LOOP_LATCH]]
102; CHECK:       loop.latch:
103; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
104; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
105; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
106; CHECK:       exit.split:
107; CHECK-NEXT:    br label [[EXIT]]
108; CHECK:       exit:
109; CHECK-NEXT:    ret i32 10
110;
111entry:
112  br label %loop.header
113
114loop.header:
115  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
116  %lv = load i32, ptr %ptr
117  %sc = icmp eq i32 %lv, 100
118  br i1 %sc, label %clobber, label %noclobber
119
120clobber:
121  call void @clobber()
122  br label %loop.latch
123
124noclobber:
125  br label %loop.latch
126
127loop.latch:
128  %c = icmp ult i32 %iv, %N
129  %iv.next = add i32 %iv, 1
130  br i1 %c, label %loop.header, label %exit
131
132exit:
133  ret i32 10
134}
135
136define i32 @partial_unswtich_gep_load_icmp(ptr %ptr, i32 %N) {
137; CHECK-LABEL: @partial_unswtich_gep_load_icmp(
138; CHECK-NEXT:  entry:
139; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr ptr, ptr [[PTR:%.*]], i32 1
140; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
141; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
142; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100
143; CHECK-NEXT:    br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
144; CHECK:       entry.split.us:
145; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
146; CHECK:       loop.header.us:
147; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
148; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
149; CHECK:       noclobber.us:
150; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
151; CHECK:       loop.latch.us:
152; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
153; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
154; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
155; CHECK:       exit.split.us:
156; CHECK-NEXT:    br label [[EXIT:%.*]]
157; CHECK:       entry.split:
158; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
159; CHECK:       loop.header:
160; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
161; CHECK-NEXT:    [[GEP:%.*]] = getelementptr ptr, ptr [[PTR]], i32 1
162; CHECK-NEXT:    [[LV_1:%.*]] = load ptr, ptr [[GEP]], align 8
163; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[LV_1]], align 4
164; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
165; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
166; CHECK:       noclobber:
167; CHECK-NEXT:    br label [[LOOP_LATCH]]
168; CHECK:       clobber:
169; CHECK-NEXT:    call void @clobber()
170; CHECK-NEXT:    br label [[LOOP_LATCH]]
171; CHECK:       loop.latch:
172; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
173; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
174; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
175; CHECK:       exit.split:
176; CHECK-NEXT:    br label [[EXIT]]
177; CHECK:       exit:
178; CHECK-NEXT:    ret i32 10
179;
180entry:
181  br label %loop.header
182
183loop.header:
184  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
185  %gep = getelementptr ptr, ptr %ptr, i32 1
186  %lv.1 = load ptr, ptr %gep
187  %lv = load i32, ptr %lv.1
188  %sc = icmp eq i32 %lv, 100
189  br i1 %sc, label %noclobber, label %clobber
190
191noclobber:
192  br label %loop.latch
193
194clobber:
195  call void @clobber()
196  br label %loop.latch
197
198loop.latch:
199  %c = icmp ult i32 %iv, %N
200  %iv.next = add i32 %iv, 1
201  br i1 %c, label %loop.header, label %exit
202
203exit:
204  ret i32 10
205}
206
207define i32 @partial_unswitch_reduction_phi(ptr %ptr, i32 %N) {
208; CHECK-LABEL: @partial_unswitch_reduction_phi(
209; CHECK-NEXT:  entry:
210; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
211; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
212; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
213; CHECK:       entry.split.us:
214; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
215; CHECK:       loop.header.us:
216; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
217; CHECK-NEXT:    [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ]
218; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
219; CHECK:       noclobber.us:
220; CHECK-NEXT:    [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10
221; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
222; CHECK:       loop.latch.us:
223; CHECK-NEXT:    [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ]
224; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
225; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
226; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
227; CHECK:       exit.split.us:
228; CHECK-NEXT:    [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ]
229; CHECK-NEXT:    br label [[EXIT:%.*]]
230; CHECK:       entry.split:
231; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
232; CHECK:       loop.header:
233; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
234; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ]
235; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
236; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
237; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
238; CHECK:       clobber:
239; CHECK-NEXT:    call void @clobber()
240; CHECK-NEXT:    [[ADD_5:%.*]] = add i32 [[RED]], 5
241; CHECK-NEXT:    br label [[LOOP_LATCH]]
242; CHECK:       noclobber:
243; CHECK-NEXT:    [[ADD_10:%.*]] = add i32 [[RED]], 10
244; CHECK-NEXT:    br label [[LOOP_LATCH]]
245; CHECK:       loop.latch:
246; CHECK-NEXT:    [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ]
247; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
248; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
249; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP4:![0-9]+]]
250; CHECK:       exit.split:
251; CHECK-NEXT:    [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]
252; CHECK-NEXT:    br label [[EXIT]]
253; CHECK:       exit:
254; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ]
255; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
256;
257entry:
258  br label %loop.header
259
260loop.header:
261  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
262  %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]
263  %lv = load i32, ptr %ptr
264  %sc = icmp eq i32 %lv, 100
265  br i1 %sc, label %clobber, label %noclobber
266
267clobber:
268  call void @clobber()
269  %add.5 = add i32 %red, 5
270  br label %loop.latch
271
272noclobber:
273  %add.10 = add i32 %red, 10
274  br label %loop.latch
275
276loop.latch:
277  %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]
278  %c = icmp ult i32 %iv, %N
279  %iv.next = add i32 %iv, 1
280  br i1 %c, label %loop.header, label %exit
281
282exit:
283  %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
284  ret i32 %red.next.lcssa
285}
286
287; Partial unswitching is possible, because the store in %noclobber does not
288; alias the load of the condition.
289define i32 @partial_unswitch_true_successor_noclobber(ptr noalias %ptr.1, ptr noalias %ptr.2, i32 %N) {
290; CHECK-LABEL: @partial_unswitch_true_successor_noclobber(
291; CHECK-NEXT:  entry:
292; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4
293; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
294; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
295; CHECK:       entry.split.us:
296; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
297; CHECK:       loop.header.us:
298; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
299; CHECK-NEXT:    [[LV_US:%.*]] = load i32, ptr [[PTR_1]], align 4
300; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
301; CHECK:       noclobber.us:
302; CHECK-NEXT:    [[GEP_1_US:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV_US]]
303; CHECK-NEXT:    store i32 [[LV_US]], ptr [[GEP_1_US]], align 4
304; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
305; CHECK:       loop.latch.us:
306; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
307; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
308; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
309; CHECK:       exit.split.us:
310; CHECK-NEXT:    br label [[EXIT:%.*]]
311; CHECK:       entry.split:
312; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
313; CHECK:       loop.header:
314; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
315; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR_1]], align 4
316; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
317; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
318; CHECK:       noclobber:
319; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2]], i32 [[IV]]
320; CHECK-NEXT:    store i32 [[LV]], ptr [[GEP_1]], align 4
321; CHECK-NEXT:    br label [[LOOP_LATCH]]
322; CHECK:       clobber:
323; CHECK-NEXT:    call void @clobber()
324; CHECK-NEXT:    br label [[LOOP_LATCH]]
325; CHECK:       loop.latch:
326; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
327; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
328; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP5:![0-9]+]]
329; CHECK:       exit.split:
330; CHECK-NEXT:    br label [[EXIT]]
331; CHECK:       exit:
332; CHECK-NEXT:    ret i32 10
333;
334entry:
335  br label %loop.header
336
337loop.header:
338  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
339  %lv = load i32, ptr %ptr.1
340  %sc = icmp eq i32 %lv, 100
341  br i1 %sc, label %noclobber, label %clobber
342
343noclobber:
344  %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv
345  store i32 %lv, ptr %gep.1
346  br label %loop.latch
347
348clobber:
349  call void @clobber()
350  br label %loop.latch
351
352loop.latch:
353  %c = icmp ult i32 %iv, %N
354  %iv.next = add i32 %iv, 1
355  br i1 %c, label %loop.header, label %exit
356
357exit:
358  ret i32 10
359}
360
361define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
362; CHECK-LABEL: @no_partial_unswitch_phi_cond(
363; CHECK-NEXT:  entry:
364; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
365; CHECK:       loop.header:
366; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
367; CHECK-NEXT:    [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ]
368; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
369; CHECK:       clobber:
370; CHECK-NEXT:    call void @clobber()
371; CHECK-NEXT:    br label [[LOOP_LATCH]]
372; CHECK:       noclobber:
373; CHECK-NEXT:    br label [[LOOP_LATCH]]
374; CHECK:       loop.latch:
375; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
376; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
377; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
378; CHECK:       exit:
379; CHECK-NEXT:    ret void
380;
381entry:
382  br label %loop.header
383
384loop.header:
385  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
386  %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]
387  br i1 %sc, label %clobber, label %noclobber
388
389clobber:
390  call void @clobber()
391  br label %loop.latch
392
393noclobber:
394  br label %loop.latch
395
396loop.latch:
397  %c = icmp ult i32 %iv, %N
398  %iv.next = add i32 %iv, 1
399  br i1 %c, label %loop.header, label %exit
400
401exit:
402  ret void
403}
404
405define void @no_partial_unswitch_clobber_latch(ptr %ptr, i32 %N) {
406; CHECK-LABEL: @no_partial_unswitch_clobber_latch(
407; CHECK-NEXT:  entry:
408; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
409; CHECK:       loop.header:
410; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
411; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4
412; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
413; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
414; CHECK:       noclobber:
415; CHECK-NEXT:    br label [[LOOP_LATCH]]
416; CHECK:       clobber:
417; CHECK-NEXT:    call void @clobber()
418; CHECK-NEXT:    br label [[LOOP_LATCH]]
419; CHECK:       loop.latch:
420; CHECK-NEXT:    call void @clobber()
421; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
422; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
423; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
424; CHECK:       exit:
425; CHECK-NEXT:    ret void
426;
427entry:
428  br label %loop.header
429
430loop.header:
431  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
432  %lv = load i32, ptr %ptr
433  %sc = icmp eq i32 %lv, 100
434  br i1 %sc, label %noclobber, label %clobber
435
436noclobber:
437  br label %loop.latch
438
439clobber:
440  call void @clobber()
441  br label %loop.latch
442
443loop.latch:
444  call void @clobber()
445  %c = icmp ult i32 %iv, %N
446  %iv.next = add i32 %iv, 1
447  br i1 %c, label %loop.header, label %exit
448
449exit:
450  ret void
451}
452
453define void @no_partial_unswitch_clobber_header(ptr %ptr, i32 %N) {
454; CHECK-LABEL: @no_partial_unswitch_clobber_header(
455; CHECK-NEXT:  entry:
456; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
457; CHECK:       loop.header:
458; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
459; CHECK-NEXT:    call void @clobber()
460; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4
461; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
462; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
463; CHECK:       noclobber:
464; CHECK-NEXT:    br label [[LOOP_LATCH]]
465; CHECK:       clobber:
466; CHECK-NEXT:    call void @clobber()
467; CHECK-NEXT:    br label [[LOOP_LATCH]]
468; CHECK:       loop.latch:
469; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
470; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
471; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
472; CHECK:       exit:
473; CHECK-NEXT:    ret void
474;
475entry:
476  br label %loop.header
477
478loop.header:
479  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
480  call void @clobber()
481  %lv = load i32, ptr %ptr
482  %sc = icmp eq i32 %lv, 100
483  br i1 %sc, label %noclobber, label %clobber
484
485noclobber:
486  br label %loop.latch
487
488clobber:
489  call void @clobber()
490  br label %loop.latch
491
492loop.latch:
493  %c = icmp ult i32 %iv, %N
494  %iv.next = add i32 %iv, 1
495  br i1 %c, label %loop.header, label %exit
496
497exit:
498  ret void
499}
500
501define void @no_partial_unswitch_clobber_both(ptr %ptr, i32 %N) {
502; CHECK-LABEL: @no_partial_unswitch_clobber_both(
503; CHECK-NEXT:  entry:
504; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
505; CHECK:       loop.header:
506; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
507; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4
508; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
509; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
510; CHECK:       noclobber:
511; CHECK-NEXT:    call void @clobber()
512; CHECK-NEXT:    br label [[LOOP_LATCH]]
513; CHECK:       clobber:
514; CHECK-NEXT:    call void @clobber()
515; CHECK-NEXT:    br label [[LOOP_LATCH]]
516; CHECK:       loop.latch:
517; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
518; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
519; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
520; CHECK:       exit:
521; CHECK-NEXT:    ret void
522;
523entry:
524  br label %loop.header
525
526loop.header:
527  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
528  %lv = load i32, ptr %ptr
529  %sc = icmp eq i32 %lv, 100
530  br i1 %sc, label %noclobber, label %clobber
531
532noclobber:
533  call void @clobber()
534  br label %loop.latch
535
536clobber:
537  call void @clobber()
538  br label %loop.latch
539
540loop.latch:
541  %c = icmp ult i32 %iv, %N
542  %iv.next = add i32 %iv, 1
543  br i1 %c, label %loop.header, label %exit
544
545exit:
546  ret void
547}
548
549define i32 @no_partial_unswitch_true_successor_storeclobber(ptr %ptr.1, ptr %ptr.2, i32 %N) {
550; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber(
551; CHECK-NEXT:  entry:
552; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
553; CHECK:       loop.header:
554; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
555; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4
556; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
557; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
558; CHECK:       noclobber:
559; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV]]
560; CHECK-NEXT:    store i32 [[LV]], ptr [[GEP_1]], align 4
561; CHECK-NEXT:    br label [[LOOP_LATCH]]
562; CHECK:       clobber:
563; CHECK-NEXT:    call void @clobber()
564; CHECK-NEXT:    br label [[LOOP_LATCH]]
565; CHECK:       loop.latch:
566; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
567; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
568; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
569; CHECK:       exit:
570; CHECK-NEXT:    ret i32 10
571;
572entry:
573  br label %loop.header
574
575loop.header:
576  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
577  %lv = load i32, ptr %ptr.1
578  %sc = icmp eq i32 %lv, 100
579  br i1 %sc, label %noclobber, label %clobber
580
581noclobber:
582  %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv
583  store i32 %lv, ptr %gep.1
584  br label %loop.latch
585
586clobber:
587  call void @clobber()
588  br label %loop.latch
589
590loop.latch:
591  %c = icmp ult i32 %iv, %N
592  %iv.next = add i32 %iv, 1
593  br i1 %c, label %loop.header, label %exit
594
595exit:
596  ret i32 10
597}
598
599; Make sure the duplicated instructions are moved to a preheader that always
600; executes when the loop body also executes. Do not check the unswitched code,
601; because it is already checked in the @partial_unswitch_true_successor test
602; case.
603define i32 @partial_unswitch_true_successor_preheader_insertion(ptr %ptr, i32 %N) {
604; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
605; CHECK-NEXT:  entry:
606; CHECK-NEXT:    [[EC:%.*]] = icmp ne ptr [[PTR:%.*]], null
607; CHECK-NEXT:    br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
608; CHECK:       loop.ph:
609; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR]], align 4
610; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
611; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]]
612; CHECK:       loop.ph.split.us:
613; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
614; CHECK:       loop.header.us:
615; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
616; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
617; CHECK:       noclobber.us:
618; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
619; CHECK:       loop.latch.us:
620; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
621; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
622; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]]
623; CHECK:       exit.loopexit.split.us:
624; CHECK-NEXT:    br label [[EXIT_LOOPEXIT:%.*]]
625; CHECK:       loop.ph.split:
626; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
627; CHECK:       loop.header:
628; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
629; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
630; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
631; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
632; CHECK:       noclobber:
633; CHECK-NEXT:    br label [[LOOP_LATCH]]
634; CHECK:       clobber:
635; CHECK-NEXT:    call void @clobber()
636; CHECK-NEXT:    br label [[LOOP_LATCH]]
637; CHECK:       loop.latch:
638; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
639; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
640; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]]
641; CHECK:       exit.loopexit.split:
642; CHECK-NEXT:    br label [[EXIT_LOOPEXIT]]
643; CHECK:       exit.loopexit:
644; CHECK-NEXT:    br label [[EXIT]]
645; CHECK:       exit:
646; CHECK-NEXT:    ret i32 10
647;
648
649entry:
650  %ec = icmp ne ptr %ptr, null
651  br i1 %ec, label %loop.ph, label %exit
652
653loop.ph:
654  br label %loop.header
655
656loop.header:
657  %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
658  %lv = load i32, ptr %ptr
659  %sc = icmp eq i32 %lv, 100
660  br i1 %sc, label %noclobber, label %clobber
661
662noclobber:
663  br label %loop.latch
664
665clobber:
666  call void @clobber()
667  br label %loop.latch
668
669loop.latch:
670  %c = icmp ult i32 %iv, %N
671  %iv.next = add i32 %iv, 1
672  br i1 %c, label %loop.header, label %exit
673
674exit:
675  ret i32 10
676}
677
678; Make sure the duplicated instructions are hoisted just before the branch of
679; the preheader. Do not check the unswitched code, because it is already checked
680; in the @partial_unswitch_true_successor test case
681define i32 @partial_unswitch_true_successor_insert_point(ptr %ptr, i32 %N) {
682; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
683; CHECK-NEXT:  entry:
684; CHECK-NEXT:    call void @clobber()
685; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
686; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
687; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
688; CHECK:       entry.split.us:
689; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
690; CHECK:       loop.header.us:
691; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
692; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
693; CHECK:       noclobber.us:
694; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
695; CHECK:       loop.latch.us:
696; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
697; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
698; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
699; CHECK:       exit.split.us:
700; CHECK-NEXT:    br label [[EXIT:%.*]]
701; CHECK:       entry.split:
702; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
703; CHECK:       loop.header:
704; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
705; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
706; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
707; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
708; CHECK:       noclobber:
709; CHECK-NEXT:    br label [[LOOP_LATCH]]
710; CHECK:       clobber:
711; CHECK-NEXT:    call void @clobber()
712; CHECK-NEXT:    br label [[LOOP_LATCH]]
713; CHECK:       loop.latch:
714; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
715; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
716; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]]
717; CHECK:       exit.split:
718; CHECK-NEXT:    br label [[EXIT]]
719; CHECK:       exit:
720; CHECK-NEXT:    ret i32 10
721;
722entry:
723  call void @clobber()
724  br label %loop.header
725
726loop.header:
727  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
728  %lv = load i32, ptr %ptr
729  %sc = icmp eq i32 %lv, 100
730  br i1 %sc, label %noclobber, label %clobber
731
732noclobber:
733  br label %loop.latch
734
735clobber:
736  call void @clobber()
737  br label %loop.latch
738
739loop.latch:
740  %c = icmp ult i32 %iv, %N
741  %iv.next = add i32 %iv, 1
742  br i1 %c, label %loop.header, label %exit
743
744exit:
745  ret i32 10
746}
747
748; Make sure invariant instructions in the loop are also hoisted to the preheader.
749; Do not check the unswitched code, because it is already checked in the
750; @partial_unswitch_true_successor test case
751define i32 @partial_unswitch_true_successor_hoist_invariant(ptr %ptr, i32 %N) {
752; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
753; CHECK-NEXT:  entry:
754; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 1
755; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
756; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100
757; CHECK-NEXT:    br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
758; CHECK:       entry.split.us:
759; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
760; CHECK:       loop.header.us:
761; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
762; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
763; CHECK:       noclobber.us:
764; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
765; CHECK:       loop.latch.us:
766; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
767; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
768; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
769; CHECK:       exit.split.us:
770; CHECK-NEXT:    br label [[EXIT:%.*]]
771; CHECK:       entry.split:
772; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
773; CHECK:       loop.header:
774; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
775; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i64 1
776; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[GEP]], align 4
777; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
778; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
779; CHECK:       noclobber:
780; CHECK-NEXT:    br label [[LOOP_LATCH]]
781; CHECK:       clobber:
782; CHECK-NEXT:    call void @clobber()
783; CHECK-NEXT:    br label [[LOOP_LATCH]]
784; CHECK:       loop.latch:
785; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
786; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
787; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]]
788; CHECK:       exit.split:
789; CHECK-NEXT:    br label [[EXIT]]
790; CHECK:       exit:
791; CHECK-NEXT:    ret i32 10
792;
793entry:
794  br label %loop.header
795
796loop.header:
797  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
798  %gep = getelementptr i32, ptr %ptr, i64 1
799  %lv = load i32, ptr %gep
800  %sc = icmp eq i32 %lv, 100
801  br i1 %sc, label %noclobber, label %clobber
802
803noclobber:
804  br label %loop.latch
805
806clobber:
807  call void @clobber()
808  br label %loop.latch
809
810loop.latch:
811  %c = icmp ult i32 %iv, %N
812  %iv.next = add i32 %iv, 1
813  br i1 %c, label %loop.header, label %exit
814
815exit:
816  ret i32 10
817}
818
819; Do not unswitch if the condition depends on an atomic load. Duplicating such
820; loads is not safe.
821define i32 @no_partial_unswitch_atomic_load_unordered(ptr %ptr, i32 %N) {
822; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered(
823; CHECK-NEXT:  entry:
824; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
825; CHECK:       loop.header:
826; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
827; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] unordered, align 4
828; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
829; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
830; CHECK:       noclobber:
831; CHECK-NEXT:    br label [[LOOP_LATCH]]
832; CHECK:       clobber:
833; CHECK-NEXT:    call void @clobber()
834; CHECK-NEXT:    br label [[LOOP_LATCH]]
835; CHECK:       loop.latch:
836; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
837; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
838; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
839; CHECK:       exit:
840; CHECK-NEXT:    ret i32 10
841;
842entry:
843  br label %loop.header
844
845loop.header:
846  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
847  %lv = load atomic i32, ptr %ptr unordered, align 4
848  %sc = icmp eq i32 %lv, 100
849  br i1 %sc, label %noclobber, label %clobber
850
851noclobber:
852  br label %loop.latch
853
854clobber:
855  call void @clobber()
856  br label %loop.latch
857
858loop.latch:
859  %c = icmp ult i32 %iv, %N
860  %iv.next = add i32 %iv, 1
861  br i1 %c, label %loop.header, label %exit
862
863exit:
864  ret i32 10
865}
866
867; Do not unswitch if the condition depends on an atomic load. Duplicating such
868; loads is not safe.
869define i32 @no_partial_unswitch_atomic_load_monotonic(ptr %ptr, i32 %N) {
870; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic(
871; CHECK-NEXT:  entry:
872; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
873; CHECK:       loop.header:
874; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
875; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
876; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
877; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
878; CHECK:       noclobber:
879; CHECK-NEXT:    br label [[LOOP_LATCH]]
880; CHECK:       clobber:
881; CHECK-NEXT:    call void @clobber()
882; CHECK-NEXT:    br label [[LOOP_LATCH]]
883; CHECK:       loop.latch:
884; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
885; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
886; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
887; CHECK:       exit:
888; CHECK-NEXT:    ret i32 10
889;
890entry:
891  br label %loop.header
892
893loop.header:
894  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
895  %lv = load atomic i32, ptr %ptr monotonic, align 4
896  %sc = icmp eq i32 %lv, 100
897  br i1 %sc, label %noclobber, label %clobber
898
899noclobber:
900  br label %loop.latch
901
902clobber:
903  call void @clobber()
904  br label %loop.latch
905
906loop.latch:
907  %c = icmp ult i32 %iv, %N
908  %iv.next = add i32 %iv, 1
909  br i1 %c, label %loop.header, label %exit
910
911exit:
912  ret i32 10
913}
914
915
916declare i32 @get_value()
917
918; Do not unswitch if the condition depends on a call, that may clobber memory.
919; Duplicating such a call is not safe.
920define i32 @no_partial_unswitch_cond_call(ptr %ptr, i32 %N) {
921; CHECK-LABEL: @no_partial_unswitch_cond_call(
922; CHECK-NEXT:  entry:
923; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
924; CHECK:       loop.header:
925; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
926; CHECK-NEXT:    [[LV:%.*]] = call i32 @get_value()
927; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
928; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
929; CHECK:       noclobber:
930; CHECK-NEXT:    br label [[LOOP_LATCH]]
931; CHECK:       clobber:
932; CHECK-NEXT:    call void @clobber()
933; CHECK-NEXT:    br label [[LOOP_LATCH]]
934; CHECK:       loop.latch:
935; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
936; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
937; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
938; CHECK:       exit:
939; CHECK-NEXT:    ret i32 10
940;
941entry:
942  br label %loop.header
943
944loop.header:
945  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
946  %lv = call i32 @get_value()
947  %sc = icmp eq i32 %lv, 100
948  br i1 %sc, label %noclobber, label %clobber
949
950noclobber:
951  br label %loop.latch
952
953clobber:
954  call void @clobber()
955  br label %loop.latch
956
957loop.latch:
958  %c = icmp ult i32 %iv, %N
959  %iv.next = add i32 %iv, 1
960  br i1 %c, label %loop.header, label %exit
961
962exit:
963  ret i32 10
964}
965
966define i32 @no_partial_unswitch_true_successor_exit(ptr %ptr, i32 %N) {
967; CHECK-LABEL: @no_partial_unswitch_true_successor_exit(
968; CHECK-NEXT:  entry:
969; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
970; CHECK:       loop.header:
971; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
972; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4
973; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
974; CHECK-NEXT:    br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]]
975; CHECK:       clobber:
976; CHECK-NEXT:    call void @clobber()
977; CHECK-NEXT:    br label [[LOOP_LATCH]]
978; CHECK:       loop.latch:
979; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
980; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
981; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]]
982; CHECK:       exit:
983; CHECK-NEXT:    ret i32 10
984;
985entry:
986  br label %loop.header
987
988loop.header:
989  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
990  %lv = load i32, ptr %ptr
991  %sc = icmp eq i32 %lv, 100
992  br i1 %sc, label %exit, label %clobber
993
994clobber:
995  call void @clobber()
996  br label %loop.latch
997
998loop.latch:
999  %c = icmp ult i32 %iv, %N
1000  %iv.next = add i32 %iv, 1
1001  br i1 %c, label %loop.header, label %exit
1002
1003exit:
1004  ret i32 10
1005}
1006
1007define i32 @no_partial_unswitch_true_same_successor(ptr %ptr, i32 %N) {
1008; CHECK-LABEL: @no_partial_unswitch_true_same_successor(
1009; CHECK-NEXT:  entry:
1010; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1011; CHECK:       loop.header:
1012; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1013; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4
1014; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
1015; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]]
1016; CHECK:       noclobber:
1017; CHECK-NEXT:    br label [[LOOP_LATCH]]
1018; CHECK:       loop.latch:
1019; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
1020; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1021; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
1022; CHECK:       exit:
1023; CHECK-NEXT:    ret i32 10
1024;
1025entry:
1026  br label %loop.header
1027
1028loop.header:
1029  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1030  %lv = load i32, ptr %ptr
1031  %sc = icmp eq i32 %lv, 100
1032  br i1 %sc, label %noclobber, label %noclobber
1033
1034noclobber:
1035  br label %loop.latch
1036
1037loop.latch:
1038  %c = icmp ult i32 %iv, %N
1039  %iv.next = add i32 %iv, 1
1040  br i1 %c, label %loop.header, label %exit
1041
1042exit:
1043  ret i32 10
1044}
1045
1046define i32 @partial_unswitch_true_to_latch(ptr %ptr, i32 %N) {
1047; CHECK-LABEL: @partial_unswitch_true_to_latch(
1048; CHECK-NEXT:  entry:
1049; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
1050; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
1051; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1052; CHECK:       entry.split.us:
1053; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1054; CHECK:       loop.header.us:
1055; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1056; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1057; CHECK:       loop.latch.us:
1058; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1059; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1060; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1061; CHECK:       exit.split.us:
1062; CHECK-NEXT:    br label [[EXIT:%.*]]
1063; CHECK:       entry.split:
1064; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1065; CHECK:       loop.header:
1066; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1067; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
1068; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
1069; CHECK-NEXT:    br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]]
1070; CHECK:       clobber:
1071; CHECK-NEXT:    call void @clobber()
1072; CHECK-NEXT:    br label [[LOOP_LATCH]]
1073; CHECK:       loop.latch:
1074; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
1075; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1076; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]]
1077; CHECK:       exit.split:
1078; CHECK-NEXT:    br label [[EXIT]]
1079; CHECK:       exit:
1080; CHECK-NEXT:    ret i32 10
1081;
1082entry:
1083  br label %loop.header
1084
1085loop.header:
1086  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1087  %lv = load i32, ptr %ptr
1088  %sc = icmp eq i32 %lv, 100
1089  br i1 %sc, label %loop.latch, label %clobber
1090
1091clobber:
1092  call void @clobber()
1093  br label %loop.latch
1094
1095loop.latch:
1096  %c = icmp ult i32 %iv, %N
1097  %iv.next = add i32 %iv, 1
1098  br i1 %c, label %loop.header, label %exit
1099
1100exit:
1101  ret i32 10
1102}
1103
1104; There could be multiple unswitch candidates which include partially invariant
1105; condition. When the exiting block is selected as best unswitch one, clone loop
1106; blocks.
1107define i32 @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(i32 %0, i32 %1, ptr %ptr) {
1108; CHECK-LABEL: @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(
1109; CHECK-NEXT:  entry:
1110; CHECK-NEXT:    [[EXIT_COND:%.*]] = icmp ne i32 [[TMP0:%.*]], 0
1111; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[PTR:%.*]], align 16
1112; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 41
1113; CHECK-NEXT:    br i1 [[TMP3]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
1114; CHECK:       entry.split.us:
1115; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]]
1116; CHECK:       entry.split.us.split.us:
1117; CHECK-NEXT:    br label [[LOOP_US_US:%.*]]
1118; CHECK:       loop.us.us:
1119; CHECK-NEXT:    br label [[EXITING_US_US:%.*]]
1120; CHECK:       exiting.us.us:
1121; CHECK-NEXT:    br label [[LOOP_US_US]]
1122; CHECK:       entry.split.us.split:
1123; CHECK-NEXT:    br label [[LOOP_US:%.*]]
1124; CHECK:       loop.us:
1125; CHECK-NEXT:    br label [[EXITING_US:%.*]]
1126; CHECK:       exiting.us:
1127; CHECK-NEXT:    br label [[EXIT_SPLIT_US:%.*]]
1128; CHECK:       exit.split.us:
1129; CHECK-NEXT:    [[RET_VAL_US:%.*]] = phi i32 [ 1, [[EXITING_US]] ]
1130; CHECK-NEXT:    br label [[EXIT:%.*]]
1131; CHECK:       entry.split:
1132; CHECK-NEXT:    br label [[LOOP:%.*]]
1133; CHECK:       loop:
1134; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR]], align 16
1135; CHECK-NEXT:    [[IF_COND:%.*]] = icmp ult i32 [[VAL]], 41
1136; CHECK-NEXT:    br i1 [[IF_COND]], label [[IF_THEN:%.*]], label [[EXITING:%.*]]
1137; CHECK:       if.then:
1138; CHECK-NEXT:    store i32 [[TMP1:%.*]], ptr [[PTR]], align 16
1139; CHECK-NEXT:    br label [[EXITING]]
1140; CHECK:       exiting:
1141; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]]
1142; CHECK:       exit.split:
1143; CHECK-NEXT:    [[RET_VAL:%.*]] = phi i32 [ 1, [[EXITING]] ]
1144; CHECK-NEXT:    br label [[EXIT]]
1145; CHECK:       exit:
1146; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[RET_VAL]], [[EXIT_SPLIT]] ], [ [[RET_VAL_US]], [[EXIT_SPLIT_US]] ]
1147; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
1148;
1149entry:
1150  %exit.cond = icmp ne i32 %0, 0
1151  br label %loop
1152
1153loop:
1154  %val = load i32, ptr %ptr, align 16
1155  %if.cond = icmp ult i32 %val, 41
1156  br i1 %if.cond, label %if.then, label %exiting
1157
1158if.then:
1159  store i32 %1, ptr %ptr, align 16
1160  br label %exiting
1161
1162exiting:
1163  br i1 %exit.cond, label %loop, label %exit
1164
1165exit:
1166  %ret.val = phi i32 [ 1, %exiting ]
1167  ret i32 %ret.val
1168}
1169
1170; The path with noclobber block is only duplicated so we need to calculate only
1171; the cost of the path with noclobber.
1172define i32 @partial_unswitch_true_successor_for_cost_calculation(ptr %ptr, i32 %N) {
1173; CHECK-LABEL: @partial_unswitch_true_successor_for_cost_calculation(
1174; CHECK-NEXT:  entry:
1175; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
1176; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
1177; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1178; CHECK:       entry.split.us:
1179; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1180; CHECK:       loop.header.us:
1181; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1182; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
1183; CHECK:       noclobber.us:
1184; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1185; CHECK:       loop.latch.us:
1186; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1187; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1188; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1189; CHECK:       exit.split.us:
1190; CHECK-NEXT:    br label [[EXIT:%.*]]
1191; CHECK:       entry.split:
1192; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1193; CHECK:       loop.header:
1194; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1195; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
1196; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
1197; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
1198; CHECK:       noclobber:
1199; CHECK-NEXT:    br label [[LOOP_LATCH]]
1200; CHECK:       clobber:
1201; CHECK-NEXT:    call void @clobber()
1202; CHECK-NEXT:    call void @clobber()
1203; CHECK-NEXT:    call void @clobber()
1204; CHECK-NEXT:    call void @clobber()
1205; CHECK-NEXT:    call void @clobber()
1206; CHECK-NEXT:    call void @clobber()
1207; CHECK-NEXT:    call void @clobber()
1208; CHECK-NEXT:    call void @clobber()
1209; CHECK-NEXT:    call void @clobber()
1210; CHECK-NEXT:    call void @clobber()
1211; CHECK-NEXT:    call void @clobber()
1212; CHECK-NEXT:    call void @clobber()
1213; CHECK-NEXT:    call void @clobber()
1214; CHECK-NEXT:    call void @clobber()
1215; CHECK-NEXT:    call void @clobber()
1216; CHECK-NEXT:    call void @clobber()
1217; CHECK-NEXT:    call void @clobber()
1218; CHECK-NEXT:    call void @clobber()
1219; CHECK-NEXT:    call void @clobber()
1220; CHECK-NEXT:    call void @clobber()
1221; CHECK-NEXT:    call void @clobber()
1222; CHECK-NEXT:    call void @clobber()
1223; CHECK-NEXT:    call void @clobber()
1224; CHECK-NEXT:    call void @clobber()
1225; CHECK-NEXT:    call void @clobber()
1226; CHECK-NEXT:    call void @clobber()
1227; CHECK-NEXT:    call void @clobber()
1228; CHECK-NEXT:    call void @clobber()
1229; CHECK-NEXT:    call void @clobber()
1230; CHECK-NEXT:    call void @clobber()
1231; CHECK-NEXT:    call void @clobber()
1232; CHECK-NEXT:    call void @clobber()
1233; CHECK-NEXT:    call void @clobber()
1234; CHECK-NEXT:    call void @clobber()
1235; CHECK-NEXT:    call void @clobber()
1236; CHECK-NEXT:    call void @clobber()
1237; CHECK-NEXT:    call void @clobber()
1238; CHECK-NEXT:    call void @clobber()
1239; CHECK-NEXT:    call void @clobber()
1240; CHECK-NEXT:    call void @clobber()
1241; CHECK-NEXT:    call void @clobber()
1242; CHECK-NEXT:    call void @clobber()
1243; CHECK-NEXT:    call void @clobber()
1244; CHECK-NEXT:    call void @clobber()
1245; CHECK-NEXT:    call void @clobber()
1246; CHECK-NEXT:    call void @clobber()
1247; CHECK-NEXT:    call void @clobber()
1248; CHECK-NEXT:    br label [[LOOP_LATCH]]
1249; CHECK:       loop.latch:
1250; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
1251; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1252; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]]
1253; CHECK:       exit.split:
1254; CHECK-NEXT:    br label [[EXIT]]
1255; CHECK:       exit:
1256; CHECK-NEXT:    ret i32 10
1257;
1258entry:
1259  br label %loop.header
1260
1261loop.header:
1262  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1263  %lv = load i32, ptr %ptr
1264  %sc = icmp eq i32 %lv, 100
1265  br i1 %sc, label %noclobber, label %clobber
1266
1267noclobber:
1268  br label %loop.latch
1269
1270clobber:
1271  call void @clobber()
1272  call void @clobber()
1273  call void @clobber()
1274  call void @clobber()
1275  call void @clobber()
1276  call void @clobber()
1277  call void @clobber()
1278  call void @clobber()
1279  call void @clobber()
1280  call void @clobber()
1281  call void @clobber()
1282  call void @clobber()
1283  call void @clobber()
1284  call void @clobber()
1285  call void @clobber()
1286  call void @clobber()
1287  call void @clobber()
1288  call void @clobber()
1289  call void @clobber()
1290  call void @clobber()
1291  call void @clobber()
1292  call void @clobber()
1293  call void @clobber()
1294  call void @clobber()
1295  call void @clobber()
1296  call void @clobber()
1297  call void @clobber()
1298  call void @clobber()
1299  call void @clobber()
1300  call void @clobber()
1301  call void @clobber()
1302  call void @clobber()
1303  call void @clobber()
1304  call void @clobber()
1305  call void @clobber()
1306  call void @clobber()
1307  call void @clobber()
1308  call void @clobber()
1309  call void @clobber()
1310  call void @clobber()
1311  call void @clobber()
1312  call void @clobber()
1313  call void @clobber()
1314  call void @clobber()
1315  call void @clobber()
1316  call void @clobber()
1317  call void @clobber()
1318  br label %loop.latch
1319
1320loop.latch:
1321  %c = icmp ult i32 %iv, %N
1322  %iv.next = add i32 %iv, 1
1323  br i1 %c, label %loop.header, label %exit
1324
1325exit:
1326  ret i32 10
1327}
1328
1329define i32 @partial_unswitch_true_successor_trunc(ptr %ptr, i32 %N) {
1330; CHECK-LABEL: @partial_unswitch_true_successor_trunc(
1331; CHECK-NEXT:  entry:
1332; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
1333; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[TMP0]] to i1
1334; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1335; CHECK:       entry.split.us:
1336; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1337; CHECK:       loop.header.us:
1338; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1339; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
1340; CHECK:       noclobber.us:
1341; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1342; CHECK:       loop.latch.us:
1343; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1344; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1345; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1346; CHECK:       exit.split.us:
1347; CHECK-NEXT:    br label [[EXIT:%.*]]
1348; CHECK:       entry.split:
1349; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1350; CHECK:       loop.header:
1351; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1352; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
1353; CHECK-NEXT:    [[SC:%.*]] = trunc i32 [[LV]] to i1
1354; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
1355; CHECK:       noclobber:
1356; CHECK-NEXT:    br label [[LOOP_LATCH]]
1357; CHECK:       clobber:
1358; CHECK-NEXT:    call void @clobber()
1359; CHECK-NEXT:    br label [[LOOP_LATCH]]
1360; CHECK:       loop.latch:
1361; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
1362; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1363; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]]
1364; CHECK:       exit.split:
1365; CHECK-NEXT:    br label [[EXIT]]
1366; CHECK:       exit:
1367; CHECK-NEXT:    ret i32 10
1368;
1369entry:
1370  br label %loop.header
1371
1372loop.header:
1373  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1374  %lv = load i32, ptr %ptr
1375  %sc = trunc i32 %lv to i1
1376  br i1 %sc, label %noclobber, label %clobber
1377
1378noclobber:
1379  br label %loop.latch
1380
1381clobber:
1382  call void @clobber()
1383  br label %loop.latch
1384
1385loop.latch:
1386  %c = icmp ult i32 %iv, %N
1387  %iv.next = add i32 %iv, 1
1388  br i1 %c, label %loop.header, label %exit
1389
1390exit:
1391  ret i32 10
1392}
1393
1394define i32 @partial_unswitch_false_successor_trunc(ptr %ptr, i32 %N) {
1395; CHECK-LABEL: @partial_unswitch_false_successor_trunc(
1396; CHECK-NEXT:  entry:
1397; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
1398; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[TMP0]] to i1
1399; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
1400; CHECK:       entry.split.us:
1401; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1402; CHECK:       loop.header.us:
1403; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1404; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
1405; CHECK:       noclobber.us:
1406; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1407; CHECK:       loop.latch.us:
1408; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1409; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1410; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1411; CHECK:       exit.split.us:
1412; CHECK-NEXT:    br label [[EXIT:%.*]]
1413; CHECK:       entry.split:
1414; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1415; CHECK:       loop.header:
1416; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1417; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
1418; CHECK-NEXT:    [[SC:%.*]] = trunc i32 [[LV]] to i1
1419; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
1420; CHECK:       clobber:
1421; CHECK-NEXT:    call void @clobber()
1422; CHECK-NEXT:    br label [[LOOP_LATCH]]
1423; CHECK:       noclobber:
1424; CHECK-NEXT:    br label [[LOOP_LATCH]]
1425; CHECK:       loop.latch:
1426; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
1427; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1428; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP13:![0-9]+]]
1429; CHECK:       exit.split:
1430; CHECK-NEXT:    br label [[EXIT]]
1431; CHECK:       exit:
1432; CHECK-NEXT:    ret i32 10
1433;
1434entry:
1435  br label %loop.header
1436
1437loop.header:
1438  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1439  %lv = load i32, ptr %ptr
1440  %sc = trunc i32 %lv to i1
1441  br i1 %sc, label %clobber, label %noclobber
1442
1443clobber:
1444  call void @clobber()
1445  br label %loop.latch
1446
1447noclobber:
1448  br label %loop.latch
1449
1450loop.latch:
1451  %c = icmp ult i32 %iv, %N
1452  %iv.next = add i32 %iv, 1
1453  br i1 %c, label %loop.header, label %exit
1454
1455exit:
1456  ret i32 10
1457}
1458
1459; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[UNSWITCH_PARTIAL_DISABLE:![0-9]+]]}
1460; CHECK: [[UNSWITCH_PARTIAL_DISABLE]] = !{!"llvm.loop.unswitch.partial.disable"}
1461; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[UNSWITCH_PARTIAL_DISABLE]]}
1462; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[UNSWITCH_PARTIAL_DISABLE]]}
1463; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[UNSWITCH_PARTIAL_DISABLE]]}
1464; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[UNSWITCH_PARTIAL_DISABLE]]}
1465; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[UNSWITCH_PARTIAL_DISABLE]]}
1466; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[UNSWITCH_PARTIAL_DISABLE]]}
1467; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[UNSWITCH_PARTIAL_DISABLE]]}
1468; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[UNSWITCH_PARTIAL_DISABLE]]}
1469; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[UNSWITCH_PARTIAL_DISABLE]]}
1470; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[UNSWITCH_PARTIAL_DISABLE]]}
1471