1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='loop-mssa(unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
3
4declare void @clobber()
5
6define i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) {
7; CHECK-LABEL: @partial_unswitch_true_successor(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
10; CHECK:       loop.header:
11; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
13; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
14; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
15; CHECK:       noclobber:
16; CHECK-NEXT:    br label [[LOOP_LATCH]]
17; CHECK:       clobber:
18; CHECK-NEXT:    call void @clobber()
19; CHECK-NEXT:    br label [[LOOP_LATCH]]
20; CHECK:       loop.latch:
21; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
22; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
23; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
24; CHECK:       exit:
25; CHECK-NEXT:    ret i32 10
26;
27entry:
28  br label %loop.header
29
30loop.header:
31  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
32  %lv = load i32, i32* %ptr
33  %sc = icmp eq i32 %lv, 100
34  br i1 %sc, label %noclobber, label %clobber
35
36noclobber:
37  br label %loop.latch
38
39clobber:
40  call void @clobber()
41  br label %loop.latch
42
43loop.latch:
44  %c = icmp ult i32 %iv, %N
45  %iv.next = add i32 %iv, 1
46  br i1 %c, label %loop.header, label %exit
47
48exit:
49  ret i32 10
50}
51
52define i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) {
53; CHECK-LABEL: @partial_unswitch_false_successor(
54; CHECK-NEXT:  entry:
55; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
56; CHECK:       loop.header:
57; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
58; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
59; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
60; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
61; CHECK:       clobber:
62; CHECK-NEXT:    call void @clobber()
63; CHECK-NEXT:    br label [[LOOP_LATCH]]
64; CHECK:       noclobber:
65; CHECK-NEXT:    br label [[LOOP_LATCH]]
66; CHECK:       loop.latch:
67; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
68; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
69; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
70; CHECK:       exit:
71; CHECK-NEXT:    ret i32 10
72;
73entry:
74  br label %loop.header
75
76loop.header:
77  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
78  %lv = load i32, i32* %ptr
79  %sc = icmp eq i32 %lv, 100
80  br i1 %sc, label %clobber, label %noclobber
81
82clobber:
83  call void @clobber()
84  br label %loop.latch
85
86noclobber:
87  br label %loop.latch
88
89loop.latch:
90  %c = icmp ult i32 %iv, %N
91  %iv.next = add i32 %iv, 1
92  br i1 %c, label %loop.header, label %exit
93
94exit:
95  ret i32 10
96}
97
98define i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) {
99; CHECK-LABEL: @partial_unswtich_gep_load_icmp(
100; CHECK-NEXT:  entry:
101; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
102; CHECK:       loop.header:
103; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
104; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32*, i32** [[PTR:%.*]], i32 1
105; CHECK-NEXT:    [[LV_1:%.*]] = load i32*, i32** [[GEP]], align 8
106; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[LV_1]], align 4
107; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
108; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
109; CHECK:       noclobber:
110; CHECK-NEXT:    br label [[LOOP_LATCH]]
111; CHECK:       clobber:
112; CHECK-NEXT:    call void @clobber()
113; CHECK-NEXT:    br label [[LOOP_LATCH]]
114; CHECK:       loop.latch:
115; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
116; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
117; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
118; CHECK:       exit:
119; CHECK-NEXT:    ret i32 10
120;
121entry:
122  br label %loop.header
123
124loop.header:
125  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
126  %gep = getelementptr i32*, i32** %ptr, i32 1
127  %lv.1 = load i32*, i32** %gep
128  %lv = load i32, i32* %lv.1
129  %sc = icmp eq i32 %lv, 100
130  br i1 %sc, label %noclobber, label %clobber
131
132noclobber:
133  br label %loop.latch
134
135clobber:
136  call void @clobber()
137  br label %loop.latch
138
139loop.latch:
140  %c = icmp ult i32 %iv, %N
141  %iv.next = add i32 %iv, 1
142  br i1 %c, label %loop.header, label %exit
143
144exit:
145  ret i32 10
146}
147
148define i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) {
149; CHECK-LABEL: @partial_unswitch_reduction_phi(
150; CHECK-NEXT:  entry:
151; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
152; CHECK:       loop.header:
153; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
154; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ 20, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ]
155; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
156; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
157; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
158; CHECK:       clobber:
159; CHECK-NEXT:    call void @clobber()
160; CHECK-NEXT:    [[ADD_5:%.*]] = add i32 [[RED]], 5
161; CHECK-NEXT:    br label [[LOOP_LATCH]]
162; CHECK:       noclobber:
163; CHECK-NEXT:    [[ADD_10:%.*]] = add i32 [[RED]], 10
164; CHECK-NEXT:    br label [[LOOP_LATCH]]
165; CHECK:       loop.latch:
166; CHECK-NEXT:    [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ]
167; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
168; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
169; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
170; CHECK:       exit:
171; CHECK-NEXT:    [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]
172; CHECK-NEXT:    ret i32 [[RED_NEXT_LCSSA]]
173;
174entry:
175  br label %loop.header
176
177loop.header:
178  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
179  %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]
180  %lv = load i32, i32* %ptr
181  %sc = icmp eq i32 %lv, 100
182  br i1 %sc, label %clobber, label %noclobber
183
184clobber:
185  call void @clobber()
186  %add.5 = add i32 %red, 5
187  br label %loop.latch
188
189noclobber:
190  %add.10 = add i32 %red, 10
191  br label %loop.latch
192
193loop.latch:
194  %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]
195  %c = icmp ult i32 %iv, %N
196  %iv.next = add i32 %iv, 1
197  br i1 %c, label %loop.header, label %exit
198
199exit:
200  %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
201  ret i32 %red.next.lcssa
202}
203
204; Partial unswitching is possible, because the store in %noclobber does not
205; alias the load of the condition.
206define i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) {
207; CHECK-LABEL: @partial_unswitch_true_successor_noclobber(
208; CHECK-NEXT:  entry:
209; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
210; CHECK:       loop.header:
211; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
212; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4
213; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
214; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
215; CHECK:       noclobber:
216; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]]
217; CHECK-NEXT:    store i32 [[LV]], i32* [[GEP_1]], align 4
218; CHECK-NEXT:    br label [[LOOP_LATCH]]
219; CHECK:       clobber:
220; CHECK-NEXT:    call void @clobber()
221; CHECK-NEXT:    br label [[LOOP_LATCH]]
222; CHECK:       loop.latch:
223; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
224; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
225; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
226; CHECK:       exit:
227; CHECK-NEXT:    ret i32 10
228;
229entry:
230  br label %loop.header
231
232loop.header:
233  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
234  %lv = load i32, i32* %ptr.1
235  %sc = icmp eq i32 %lv, 100
236  br i1 %sc, label %noclobber, label %clobber
237
238noclobber:
239  %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
240  store i32 %lv, i32* %gep.1
241  br label %loop.latch
242
243clobber:
244  call void @clobber()
245  br label %loop.latch
246
247loop.latch:
248  %c = icmp ult i32 %iv, %N
249  %iv.next = add i32 %iv, 1
250  br i1 %c, label %loop.header, label %exit
251
252exit:
253  ret i32 10
254}
255
256define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
257; CHECK-LABEL: @no_partial_unswitch_phi_cond(
258; CHECK-NEXT:  entry:
259; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
260; CHECK:       loop.header:
261; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
262; CHECK-NEXT:    [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ]
263; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
264; CHECK:       clobber:
265; CHECK-NEXT:    call void @clobber()
266; CHECK-NEXT:    br label [[LOOP_LATCH]]
267; CHECK:       noclobber:
268; CHECK-NEXT:    br label [[LOOP_LATCH]]
269; CHECK:       loop.latch:
270; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
271; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
272; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
273; CHECK:       exit:
274; CHECK-NEXT:    ret void
275;
276entry:
277  br label %loop.header
278
279loop.header:
280  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
281  %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]
282  br i1 %sc, label %clobber, label %noclobber
283
284clobber:
285  call void @clobber()
286  br label %loop.latch
287
288noclobber:
289  br label %loop.latch
290
291loop.latch:
292  %c = icmp ult i32 %iv, %N
293  %iv.next = add i32 %iv, 1
294  br i1 %c, label %loop.header, label %exit
295
296exit:
297  ret void
298}
299
300define void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) {
301; CHECK-LABEL: @no_partial_unswitch_clobber_latch(
302; CHECK-NEXT:  entry:
303; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
304; CHECK:       loop.header:
305; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
306; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
307; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
308; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
309; CHECK:       noclobber:
310; CHECK-NEXT:    br label [[LOOP_LATCH]]
311; CHECK:       clobber:
312; CHECK-NEXT:    call void @clobber()
313; CHECK-NEXT:    br label [[LOOP_LATCH]]
314; CHECK:       loop.latch:
315; CHECK-NEXT:    call void @clobber()
316; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
317; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
318; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
319; CHECK:       exit:
320; CHECK-NEXT:    ret void
321;
322entry:
323  br label %loop.header
324
325loop.header:
326  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
327  %lv = load i32, i32* %ptr
328  %sc = icmp eq i32 %lv, 100
329  br i1 %sc, label %noclobber, label %clobber
330
331noclobber:
332  br label %loop.latch
333
334clobber:
335  call void @clobber()
336  br label %loop.latch
337
338loop.latch:
339  call void @clobber()
340  %c = icmp ult i32 %iv, %N
341  %iv.next = add i32 %iv, 1
342  br i1 %c, label %loop.header, label %exit
343
344exit:
345  ret void
346}
347
348define void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) {
349; CHECK-LABEL: @no_partial_unswitch_clobber_header(
350; CHECK-NEXT:  entry:
351; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
352; CHECK:       loop.header:
353; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
354; CHECK-NEXT:    call void @clobber()
355; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
356; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
357; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
358; CHECK:       noclobber:
359; CHECK-NEXT:    br label [[LOOP_LATCH]]
360; CHECK:       clobber:
361; CHECK-NEXT:    call void @clobber()
362; CHECK-NEXT:    br label [[LOOP_LATCH]]
363; CHECK:       loop.latch:
364; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
365; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
366; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
367; CHECK:       exit:
368; CHECK-NEXT:    ret void
369;
370entry:
371  br label %loop.header
372
373loop.header:
374  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
375  call void @clobber()
376  %lv = load i32, i32* %ptr
377  %sc = icmp eq i32 %lv, 100
378  br i1 %sc, label %noclobber, label %clobber
379
380noclobber:
381  br label %loop.latch
382
383clobber:
384  call void @clobber()
385  br label %loop.latch
386
387loop.latch:
388  %c = icmp ult i32 %iv, %N
389  %iv.next = add i32 %iv, 1
390  br i1 %c, label %loop.header, label %exit
391
392exit:
393  ret void
394}
395
396define void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) {
397; CHECK-LABEL: @no_partial_unswitch_clobber_both(
398; CHECK-NEXT:  entry:
399; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
400; CHECK:       loop.header:
401; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
402; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
403; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
404; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
405; CHECK:       noclobber:
406; CHECK-NEXT:    call void @clobber()
407; CHECK-NEXT:    br label [[LOOP_LATCH]]
408; CHECK:       clobber:
409; CHECK-NEXT:    call void @clobber()
410; CHECK-NEXT:    br label [[LOOP_LATCH]]
411; CHECK:       loop.latch:
412; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
413; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
414; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
415; CHECK:       exit:
416; CHECK-NEXT:    ret void
417;
418entry:
419  br label %loop.header
420
421loop.header:
422  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
423  %lv = load i32, i32* %ptr
424  %sc = icmp eq i32 %lv, 100
425  br i1 %sc, label %noclobber, label %clobber
426
427noclobber:
428  call void @clobber()
429  br label %loop.latch
430
431clobber:
432  call void @clobber()
433  br label %loop.latch
434
435loop.latch:
436  %c = icmp ult i32 %iv, %N
437  %iv.next = add i32 %iv, 1
438  br i1 %c, label %loop.header, label %exit
439
440exit:
441  ret void
442}
443
444define i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) {
445; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber(
446; CHECK-NEXT:  entry:
447; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
448; CHECK:       loop.header:
449; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
450; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4
451; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
452; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
453; CHECK:       noclobber:
454; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]]
455; CHECK-NEXT:    store i32 [[LV]], i32* [[GEP_1]], align 4
456; CHECK-NEXT:    br label [[LOOP_LATCH]]
457; CHECK:       clobber:
458; CHECK-NEXT:    call void @clobber()
459; CHECK-NEXT:    br label [[LOOP_LATCH]]
460; CHECK:       loop.latch:
461; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
462; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
463; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
464; CHECK:       exit:
465; CHECK-NEXT:    ret i32 10
466;
467entry:
468  br label %loop.header
469
470loop.header:
471  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
472  %lv = load i32, i32* %ptr.1
473  %sc = icmp eq i32 %lv, 100
474  br i1 %sc, label %noclobber, label %clobber
475
476noclobber:
477  %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
478  store i32 %lv, i32* %gep.1
479  br label %loop.latch
480
481clobber:
482  call void @clobber()
483  br label %loop.latch
484
485loop.latch:
486  %c = icmp ult i32 %iv, %N
487  %iv.next = add i32 %iv, 1
488  br i1 %c, label %loop.header, label %exit
489
490exit:
491  ret i32 10
492}
493
494; Make sure the duplicated instructions are moved to a preheader that always
495; executes when the loop body also executes. Do not check the unswitched code,
496; because it is already checked in the @partial_unswitch_true_successor test
497; case.
498define i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) {
499; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
500; CHECK-NEXT:  entry:
501; CHECK-NEXT:    [[EC:%.*]] = icmp ne i32* [[PTR:%.*]], null
502; CHECK-NEXT:    br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
503; CHECK:       loop.ph:
504; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
505; CHECK:       loop.header:
506; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
507; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[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:    br label [[LOOP_LATCH]]
512; CHECK:       clobber:
513; CHECK-NEXT:    call void @clobber()
514; CHECK-NEXT:    br label [[LOOP_LATCH]]
515; CHECK:       loop.latch:
516; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
517; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
518; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]]
519; CHECK:       exit.loopexit:
520; CHECK-NEXT:    br label [[EXIT]]
521; CHECK:       exit:
522; CHECK-NEXT:    ret i32 10
523;
524
525entry:
526  %ec = icmp ne i32* %ptr, null
527  br i1 %ec, label %loop.ph, label %exit
528
529loop.ph:
530  br label %loop.header
531
532loop.header:
533  %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
534  %lv = load i32, i32* %ptr
535  %sc = icmp eq i32 %lv, 100
536  br i1 %sc, label %noclobber, label %clobber
537
538noclobber:
539  br label %loop.latch
540
541clobber:
542  call void @clobber()
543  br label %loop.latch
544
545loop.latch:
546  %c = icmp ult i32 %iv, %N
547  %iv.next = add i32 %iv, 1
548  br i1 %c, label %loop.header, label %exit
549
550exit:
551  ret i32 10
552}
553
554; Make sure the duplicated instructions are hoisted just before the branch of
555; the preheader. Do not check the unswitched code, because it is already checked
556; in the @partial_unswitch_true_successor test case
557define i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) {
558; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
559; CHECK-NEXT:  entry:
560; CHECK-NEXT:    call void @clobber()
561; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
562; CHECK:       loop.header:
563; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
564; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
565; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
566; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
567; CHECK:       noclobber:
568; CHECK-NEXT:    br label [[LOOP_LATCH]]
569; CHECK:       clobber:
570; CHECK-NEXT:    call void @clobber()
571; CHECK-NEXT:    br label [[LOOP_LATCH]]
572; CHECK:       loop.latch:
573; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
574; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
575; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
576; CHECK:       exit:
577; CHECK-NEXT:    ret i32 10
578;
579entry:
580  call void @clobber()
581  br label %loop.header
582
583loop.header:
584  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
585  %lv = load i32, i32* %ptr
586  %sc = icmp eq i32 %lv, 100
587  br i1 %sc, label %noclobber, label %clobber
588
589noclobber:
590  br label %loop.latch
591
592clobber:
593  call void @clobber()
594  br label %loop.latch
595
596loop.latch:
597  %c = icmp ult i32 %iv, %N
598  %iv.next = add i32 %iv, 1
599  br i1 %c, label %loop.header, label %exit
600
601exit:
602  ret i32 10
603}
604
605; Make sure invariant instructions in the loop are also hoisted to the preheader.
606; Do not check the unswitched code, because it is already checked in the
607; @partial_unswitch_true_successor test case
608define i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) {
609; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
610; CHECK-NEXT:  entry:
611; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
612; CHECK:       loop.header:
613; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
614; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 1
615; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[GEP]], align 4
616; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
617; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
618; CHECK:       noclobber:
619; CHECK-NEXT:    br label [[LOOP_LATCH]]
620; CHECK:       clobber:
621; CHECK-NEXT:    call void @clobber()
622; CHECK-NEXT:    br label [[LOOP_LATCH]]
623; CHECK:       loop.latch:
624; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
625; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
626; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
627; CHECK:       exit:
628; CHECK-NEXT:    ret i32 10
629;
630entry:
631  br label %loop.header
632
633loop.header:
634  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
635  %gep = getelementptr i32, i32* %ptr, i64 1
636  %lv = load i32, i32* %gep
637  %sc = icmp eq i32 %lv, 100
638  br i1 %sc, label %noclobber, label %clobber
639
640noclobber:
641  br label %loop.latch
642
643clobber:
644  call void @clobber()
645  br label %loop.latch
646
647loop.latch:
648  %c = icmp ult i32 %iv, %N
649  %iv.next = add i32 %iv, 1
650  br i1 %c, label %loop.header, label %exit
651
652exit:
653  ret i32 10
654}
655
656; Do not unswitch if the condition depends on an atomic load. Duplicating such
657; loads is not safe.
658define i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) {
659; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered(
660; CHECK-NEXT:  entry:
661; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
662; CHECK:       loop.header:
663; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
664; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] unordered, align 4
665; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
666; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
667; CHECK:       noclobber:
668; CHECK-NEXT:    br label [[LOOP_LATCH]]
669; CHECK:       clobber:
670; CHECK-NEXT:    call void @clobber()
671; CHECK-NEXT:    br label [[LOOP_LATCH]]
672; CHECK:       loop.latch:
673; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
674; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
675; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
676; CHECK:       exit:
677; CHECK-NEXT:    ret i32 10
678;
679entry:
680  br label %loop.header
681
682loop.header:
683  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
684  %lv = load atomic i32, i32* %ptr unordered, align 4
685  %sc = icmp eq i32 %lv, 100
686  br i1 %sc, label %noclobber, label %clobber
687
688noclobber:
689  br label %loop.latch
690
691clobber:
692  call void @clobber()
693  br label %loop.latch
694
695loop.latch:
696  %c = icmp ult i32 %iv, %N
697  %iv.next = add i32 %iv, 1
698  br i1 %c, label %loop.header, label %exit
699
700exit:
701  ret i32 10
702}
703
704; Do not unswitch if the condition depends on an atomic load. Duplicating such
705; loads is not safe.
706define i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) {
707; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic(
708; CHECK-NEXT:  entry:
709; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
710; CHECK:       loop.header:
711; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
712; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] monotonic, align 4
713; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
714; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
715; CHECK:       noclobber:
716; CHECK-NEXT:    br label [[LOOP_LATCH]]
717; CHECK:       clobber:
718; CHECK-NEXT:    call void @clobber()
719; CHECK-NEXT:    br label [[LOOP_LATCH]]
720; CHECK:       loop.latch:
721; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
722; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
723; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
724; CHECK:       exit:
725; CHECK-NEXT:    ret i32 10
726;
727entry:
728  br label %loop.header
729
730loop.header:
731  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
732  %lv = load atomic i32, i32* %ptr monotonic, align 4
733  %sc = icmp eq i32 %lv, 100
734  br i1 %sc, label %noclobber, label %clobber
735
736noclobber:
737  br label %loop.latch
738
739clobber:
740  call void @clobber()
741  br label %loop.latch
742
743loop.latch:
744  %c = icmp ult i32 %iv, %N
745  %iv.next = add i32 %iv, 1
746  br i1 %c, label %loop.header, label %exit
747
748exit:
749  ret i32 10
750}
751
752
753declare i32 @get_value()
754
755; Do not unswitch if the condition depends on a call, that may clobber memory.
756; Duplicating such a call is not safe.
757define i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) {
758; CHECK-LABEL: @no_partial_unswitch_cond_call(
759; CHECK-NEXT:  entry:
760; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
761; CHECK:       loop.header:
762; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
763; CHECK-NEXT:    [[LV:%.*]] = call i32 @get_value()
764; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
765; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
766; CHECK:       noclobber:
767; CHECK-NEXT:    br label [[LOOP_LATCH]]
768; CHECK:       clobber:
769; CHECK-NEXT:    call void @clobber()
770; CHECK-NEXT:    br label [[LOOP_LATCH]]
771; CHECK:       loop.latch:
772; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
773; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
774; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
775; CHECK:       exit:
776; CHECK-NEXT:    ret i32 10
777;
778entry:
779  br label %loop.header
780
781loop.header:
782  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
783  %lv = call i32 @get_value()
784  %sc = icmp eq i32 %lv, 100
785  br i1 %sc, label %noclobber, label %clobber
786
787noclobber:
788  br label %loop.latch
789
790clobber:
791  call void @clobber()
792  br label %loop.latch
793
794loop.latch:
795  %c = icmp ult i32 %iv, %N
796  %iv.next = add i32 %iv, 1
797  br i1 %c, label %loop.header, label %exit
798
799exit:
800  ret i32 10
801}
802
803define i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) {
804; CHECK-LABEL: @no_partial_unswitch_true_successor_exit(
805; CHECK-NEXT:  entry:
806; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
807; CHECK:       loop.header:
808; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
809; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
810; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
811; CHECK-NEXT:    br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]]
812; CHECK:       clobber:
813; CHECK-NEXT:    call void @clobber()
814; CHECK-NEXT:    br label [[LOOP_LATCH]]
815; CHECK:       loop.latch:
816; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
817; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
818; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]]
819; CHECK:       exit:
820; CHECK-NEXT:    ret i32 10
821;
822entry:
823  br label %loop.header
824
825loop.header:
826  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
827  %lv = load i32, i32* %ptr
828  %sc = icmp eq i32 %lv, 100
829  br i1 %sc, label %exit, label %clobber
830
831clobber:
832  call void @clobber()
833  br label %loop.latch
834
835loop.latch:
836  %c = icmp ult i32 %iv, %N
837  %iv.next = add i32 %iv, 1
838  br i1 %c, label %loop.header, label %exit
839
840exit:
841  ret i32 10
842}
843
844define i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) {
845; CHECK-LABEL: @no_partial_unswitch_true_same_successor(
846; CHECK-NEXT:  entry:
847; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
848; CHECK:       loop.header:
849; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
850; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
851; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
852; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]]
853; CHECK:       noclobber:
854; CHECK-NEXT:    br label [[LOOP_LATCH]]
855; CHECK:       loop.latch:
856; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
857; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
858; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
859; CHECK:       exit:
860; CHECK-NEXT:    ret i32 10
861;
862entry:
863  br label %loop.header
864
865loop.header:
866  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
867  %lv = load i32, i32* %ptr
868  %sc = icmp eq i32 %lv, 100
869  br i1 %sc, label %noclobber, label %noclobber
870
871noclobber:
872  br label %loop.latch
873
874loop.latch:
875  %c = icmp ult i32 %iv, %N
876  %iv.next = add i32 %iv, 1
877  br i1 %c, label %loop.header, label %exit
878
879exit:
880  ret i32 10
881}
882
883define i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) {
884; CHECK-LABEL: @partial_unswitch_true_to_latch(
885; CHECK-NEXT:  entry:
886; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
887; CHECK:       loop.header:
888; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
889; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
890; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
891; CHECK-NEXT:    br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]]
892; CHECK:       clobber:
893; CHECK-NEXT:    call void @clobber()
894; CHECK-NEXT:    br label [[LOOP_LATCH]]
895; CHECK:       loop.latch:
896; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
897; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
898; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
899; CHECK:       exit:
900; CHECK-NEXT:    ret i32 10
901;
902entry:
903  br label %loop.header
904
905loop.header:
906  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
907  %lv = load i32, i32* %ptr
908  %sc = icmp eq i32 %lv, 100
909  br i1 %sc, label %loop.latch, label %clobber
910
911clobber:
912  call void @clobber()
913  br label %loop.latch
914
915loop.latch:
916  %c = icmp ult i32 %iv, %N
917  %iv.next = add i32 %iv, 1
918  br i1 %c, label %loop.header, label %exit
919
920exit:
921  ret i32 10
922}
923