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
4 declare void @clobber()
6 define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) {
7 ; CHECK-LABEL: @partial_unswitch_true_successor(
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:%.*]]
26 ; CHECK-NEXT: br label [[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:%.*]]
33 ; CHECK-NEXT: br label [[LOOP_LATCH]]
35 ; CHECK-NEXT: call void @clobber()
36 ; CHECK-NEXT: br label [[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]+]]
42 ; CHECK-NEXT: br label [[EXIT]]
44 ; CHECK-NEXT: ret i32 10
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
63 %c = icmp ult i32 %iv, %N
64 %iv.next = add i32 %iv, 1
65 br i1 %c, label %loop.header, label %exit
71 define i32 @partial_unswitch_false_successor(ptr %ptr, i32 %N) {
72 ; CHECK-LABEL: @partial_unswitch_false_successor(
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:%.*]]
91 ; CHECK-NEXT: br label [[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:%.*]]
98 ; CHECK-NEXT: call void @clobber()
99 ; CHECK-NEXT: br label [[LOOP_LATCH]]
101 ; CHECK-NEXT: br label [[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]+]]
107 ; CHECK-NEXT: br label [[EXIT]]
109 ; CHECK-NEXT: ret i32 10
112 br label %loop.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
128 %c = icmp ult i32 %iv, %N
129 %iv.next = add i32 %iv, 1
130 br i1 %c, label %loop.header, label %exit
136 define i32 @partial_unswtich_gep_load_icmp(ptr %ptr, i32 %N) {
137 ; CHECK-LABEL: @partial_unswtich_gep_load_icmp(
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:%.*]]
167 ; CHECK-NEXT: br label [[LOOP_LATCH]]
169 ; CHECK-NEXT: call void @clobber()
170 ; CHECK-NEXT: br label [[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]+]]
176 ; CHECK-NEXT: br label [[EXIT]]
178 ; CHECK-NEXT: ret i32 10
181 br label %loop.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
199 %c = icmp ult i32 %iv, %N
200 %iv.next = add i32 %iv, 1
201 br i1 %c, label %loop.header, label %exit
207 define i32 @partial_unswitch_reduction_phi(ptr %ptr, i32 %N) {
208 ; CHECK-LABEL: @partial_unswitch_reduction_phi(
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:%.*]]
239 ; CHECK-NEXT: call void @clobber()
240 ; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5
241 ; CHECK-NEXT: br label [[LOOP_LATCH]]
243 ; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10
244 ; CHECK-NEXT: br label [[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]+]]
251 ; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]
252 ; CHECK-NEXT: br label [[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]]
258 br label %loop.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
269 %add.5 = add i32 %red, 5
273 %add.10 = add i32 %red, 10
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
283 %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
284 ret i32 %red.next.lcssa
287 ; Partial unswitching is possible, because the store in %noclobber does not
288 ; alias the load of the condition.
289 define i32 @partial_unswitch_true_successor_noclobber(ptr noalias %ptr.1, ptr noalias %ptr.2, i32 %N) {
290 ; CHECK-LABEL: @partial_unswitch_true_successor_noclobber(
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:%.*]]
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]]
323 ; CHECK-NEXT: call void @clobber()
324 ; CHECK-NEXT: br label [[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]+]]
330 ; CHECK-NEXT: br label [[EXIT]]
332 ; CHECK-NEXT: ret i32 10
335 br label %loop.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
344 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv
345 store i32 %lv, ptr %gep.1
353 %c = icmp ult i32 %iv, %N
354 %iv.next = add i32 %iv, 1
355 br i1 %c, label %loop.header, label %exit
361 define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
362 ; CHECK-LABEL: @no_partial_unswitch_phi_cond(
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:%.*]]
370 ; CHECK-NEXT: call void @clobber()
371 ; CHECK-NEXT: br label [[LOOP_LATCH]]
373 ; CHECK-NEXT: br label [[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:%.*]]
379 ; CHECK-NEXT: ret void
382 br label %loop.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
397 %c = icmp ult i32 %iv, %N
398 %iv.next = add i32 %iv, 1
399 br i1 %c, label %loop.header, label %exit
405 define void @no_partial_unswitch_clobber_latch(ptr %ptr, i32 %N) {
406 ; CHECK-LABEL: @no_partial_unswitch_clobber_latch(
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:%.*]]
415 ; CHECK-NEXT: br label [[LOOP_LATCH]]
417 ; CHECK-NEXT: call void @clobber()
418 ; CHECK-NEXT: br label [[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:%.*]]
425 ; CHECK-NEXT: ret void
428 br label %loop.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
445 %c = icmp ult i32 %iv, %N
446 %iv.next = add i32 %iv, 1
447 br i1 %c, label %loop.header, label %exit
453 define void @no_partial_unswitch_clobber_header(ptr %ptr, i32 %N) {
454 ; CHECK-LABEL: @no_partial_unswitch_clobber_header(
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:%.*]]
464 ; CHECK-NEXT: br label [[LOOP_LATCH]]
466 ; CHECK-NEXT: call void @clobber()
467 ; CHECK-NEXT: br label [[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:%.*]]
473 ; CHECK-NEXT: ret void
476 br label %loop.header
479 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
481 %lv = load i32, ptr %ptr
482 %sc = icmp eq i32 %lv, 100
483 br i1 %sc, label %noclobber, label %clobber
493 %c = icmp ult i32 %iv, %N
494 %iv.next = add i32 %iv, 1
495 br i1 %c, label %loop.header, label %exit
501 define void @no_partial_unswitch_clobber_both(ptr %ptr, i32 %N) {
502 ; CHECK-LABEL: @no_partial_unswitch_clobber_both(
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:%.*]]
511 ; CHECK-NEXT: call void @clobber()
512 ; CHECK-NEXT: br label [[LOOP_LATCH]]
514 ; CHECK-NEXT: call void @clobber()
515 ; CHECK-NEXT: br label [[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:%.*]]
521 ; CHECK-NEXT: ret void
524 br label %loop.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
541 %c = icmp ult i32 %iv, %N
542 %iv.next = add i32 %iv, 1
543 br i1 %c, label %loop.header, label %exit
549 define i32 @no_partial_unswitch_true_successor_storeclobber(ptr %ptr.1, ptr %ptr.2, i32 %N) {
550 ; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber(
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:%.*]]
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]]
563 ; CHECK-NEXT: call void @clobber()
564 ; CHECK-NEXT: br label [[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:%.*]]
570 ; CHECK-NEXT: ret i32 10
573 br label %loop.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
582 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv
583 store i32 %lv, ptr %gep.1
591 %c = icmp ult i32 %iv, %N
592 %iv.next = add i32 %iv, 1
593 br i1 %c, label %loop.header, label %exit
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
603 define i32 @partial_unswitch_true_successor_preheader_insertion(ptr %ptr, i32 %N) {
604 ; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
606 ; CHECK-NEXT: [[EC:%.*]] = icmp ne ptr [[PTR:%.*]], null
607 ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
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:%.*]]
633 ; CHECK-NEXT: br label [[LOOP_LATCH]]
635 ; CHECK-NEXT: call void @clobber()
636 ; CHECK-NEXT: br label [[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]]
646 ; CHECK-NEXT: ret i32 10
650 %ec = icmp ne ptr %ptr, null
651 br i1 %ec, label %loop.ph, label %exit
654 br label %loop.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
670 %c = icmp ult i32 %iv, %N
671 %iv.next = add i32 %iv, 1
672 br i1 %c, label %loop.header, label %exit
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
681 define i32 @partial_unswitch_true_successor_insert_point(ptr %ptr, i32 %N) {
682 ; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
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:%.*]]
709 ; CHECK-NEXT: br label [[LOOP_LATCH]]
711 ; CHECK-NEXT: call void @clobber()
712 ; CHECK-NEXT: br label [[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]+]]
718 ; CHECK-NEXT: br label [[EXIT]]
720 ; CHECK-NEXT: ret i32 10
724 br label %loop.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
740 %c = icmp ult i32 %iv, %N
741 %iv.next = add i32 %iv, 1
742 br i1 %c, label %loop.header, label %exit
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
751 define i32 @partial_unswitch_true_successor_hoist_invariant(ptr %ptr, i32 %N) {
752 ; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
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:%.*]]
780 ; CHECK-NEXT: br label [[LOOP_LATCH]]
782 ; CHECK-NEXT: call void @clobber()
783 ; CHECK-NEXT: br label [[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]+]]
789 ; CHECK-NEXT: br label [[EXIT]]
791 ; CHECK-NEXT: ret i32 10
794 br label %loop.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
811 %c = icmp ult i32 %iv, %N
812 %iv.next = add i32 %iv, 1
813 br i1 %c, label %loop.header, label %exit
819 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
821 define i32 @no_partial_unswitch_atomic_load_unordered(ptr %ptr, i32 %N) {
822 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered(
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:%.*]]
831 ; CHECK-NEXT: br label [[LOOP_LATCH]]
833 ; CHECK-NEXT: call void @clobber()
834 ; CHECK-NEXT: br label [[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:%.*]]
840 ; CHECK-NEXT: ret i32 10
843 br label %loop.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
859 %c = icmp ult i32 %iv, %N
860 %iv.next = add i32 %iv, 1
861 br i1 %c, label %loop.header, label %exit
867 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
869 define i32 @no_partial_unswitch_atomic_load_monotonic(ptr %ptr, i32 %N) {
870 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic(
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:%.*]]
879 ; CHECK-NEXT: br label [[LOOP_LATCH]]
881 ; CHECK-NEXT: call void @clobber()
882 ; CHECK-NEXT: br label [[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:%.*]]
888 ; CHECK-NEXT: ret i32 10
891 br label %loop.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
907 %c = icmp ult i32 %iv, %N
908 %iv.next = add i32 %iv, 1
909 br i1 %c, label %loop.header, label %exit
916 declare i32 @get_value()
918 ; Do not unswitch if the condition depends on a call, that may clobber memory.
919 ; Duplicating such a call is not safe.
920 define i32 @no_partial_unswitch_cond_call(ptr %ptr, i32 %N) {
921 ; CHECK-LABEL: @no_partial_unswitch_cond_call(
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:%.*]]
930 ; CHECK-NEXT: br label [[LOOP_LATCH]]
932 ; CHECK-NEXT: call void @clobber()
933 ; CHECK-NEXT: br label [[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:%.*]]
939 ; CHECK-NEXT: ret i32 10
942 br label %loop.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
958 %c = icmp ult i32 %iv, %N
959 %iv.next = add i32 %iv, 1
960 br i1 %c, label %loop.header, label %exit
966 define i32 @no_partial_unswitch_true_successor_exit(ptr %ptr, i32 %N) {
967 ; CHECK-LABEL: @no_partial_unswitch_true_successor_exit(
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:%.*]]
976 ; CHECK-NEXT: call void @clobber()
977 ; CHECK-NEXT: br label [[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]]
983 ; CHECK-NEXT: ret i32 10
986 br label %loop.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
999 %c = icmp ult i32 %iv, %N
1000 %iv.next = add i32 %iv, 1
1001 br i1 %c, label %loop.header, label %exit
1007 define 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]]
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:%.*]]
1023 ; CHECK-NEXT: ret i32 10
1026 br label %loop.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
1035 br label %loop.latch
1038 %c = icmp ult i32 %iv, %N
1039 %iv.next = add i32 %iv, 1
1040 br i1 %c, label %loop.header, label %exit
1046 define 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:%.*]]
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]]
1080 ; CHECK-NEXT: ret i32 10
1083 br label %loop.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
1092 call void @clobber()
1093 br label %loop.latch
1096 %c = icmp ult i32 %iv, %N
1097 %iv.next = add i32 %iv, 1
1098 br i1 %c, label %loop.header, label %exit
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
1107 define 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:%.*]]
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:%.*]]
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:%.*]]
1138 ; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[PTR]], align 16
1139 ; CHECK-NEXT: br label [[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]]
1146 ; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RET_VAL]], [[EXIT_SPLIT]] ], [ [[RET_VAL_US]], [[EXIT_SPLIT_US]] ]
1147 ; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
1150 %exit.cond = icmp ne i32 %0, 0
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
1159 store i32 %1, ptr %ptr, align 16
1163 br i1 %exit.cond, label %loop, label %exit
1166 %ret.val = phi i32 [ 1, %exiting ]
1170 ; The path with noclobber block is only duplicated so we need to calculate only
1171 ; the cost of the path with noclobber.
1172 define 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:%.*]]
1199 ; CHECK-NEXT: br label [[LOOP_LATCH]]
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]]
1256 ; CHECK-NEXT: ret i32 10
1259 br label %loop.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
1268 br label %loop.latch
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
1321 %c = icmp ult i32 %iv, %N
1322 %iv.next = add i32 %iv, 1
1323 br i1 %c, label %loop.header, label %exit
1329 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[UNSWITCH_PARTIAL_DISABLE:![0-9]+]]}
1330 ; CHECK: [[UNSWITCH_PARTIAL_DISABLE]] = !{!"llvm.loop.unswitch.partial.disable"}
1331 ; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[UNSWITCH_PARTIAL_DISABLE]]}
1332 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[UNSWITCH_PARTIAL_DISABLE]]}
1333 ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[UNSWITCH_PARTIAL_DISABLE]]}
1334 ; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[UNSWITCH_PARTIAL_DISABLE]]}
1335 ; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[UNSWITCH_PARTIAL_DISABLE]]}
1336 ; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[UNSWITCH_PARTIAL_DISABLE]]}
1337 ; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[UNSWITCH_PARTIAL_DISABLE]]}
1338 ; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[UNSWITCH_PARTIAL_DISABLE]]}
1339 ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[UNSWITCH_PARTIAL_DISABLE]]}
1340 ; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[UNSWITCH_PARTIAL_DISABLE]]}