1 ; RUN: opt -loop-unswitch -verify-dom-info -verify-memoryssa -S -enable-new-pm=0 %s | FileCheck %s
3 declare void @clobber()
5 define i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) {
6 ; CHECK-LABEL: @partial_unswitch_true_successor
8 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
9 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
10 ; CHECK-NEXT: br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
12 ; CHECK: [[FALSE_CRIT]]:
13 ; CHECK-NEXT: br label %[[FALSE_PH:[a-z.]+]]
15 ; CHECK: [[SPLIT_TRUE_PH]]:
16 ; CHECK-NEXT: br label %[[TRUE_HEADER:[a-z.]+]]
18 ; CHECK: [[TRUE_HEADER]]:
20 ; CHECK-NEXT: [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
21 ; CHECK-NEXT: [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
22 ; CHECK-NEXT: br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
24 ; CHECK: [[TRUE_CLOBBER]]:
26 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
28 ; CHECK: [[TRUE_NOCLOBBER]]:
29 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
31 ; CHECK: [[TRUE_LATCH]]:
34 ; CHECK-NEXT: br {{.*}} label %[[TRUE_HEADER]]
37 ; CHECK: [[FALSE_PH]]:
38 ; CHECK-NEXT: br label %[[FALSE_HEADER:[a-z.]+]]
40 ; CHECK: [[FALSE_HEADER]]:
42 ; CHECK-NEXT: [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
43 ; CHECK-NEXT: [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
44 ; CHECK-NEXT: br i1 [[FALSE_C]], label %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
46 ; CHECK: [[FALSE_NOCLOBBER]]:
47 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
49 ; CHECK: [[FALSE_CLOBBER]]:
51 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
53 ; CHECK: [[FALSE_LATCH]]:
56 ; CHECK-NEXT: br {{.*}} label %[[FALSE_HEADER]]
62 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
63 %lv = load i32, i32* %ptr
64 %sc = icmp eq i32 %lv, 100
65 br i1 %sc, label %noclobber, label %clobber
75 %c = icmp ult i32 %iv, %N
76 %iv.next = add i32 %iv, 1
77 br i1 %c, label %loop.header, label %exit
83 define i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) {
84 ; CHECK-LABEL: @partial_unswitch_false_successor
86 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
87 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
88 ; CHECK-NEXT: br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
90 ; CHECK: [[FALSE_CRIT]]:
91 ; CHECK-NEXT: br label %[[FALSE_PH:[a-z.]+]]
93 ; CHECK: [[SPLIT_TRUE_PH]]:
94 ; CHECK-NEXT: br label %[[TRUE_HEADER:[a-z.]+]]
96 ; CHECK: [[TRUE_HEADER]]:
98 ; CHECK-NEXT: [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
99 ; CHECK-NEXT: [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
100 ; CHECK-NEXT: br i1 [[TRUE_C]], label %[[TRUE_CLOBBER:.+]], label %[[TRUE_NOCLOBBER:[a-z0-9._]+]]
102 ; CHECK: [[TRUE_NOCLOBBER]]:
103 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
105 ; CHECK: [[TRUE_CLOBBER]]:
107 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
109 ; CHECK: [[TRUE_LATCH]]:
112 ; CHECK-NEXT: br {{.*}} label %[[TRUE_HEADER]]
115 ; CHECK: [[FALSE_PH]]:
116 ; CHECK-NEXT: br label %[[FALSE_HEADER:[a-z.]+]]
118 ; CHECK: [[FALSE_HEADER]]:
119 ; CHECK-NEXT: phi i32
120 ; CHECK-NEXT: [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
121 ; CHECK-NEXT: [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
122 ; CHECK-NEXT: br i1 false, label %[[FALSE_CLOBBER:.+]], label %[[FALSE_NOCLOBBER:[a-z0-9._]+]]
124 ; CHECK: [[FALSE_CLOBBER]]:
126 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
128 ; CHECK: [[FALSE_NOCLOBBER]]:
129 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
131 ; CHECK: [[FALSE_LATCH]]:
134 ; CHECK-NEXT: br {{.*}} label %[[FALSE_HEADER]]
137 br label %loop.header
140 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
141 %lv = load i32, i32* %ptr
142 %sc = icmp eq i32 %lv, 100
143 br i1 %sc, label %clobber, label %noclobber
153 %c = icmp ult i32 %iv, %N
154 %iv.next = add i32 %iv, 1
155 br i1 %c, label %loop.header, label %exit
161 define i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) {
162 ; CHECK-LABEL: @partial_unswtich_gep_load_icmp
163 ; CHECK-LABEL: entry:
164 ; CHECK-NEXT: [[GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
165 ; CHECK-NEXT: [[LV0:%[a-z.0-9]+]] = load i32*, i32** [[GEP]]
166 ; CHECK-NEXT: [[LV1:%[a-z.0-9]+]] = load i32, i32* [[LV0]]
167 ; CHECK-NEXT: [[C:%[a-z.0-9]+]] = icmp eq i32 [[LV1]], 100
168 ; CHECK-NEXT: br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
170 ; CHECK: [[FALSE_CRIT]]:
171 ; CHECK-NEXT: br label %[[FALSE_PH:[a-z.]+]]
173 ; CHECK: [[SPLIT_TRUE_PH]]:
174 ; CHECK-NEXT: br label %[[TRUE_HEADER:[a-z.]+]]
176 ; CHECK: [[TRUE_HEADER]]:
177 ; CHECK-NEXT: phi i32
178 ; CHECK-NEXT: [[TRUE_GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
179 ; CHECK-NEXT: [[TRUE_LV0:%[a-z.0-9]+]] = load i32*, i32** [[TRUE_GEP]]
180 ; CHECK-NEXT: [[TRUE_LV1:%[a-z.0-9]+]] = load i32, i32* [[TRUE_LV0]]
181 ; CHECK-NEXT: [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV1]], 100
182 ; CHECK-NEXT: br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
184 ; CHECK: [[TRUE_CLOBBER]]:
186 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
188 ; CHECK: [[TRUE_NOCLOBBER]]:
189 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
191 ; CHECK: [[TRUE_LATCH]]:
194 ; CHECK-NEXT: br {{.*}} label %[[TRUE_HEADER]]
196 ; CHECK: [[FALSE_PH]]:
197 ; CHECK-NEXT: br label %[[FALSE_HEADER:[a-z.]+]]
199 ; CHECK: [[FALSE_HEADER]]:
200 ; CHECK-NEXT: phi i32
201 ; CHECK-NEXT: [[FALSE_GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
202 ; CHECK-NEXT: [[FALSE_LV0:%[a-z.0-9]+]] = load i32*, i32** [[FALSE_GEP]]
203 ; CHECK-NEXT: [[FALSE_LV1:%[a-z.0-9]+]] = load i32, i32* [[FALSE_LV0]]
204 ; CHECK-NEXT: [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV1]], 100
205 ; CHECK-NEXT: br i1 [[FALSE_C]], label %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
207 ; CHECK: [[FALSE_NOCLOBBER]]:
208 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
210 ; CHECK: [[FALSE_CLOBBER]]:
212 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
215 ; CHECK: [[FALSE_LATCH]]:
218 ; CHECK-NEXT: br {{.*}} label %[[FALSE_HEADER]]
221 br label %loop.header
224 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
225 %gep = getelementptr i32*, i32** %ptr, i32 1
226 %lv.1 = load i32*, i32** %gep
227 %lv = load i32, i32* %lv.1
228 %sc = icmp eq i32 %lv, 100
229 br i1 %sc, label %noclobber, label %clobber
239 %c = icmp ult i32 %iv, %N
240 %iv.next = add i32 %iv, 1
241 br i1 %c, label %loop.header, label %exit
247 define i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) {
248 ; CHECK-LABEL: @partial_unswitch_reduction_phi
249 ; CHECK-LABEL: entry:
250 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
251 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
252 ; CHECK-NEXT: br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
254 ; CHECK: [[FALSE_CRIT]]:
255 ; CHECK-NEXT: br label %[[FALSE_PH:[a-z.]+]]
257 ; CHECK: [[SPLIT_TRUE_PH]]:
258 ; CHECK-NEXT: br label %[[TRUE_HEADER:[a-z.]+]]
260 ; CHECK: [[TRUE_HEADER]]:
261 ; CHECK-NEXT: phi i32
262 ; CHECK-NEXT: [[TRUE_RED:%[a-z.0-9]+]] = phi i32 [ 20, %[[SPLIT_TRUE_PH]] ], [ [[TRUE_RED_NEXT:%[a-z.0-9]+]], %[[TRUE_LATCH:[a-z.0-9]+]]
263 ; CHECK-NEXT: [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
264 ; CHECK-NEXT: [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
265 ; CHECK-NEXT: br i1 [[TRUE_C]], label %[[TRUE_CLOBBER:.+]], label %[[TRUE_NOCLOBBER:[a-z0-9._]+]]
267 ; CHECK: [[TRUE_NOCLOBBER]]:
268 ; CHECK-NEXT: [[TRUE_ADD10:%.+]] = add i32 [[TRUE_RED]], 10
269 ; CHECK-NEXT: br label %[[TRUE_LATCH]]
271 ; CHECK: [[TRUE_CLOBBER]]:
273 ; CHECK-NEXT: [[TRUE_ADD5:%.+]] = add i32 [[TRUE_RED]], 5
274 ; CHECK-NEXT: br label %[[TRUE_LATCH]]
276 ; CHECK: [[TRUE_LATCH]]:
277 ; CHECK-NEXT: [[TRUE_RED_NEXT]] = phi i32 [ [[TRUE_ADD5]], %[[TRUE_CLOBBER]] ], [ [[TRUE_ADD10]], %[[TRUE_NOCLOBBER]] ]
280 ; CHECK-NEXT: br {{.*}} label %[[TRUE_HEADER]]
283 ; CHECK: [[FALSE_PH]]:
284 ; CHECK-NEXT: br label %[[FALSE_HEADER:[a-z.]+]]
286 ; CHECK: [[FALSE_HEADER]]:
287 ; CHECK-NEXT: phi i32
288 ; CHECK-NEXT: [[FALSE_RED:%[a-z.0-9]+]] = phi i32 [ 20, %[[FALSE_PH]] ], [ [[FALSE_RED_NEXT:%[a-z.0-9]+]], %[[FALSE_LATCH:[a-z.0-9]+]]
289 ; CHECK-NEXT: [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
290 ; CHECK-NEXT: [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
291 ; CHECK-NEXT: br i1 false, label %[[FALSE_CLOBBER:.+]], label %[[FALSE_NOCLOBBER:[a-z0-9._]+]]
293 ; CHECK: [[FALSE_CLOBBER]]:
295 ; CHECK-NEXT: [[FALSE_ADD5:%.+]] = add i32 [[FALSE_RED]], 5
296 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
298 ; CHECK: [[FALSE_NOCLOBBER]]:
299 ; CHECK-NEXT: [[FALSE_ADD10:%.+]] = add i32 [[FALSE_RED]], 10
300 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
302 ; CHECK: [[FALSE_LATCH]]:
303 ; CHECK-NEXT: [[FALSE_RED_NEXT]] = phi i32 [ [[FALSE_ADD5]], %[[FALSE_CLOBBER]] ], [ [[FALSE_ADD10]], %[[FALSE_NOCLOBBER]] ]
306 ; CHECK-NEXT: br {{.*}} label %[[FALSE_HEADER]]
309 br label %loop.header
312 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
313 %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]
314 %lv = load i32, i32* %ptr
315 %sc = icmp eq i32 %lv, 100
316 br i1 %sc, label %clobber, label %noclobber
320 %add.5 = add i32 %red, 5
324 %add.10 = add i32 %red, 10
328 %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]
329 %c = icmp ult i32 %iv, %N
330 %iv.next = add i32 %iv, 1
331 br i1 %c, label %loop.header, label %exit
334 %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
335 ret i32 %red.next.lcssa
338 ; Partial unswitching is possible, because the store in %noclobber does not
339 ; alias the load of the condition.
340 define i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) {
341 ; CHECK-LABEL: @partial_unswitch_true_successor
343 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr.1, align 4
344 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
345 ; CHECK-NEXT: br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
347 ; CHECK: [[FALSE_CRIT]]:
348 ; CHECK-NEXT: br label %[[FALSE_PH:[a-z.]+]]
350 ; CHECK: [[SPLIT_TRUE_PH]]:
351 ; CHECK-NEXT: br label %[[TRUE_HEADER:[a-z.]+]]
353 ; CHECK: [[TRUE_HEADER]]:
354 ; CHECK-NEXT: phi i32
355 ; CHECK-NEXT: [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr.1, align 4
356 ; CHECK-NEXT: [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
357 ; CHECK-NEXT: br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
359 ; CHECK: [[TRUE_CLOBBER]]:
361 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
363 ; CHECK: [[TRUE_NOCLOBBER]]:
364 ; CHECK-NEXT: [[TRUE_GEP:%[a-z0-9._]+]] = getelementptr i32, i32* %ptr.2
365 ; CHECK-NEXT: store i32 [[TRUE_LV]], i32* [[TRUE_GEP]], align 4
366 ; CHECK-NEXT: br label %[[TRUE_LATCH:[a-z0-9._]+]]
368 ; CHECK: [[TRUE_LATCH]]:
371 ; CHECK-NEXT: br {{.*}} label %[[TRUE_HEADER]]
374 ; CHECK: [[FALSE_PH]]:
375 ; CHECK-NEXT: br label %[[FALSE_HEADER:[a-z.]+]]
377 ; CHECK: [[FALSE_HEADER]]:
378 ; CHECK-NEXT: phi i32
379 ; CHECK-NEXT: [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr.1, align 4
380 ; CHECK-NEXT: [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
381 ; CHECK-NEXT: br i1 [[FALSE_C]], label %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
383 ; CHECK: [[FALSE_NOCLOBBER]]:
384 ; CHECK-NEXT: [[FALSE_GEP:%[a-z0-9._]+]] = getelementptr i32, i32* %ptr.2
385 ; CHECK-NEXT: store i32 [[FALSE_LV]], i32* [[FALSE_GEP]], align 4
386 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
388 ; CHECK: [[FALSE_CLOBBER]]:
390 ; CHECK-NEXT: br label %[[FALSE_LATCH:[a-z0-9._]+]]
392 ; CHECK: [[FALSE_LATCH]]:
395 ; CHECK-NEXT: br {{.*}} label %[[FALSE_HEADER]]
398 br label %loop.header
401 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
402 %lv = load i32, i32* %ptr.1
403 %sc = icmp eq i32 %lv, 100
404 br i1 %sc, label %noclobber, label %clobber
407 %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
408 store i32 %lv, i32* %gep.1
416 %c = icmp ult i32 %iv, %N
417 %iv.next = add i32 %iv, 1
418 br i1 %c, label %loop.header, label %exit
424 define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
425 ; CHECK-LABEL: @no_partial_unswitch_phi_cond
427 ; CHECK-NEXT: br label %loop.header
430 br label %loop.header
433 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
434 %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]
435 br i1 %sc, label %clobber, label %noclobber
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_latch(i32* %ptr, i32 %N) {
454 ; CHECK-LABEL: @no_partial_unswitch_clobber_latch
456 ; CHECK-NEXT: br label %loop.header
459 br label %loop.header
462 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
463 %lv = load i32, i32* %ptr
464 %sc = icmp eq i32 %lv, 100
465 br i1 %sc, label %noclobber, label %clobber
476 %c = icmp ult i32 %iv, %N
477 %iv.next = add i32 %iv, 1
478 br i1 %c, label %loop.header, label %exit
484 define void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) {
485 ; CHECK-LABEL: @no_partial_unswitch_clobber_header
487 ; CHECK-NEXT: br label %loop.header
490 br label %loop.header
493 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
495 %lv = load i32, i32* %ptr
496 %sc = icmp eq i32 %lv, 100
497 br i1 %sc, label %noclobber, label %clobber
507 %c = icmp ult i32 %iv, %N
508 %iv.next = add i32 %iv, 1
509 br i1 %c, label %loop.header, label %exit
515 define void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) {
516 ; CHECK-LABEL: @no_partial_unswitch_clobber_both
518 ; CHECK-NEXT: br label %loop.header
521 br label %loop.header
524 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
525 %lv = load i32, i32* %ptr
526 %sc = icmp eq i32 %lv, 100
527 br i1 %sc, label %noclobber, label %clobber
538 %c = icmp ult i32 %iv, %N
539 %iv.next = add i32 %iv, 1
540 br i1 %c, label %loop.header, label %exit
546 define i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) {
547 ; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber
549 ; CHECK-NEXT: br label %loop.header
552 br label %loop.header
555 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
556 %lv = load i32, i32* %ptr.1
557 %sc = icmp eq i32 %lv, 100
558 br i1 %sc, label %noclobber, label %clobber
561 %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
562 store i32 %lv, i32* %gep.1
570 %c = icmp ult i32 %iv, %N
571 %iv.next = add i32 %iv, 1
572 br i1 %c, label %loop.header, label %exit
578 ; Make sure the duplicated instructions are moved to a preheader that always
579 ; executes when the loop body also executes. Do not check the unswitched code,
580 ; because it is already checked in the @partial_unswitch_true_successor test
582 define i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) {
583 ; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
585 ; CHECK-NEXT: [[EC:%[a-z]+]] = icmp ne i32* %ptr, null
586 ; CHECK-NEXT: br i1 [[EC]], label %[[PH:[a-z0-9.]+]], label %[[EXIT:[a-z0-9.]+]]
589 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
590 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
591 ; CHECK-NEXT: br i1 [[C]]
594 %ec = icmp ne i32* %ptr, null
595 br i1 %ec, label %loop.ph, label %exit
598 br label %loop.header
601 %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
602 %lv = load i32, i32* %ptr
603 %sc = icmp eq i32 %lv, 100
604 br i1 %sc, label %noclobber, label %clobber
614 %c = icmp ult i32 %iv, %N
615 %iv.next = add i32 %iv, 1
616 br i1 %c, label %loop.header, label %exit
622 ; Make sure the duplicated instructions are hoisted just before the branch of
623 ; the preheader. Do not check the unswitched code, because it is already checked
624 ; in the @partial_unswitch_true_successor test case
625 define i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) {
626 ; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
628 ; CHECK-NEXT: call void @clobber()
629 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
630 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
631 ; CHECK-NEXT: br i1 [[C]]
635 br label %loop.header
638 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
639 %lv = load i32, i32* %ptr
640 %sc = icmp eq i32 %lv, 100
641 br i1 %sc, label %noclobber, label %clobber
651 %c = icmp ult i32 %iv, %N
652 %iv.next = add i32 %iv, 1
653 br i1 %c, label %loop.header, label %exit
659 ; Make sure invariant instructions in the loop are also hoisted to the preheader.
660 ; Do not check the unswitched code, because it is already checked in the
661 ; @partial_unswitch_true_successor test case
662 define i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) {
663 ; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
665 ; CHECK-NEXT: [[GEP:%[0-9]+]] = getelementptr i32, i32* %ptr, i64 1
666 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* [[GEP]], align 4
667 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
668 ; CHECK-NEXT: br i1 [[C]]
671 br label %loop.header
674 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
675 %gep = getelementptr i32, i32* %ptr, i64 1
676 %lv = load i32, i32* %gep
677 %sc = icmp eq i32 %lv, 100
678 br i1 %sc, label %noclobber, label %clobber
688 %c = icmp ult i32 %iv, %N
689 %iv.next = add i32 %iv, 1
690 br i1 %c, label %loop.header, label %exit
696 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
698 define i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) {
699 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered
701 ; CHECK-NEXT: br label %loop.header
704 br label %loop.header
707 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
708 %lv = load atomic i32, i32* %ptr unordered, align 4
709 %sc = icmp eq i32 %lv, 100
710 br i1 %sc, label %noclobber, label %clobber
720 %c = icmp ult i32 %iv, %N
721 %iv.next = add i32 %iv, 1
722 br i1 %c, label %loop.header, label %exit
728 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
730 define i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) {
731 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic
733 ; CHECK-NEXT: br label %loop.header
736 br label %loop.header
739 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
740 %lv = load atomic i32, i32* %ptr monotonic, align 4
741 %sc = icmp eq i32 %lv, 100
742 br i1 %sc, label %noclobber, label %clobber
752 %c = icmp ult i32 %iv, %N
753 %iv.next = add i32 %iv, 1
754 br i1 %c, label %loop.header, label %exit
761 declare i32 @get_value()
763 ; Do not unswitch if the condition depends on a call, that may clobber memory.
764 ; Duplicating such a call is not safe.
765 define i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) {
766 ; CHECK-LABEL: @no_partial_unswitch_cond_call
768 ; CHECK-NEXT: br label %loop.header
771 br label %loop.header
774 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
775 %lv = call i32 @get_value()
776 %sc = icmp eq i32 %lv, 100
777 br i1 %sc, label %noclobber, label %clobber
787 %c = icmp ult i32 %iv, %N
788 %iv.next = add i32 %iv, 1
789 br i1 %c, label %loop.header, label %exit
795 define i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) {
796 ; CHECK-LABEL: @no_partial_unswitch_true_successor_exit
797 ; CHECK-LABEL: entry:
798 ; CHECK-NEXT: br label %loop.header
801 br label %loop.header
804 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
805 %lv = load i32, i32* %ptr
806 %sc = icmp eq i32 %lv, 100
807 br i1 %sc, label %exit, label %clobber
814 %c = icmp ult i32 %iv, %N
815 %iv.next = add i32 %iv, 1
816 br i1 %c, label %loop.header, label %exit
822 define i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) {
823 ; CHECK-LABEL: @no_partial_unswitch_true_same_successor
824 ; CHECK-LABEL: entry:
825 ; CHECK-NEXT: br label %loop.header
828 br label %loop.header
831 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
832 %lv = load i32, i32* %ptr
833 %sc = icmp eq i32 %lv, 100
834 br i1 %sc, label %noclobber, label %noclobber
840 %c = icmp ult i32 %iv, %N
841 %iv.next = add i32 %iv, 1
842 br i1 %c, label %loop.header, label %exit
848 define i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) {
849 ; CHECK-LABEL: @partial_unswitch_true_to_latch
850 ; CHECK-LABEL: entry:
851 ; CHECK-NEXT: [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
852 ; CHECK-NEXT: [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
853 ; CHECK-NEXT: br i1 [[C]],
856 br label %loop.header
859 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
860 %lv = load i32, i32* %ptr
861 %sc = icmp eq i32 %lv, 100
862 br i1 %sc, label %loop.latch, label %clobber
869 %c = icmp ult i32 %iv, %N
870 %iv.next = add i32 %iv, 1
871 br i1 %c, label %loop.header, label %exit