107142b30SJingu Kang; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*1db2551cSBjorn Pettersson; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
307142b30SJingu Kang
407142b30SJingu Kangdeclare void @clobber()
507142b30SJingu Kang
607142b30SJingu Kangdefine i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) {
707142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor(
807142b30SJingu Kang; CHECK-NEXT:  entry:
9f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
10f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
11f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
12f3a27511SJingu Kang; CHECK:       entry.split.us:
13f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
14f3a27511SJingu Kang; CHECK:       loop.header.us:
15f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
16f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
17f3a27511SJingu Kang; CHECK:       noclobber.us:
18f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
19f3a27511SJingu Kang; CHECK:       loop.latch.us:
20f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
21f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
22f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
23f3a27511SJingu Kang; CHECK:       exit.split.us:
24f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
25f3a27511SJingu Kang; CHECK:       entry.split:
2607142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
2707142b30SJingu Kang; CHECK:       loop.header:
28f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
29f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
3007142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
3107142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
3207142b30SJingu Kang; CHECK:       noclobber:
3307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
3407142b30SJingu Kang; CHECK:       clobber:
3507142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
3607142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
3707142b30SJingu Kang; CHECK:       loop.latch:
38f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
3907142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
40f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
41f3a27511SJingu Kang; CHECK:       exit.split:
42f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
4307142b30SJingu Kang; CHECK:       exit:
4407142b30SJingu Kang; CHECK-NEXT:    ret i32 10
4507142b30SJingu Kang;
4607142b30SJingu Kangentry:
4707142b30SJingu Kang  br label %loop.header
4807142b30SJingu Kang
4907142b30SJingu Kangloop.header:
5007142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
5107142b30SJingu Kang  %lv = load i32, i32* %ptr
5207142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
5307142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
5407142b30SJingu Kang
5507142b30SJingu Kangnoclobber:
5607142b30SJingu Kang  br label %loop.latch
5707142b30SJingu Kang
5807142b30SJingu Kangclobber:
5907142b30SJingu Kang  call void @clobber()
6007142b30SJingu Kang  br label %loop.latch
6107142b30SJingu Kang
6207142b30SJingu Kangloop.latch:
6307142b30SJingu Kang  %c = icmp ult i32 %iv, %N
6407142b30SJingu Kang  %iv.next = add i32 %iv, 1
6507142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
6607142b30SJingu Kang
6707142b30SJingu Kangexit:
6807142b30SJingu Kang  ret i32 10
6907142b30SJingu Kang}
7007142b30SJingu Kang
7107142b30SJingu Kangdefine i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) {
7207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_false_successor(
7307142b30SJingu Kang; CHECK-NEXT:  entry:
74f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
75f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
76f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
77f3a27511SJingu Kang; CHECK:       entry.split.us:
78f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
79f3a27511SJingu Kang; CHECK:       loop.header.us:
80f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
81f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
82f3a27511SJingu Kang; CHECK:       noclobber.us:
83f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
84f3a27511SJingu Kang; CHECK:       loop.latch.us:
85f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
86f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
87f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
88f3a27511SJingu Kang; CHECK:       exit.split.us:
89f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
90f3a27511SJingu Kang; CHECK:       entry.split:
9107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
9207142b30SJingu Kang; CHECK:       loop.header:
93f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
94f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
9507142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
9607142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
9707142b30SJingu Kang; CHECK:       clobber:
9807142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
9907142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
10007142b30SJingu Kang; CHECK:       noclobber:
10107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
10207142b30SJingu Kang; CHECK:       loop.latch:
103f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
10407142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
105f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
106f3a27511SJingu Kang; CHECK:       exit.split:
107f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
10807142b30SJingu Kang; CHECK:       exit:
10907142b30SJingu Kang; CHECK-NEXT:    ret i32 10
11007142b30SJingu Kang;
11107142b30SJingu Kangentry:
11207142b30SJingu Kang  br label %loop.header
11307142b30SJingu Kang
11407142b30SJingu Kangloop.header:
11507142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
11607142b30SJingu Kang  %lv = load i32, i32* %ptr
11707142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
11807142b30SJingu Kang  br i1 %sc, label %clobber, label %noclobber
11907142b30SJingu Kang
12007142b30SJingu Kangclobber:
12107142b30SJingu Kang  call void @clobber()
12207142b30SJingu Kang  br label %loop.latch
12307142b30SJingu Kang
12407142b30SJingu Kangnoclobber:
12507142b30SJingu Kang  br label %loop.latch
12607142b30SJingu Kang
12707142b30SJingu Kangloop.latch:
12807142b30SJingu Kang  %c = icmp ult i32 %iv, %N
12907142b30SJingu Kang  %iv.next = add i32 %iv, 1
13007142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
13107142b30SJingu Kang
13207142b30SJingu Kangexit:
13307142b30SJingu Kang  ret i32 10
13407142b30SJingu Kang}
13507142b30SJingu Kang
13607142b30SJingu Kangdefine i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) {
13707142b30SJingu Kang; CHECK-LABEL: @partial_unswtich_gep_load_icmp(
13807142b30SJingu Kang; CHECK-NEXT:  entry:
139f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32*, i32** [[PTR:%.*]], i32 1
140f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8
141f3a27511SJingu Kang; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4
142f3a27511SJingu Kang; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100
143f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
144f3a27511SJingu Kang; CHECK:       entry.split.us:
145f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
146f3a27511SJingu Kang; CHECK:       loop.header.us:
147f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
148f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
149f3a27511SJingu Kang; CHECK:       noclobber.us:
150f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
151f3a27511SJingu Kang; CHECK:       loop.latch.us:
152f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
153f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
154f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
155f3a27511SJingu Kang; CHECK:       exit.split.us:
156f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
157f3a27511SJingu Kang; CHECK:       entry.split:
15807142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
15907142b30SJingu Kang; CHECK:       loop.header:
160f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
161f3a27511SJingu Kang; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32*, i32** [[PTR]], i32 1
16207142b30SJingu Kang; CHECK-NEXT:    [[LV_1:%.*]] = load i32*, i32** [[GEP]], align 8
16307142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[LV_1]], align 4
16407142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
16507142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
16607142b30SJingu Kang; CHECK:       noclobber:
16707142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
16807142b30SJingu Kang; CHECK:       clobber:
16907142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
17007142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
17107142b30SJingu Kang; CHECK:       loop.latch:
172f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
17307142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
174f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
175f3a27511SJingu Kang; CHECK:       exit.split:
176f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
17707142b30SJingu Kang; CHECK:       exit:
17807142b30SJingu Kang; CHECK-NEXT:    ret i32 10
17907142b30SJingu Kang;
18007142b30SJingu Kangentry:
18107142b30SJingu Kang  br label %loop.header
18207142b30SJingu Kang
18307142b30SJingu Kangloop.header:
18407142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
18507142b30SJingu Kang  %gep = getelementptr i32*, i32** %ptr, i32 1
18607142b30SJingu Kang  %lv.1 = load i32*, i32** %gep
18707142b30SJingu Kang  %lv = load i32, i32* %lv.1
18807142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
18907142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
19007142b30SJingu Kang
19107142b30SJingu Kangnoclobber:
19207142b30SJingu Kang  br label %loop.latch
19307142b30SJingu Kang
19407142b30SJingu Kangclobber:
19507142b30SJingu Kang  call void @clobber()
19607142b30SJingu Kang  br label %loop.latch
19707142b30SJingu Kang
19807142b30SJingu Kangloop.latch:
19907142b30SJingu Kang  %c = icmp ult i32 %iv, %N
20007142b30SJingu Kang  %iv.next = add i32 %iv, 1
20107142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
20207142b30SJingu Kang
20307142b30SJingu Kangexit:
20407142b30SJingu Kang  ret i32 10
20507142b30SJingu Kang}
20607142b30SJingu Kang
20707142b30SJingu Kangdefine i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) {
20807142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_reduction_phi(
20907142b30SJingu Kang; CHECK-NEXT:  entry:
210f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
211f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
212f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
213f3a27511SJingu Kang; CHECK:       entry.split.us:
214f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
215f3a27511SJingu Kang; CHECK:       loop.header.us:
216f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
217f3a27511SJingu Kang; CHECK-NEXT:    [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ]
218f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
219f3a27511SJingu Kang; CHECK:       noclobber.us:
220f3a27511SJingu Kang; CHECK-NEXT:    [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10
221f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
222f3a27511SJingu Kang; CHECK:       loop.latch.us:
223f3a27511SJingu Kang; CHECK-NEXT:    [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ]
224f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
225f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
226f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
227f3a27511SJingu Kang; CHECK:       exit.split.us:
228f3a27511SJingu Kang; CHECK-NEXT:    [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ]
229f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
230f3a27511SJingu Kang; CHECK:       entry.split:
23107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
23207142b30SJingu Kang; CHECK:       loop.header:
233f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
234f3a27511SJingu Kang; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ]
235f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
23607142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
23707142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
23807142b30SJingu Kang; CHECK:       clobber:
23907142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
24007142b30SJingu Kang; CHECK-NEXT:    [[ADD_5:%.*]] = add i32 [[RED]], 5
24107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
24207142b30SJingu Kang; CHECK:       noclobber:
24307142b30SJingu Kang; CHECK-NEXT:    [[ADD_10:%.*]] = add i32 [[RED]], 10
24407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
24507142b30SJingu Kang; CHECK:       loop.latch:
24607142b30SJingu Kang; CHECK-NEXT:    [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ]
247f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
24807142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
249f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP4:![0-9]+]]
250f3a27511SJingu Kang; CHECK:       exit.split:
251107d19ebSJingu Kang; CHECK-NEXT:    [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]
252f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
253f3a27511SJingu Kang; CHECK:       exit:
254f3a27511SJingu Kang; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ]
255f3a27511SJingu Kang; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
25607142b30SJingu Kang;
25707142b30SJingu Kangentry:
25807142b30SJingu Kang  br label %loop.header
25907142b30SJingu Kang
26007142b30SJingu Kangloop.header:
26107142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
26207142b30SJingu Kang  %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]
26307142b30SJingu Kang  %lv = load i32, i32* %ptr
26407142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
26507142b30SJingu Kang  br i1 %sc, label %clobber, label %noclobber
26607142b30SJingu Kang
26707142b30SJingu Kangclobber:
26807142b30SJingu Kang  call void @clobber()
26907142b30SJingu Kang  %add.5 = add i32 %red, 5
27007142b30SJingu Kang  br label %loop.latch
27107142b30SJingu Kang
27207142b30SJingu Kangnoclobber:
27307142b30SJingu Kang  %add.10 = add i32 %red, 10
27407142b30SJingu Kang  br label %loop.latch
27507142b30SJingu Kang
27607142b30SJingu Kangloop.latch:
27707142b30SJingu Kang  %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]
27807142b30SJingu Kang  %c = icmp ult i32 %iv, %N
27907142b30SJingu Kang  %iv.next = add i32 %iv, 1
28007142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
28107142b30SJingu Kang
28207142b30SJingu Kangexit:
28307142b30SJingu Kang  %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
28407142b30SJingu Kang  ret i32 %red.next.lcssa
28507142b30SJingu Kang}
28607142b30SJingu Kang
28707142b30SJingu Kang; Partial unswitching is possible, because the store in %noclobber does not
28807142b30SJingu Kang; alias the load of the condition.
28907142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) {
29007142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_noclobber(
29107142b30SJingu Kang; CHECK-NEXT:  entry:
292f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4
293f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
294f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
295f3a27511SJingu Kang; CHECK:       entry.split.us:
296f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
297f3a27511SJingu Kang; CHECK:       loop.header.us:
298f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
299f3a27511SJingu Kang; CHECK-NEXT:    [[LV_US:%.*]] = load i32, i32* [[PTR_1]], align 4
300f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
301f3a27511SJingu Kang; CHECK:       noclobber.us:
302f3a27511SJingu Kang; CHECK-NEXT:    [[GEP_1_US:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV_US]]
303f3a27511SJingu Kang; CHECK-NEXT:    store i32 [[LV_US]], i32* [[GEP_1_US]], align 4
304f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
305f3a27511SJingu Kang; CHECK:       loop.latch.us:
306f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
307f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
308f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
309f3a27511SJingu Kang; CHECK:       exit.split.us:
310f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
311f3a27511SJingu Kang; CHECK:       entry.split:
31207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
31307142b30SJingu Kang; CHECK:       loop.header:
314f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
315f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_1]], align 4
31607142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
31707142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
31807142b30SJingu Kang; CHECK:       noclobber:
319f3a27511SJingu Kang; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2]], i32 [[IV]]
32007142b30SJingu Kang; CHECK-NEXT:    store i32 [[LV]], i32* [[GEP_1]], align 4
32107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
32207142b30SJingu Kang; CHECK:       clobber:
32307142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
32407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
32507142b30SJingu Kang; CHECK:       loop.latch:
326f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
32707142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
328f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP5:![0-9]+]]
329f3a27511SJingu Kang; CHECK:       exit.split:
330f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
33107142b30SJingu Kang; CHECK:       exit:
33207142b30SJingu Kang; CHECK-NEXT:    ret i32 10
33307142b30SJingu Kang;
33407142b30SJingu Kangentry:
33507142b30SJingu Kang  br label %loop.header
33607142b30SJingu Kang
33707142b30SJingu Kangloop.header:
33807142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
33907142b30SJingu Kang  %lv = load i32, i32* %ptr.1
34007142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
34107142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
34207142b30SJingu Kang
34307142b30SJingu Kangnoclobber:
34407142b30SJingu Kang  %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
34507142b30SJingu Kang  store i32 %lv, i32* %gep.1
34607142b30SJingu Kang  br label %loop.latch
34707142b30SJingu Kang
34807142b30SJingu Kangclobber:
34907142b30SJingu Kang  call void @clobber()
35007142b30SJingu Kang  br label %loop.latch
35107142b30SJingu Kang
35207142b30SJingu Kangloop.latch:
35307142b30SJingu Kang  %c = icmp ult i32 %iv, %N
35407142b30SJingu Kang  %iv.next = add i32 %iv, 1
35507142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
35607142b30SJingu Kang
35707142b30SJingu Kangexit:
35807142b30SJingu Kang  ret i32 10
35907142b30SJingu Kang}
36007142b30SJingu Kang
36107142b30SJingu Kangdefine void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
36207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_phi_cond(
36307142b30SJingu Kang; CHECK-NEXT:  entry:
36407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
36507142b30SJingu Kang; CHECK:       loop.header:
36607142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
36707142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ]
36807142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]
36907142b30SJingu Kang; CHECK:       clobber:
37007142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
37107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
37207142b30SJingu Kang; CHECK:       noclobber:
37307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
37407142b30SJingu Kang; CHECK:       loop.latch:
37507142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
37607142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
37707142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
37807142b30SJingu Kang; CHECK:       exit:
37907142b30SJingu Kang; CHECK-NEXT:    ret void
38007142b30SJingu Kang;
38107142b30SJingu Kangentry:
38207142b30SJingu Kang  br label %loop.header
38307142b30SJingu Kang
38407142b30SJingu Kangloop.header:
38507142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
38607142b30SJingu Kang  %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]
38707142b30SJingu Kang  br i1 %sc, label %clobber, label %noclobber
38807142b30SJingu Kang
38907142b30SJingu Kangclobber:
39007142b30SJingu Kang  call void @clobber()
39107142b30SJingu Kang  br label %loop.latch
39207142b30SJingu Kang
39307142b30SJingu Kangnoclobber:
39407142b30SJingu Kang  br label %loop.latch
39507142b30SJingu Kang
39607142b30SJingu Kangloop.latch:
39707142b30SJingu Kang  %c = icmp ult i32 %iv, %N
39807142b30SJingu Kang  %iv.next = add i32 %iv, 1
39907142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
40007142b30SJingu Kang
40107142b30SJingu Kangexit:
40207142b30SJingu Kang  ret void
40307142b30SJingu Kang}
40407142b30SJingu Kang
40507142b30SJingu Kangdefine void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) {
40607142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_latch(
40707142b30SJingu Kang; CHECK-NEXT:  entry:
40807142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
40907142b30SJingu Kang; CHECK:       loop.header:
41007142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
41107142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
41207142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
41307142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
41407142b30SJingu Kang; CHECK:       noclobber:
41507142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
41607142b30SJingu Kang; CHECK:       clobber:
41707142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
41807142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
41907142b30SJingu Kang; CHECK:       loop.latch:
42007142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
42107142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
42207142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
42307142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
42407142b30SJingu Kang; CHECK:       exit:
42507142b30SJingu Kang; CHECK-NEXT:    ret void
42607142b30SJingu Kang;
42707142b30SJingu Kangentry:
42807142b30SJingu Kang  br label %loop.header
42907142b30SJingu Kang
43007142b30SJingu Kangloop.header:
43107142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
43207142b30SJingu Kang  %lv = load i32, i32* %ptr
43307142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
43407142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
43507142b30SJingu Kang
43607142b30SJingu Kangnoclobber:
43707142b30SJingu Kang  br label %loop.latch
43807142b30SJingu Kang
43907142b30SJingu Kangclobber:
44007142b30SJingu Kang  call void @clobber()
44107142b30SJingu Kang  br label %loop.latch
44207142b30SJingu Kang
44307142b30SJingu Kangloop.latch:
44407142b30SJingu Kang  call void @clobber()
44507142b30SJingu Kang  %c = icmp ult i32 %iv, %N
44607142b30SJingu Kang  %iv.next = add i32 %iv, 1
44707142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
44807142b30SJingu Kang
44907142b30SJingu Kangexit:
45007142b30SJingu Kang  ret void
45107142b30SJingu Kang}
45207142b30SJingu Kang
45307142b30SJingu Kangdefine void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) {
45407142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_header(
45507142b30SJingu Kang; CHECK-NEXT:  entry:
45607142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
45707142b30SJingu Kang; CHECK:       loop.header:
45807142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
45907142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
46007142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
46107142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
46207142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
46307142b30SJingu Kang; CHECK:       noclobber:
46407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
46507142b30SJingu Kang; CHECK:       clobber:
46607142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
46707142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
46807142b30SJingu Kang; CHECK:       loop.latch:
46907142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
47007142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
47107142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
47207142b30SJingu Kang; CHECK:       exit:
47307142b30SJingu Kang; CHECK-NEXT:    ret void
47407142b30SJingu Kang;
47507142b30SJingu Kangentry:
47607142b30SJingu Kang  br label %loop.header
47707142b30SJingu Kang
47807142b30SJingu Kangloop.header:
47907142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
48007142b30SJingu Kang  call void @clobber()
48107142b30SJingu Kang  %lv = load i32, i32* %ptr
48207142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
48307142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
48407142b30SJingu Kang
48507142b30SJingu Kangnoclobber:
48607142b30SJingu Kang  br label %loop.latch
48707142b30SJingu Kang
48807142b30SJingu Kangclobber:
48907142b30SJingu Kang  call void @clobber()
49007142b30SJingu Kang  br label %loop.latch
49107142b30SJingu Kang
49207142b30SJingu Kangloop.latch:
49307142b30SJingu Kang  %c = icmp ult i32 %iv, %N
49407142b30SJingu Kang  %iv.next = add i32 %iv, 1
49507142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
49607142b30SJingu Kang
49707142b30SJingu Kangexit:
49807142b30SJingu Kang  ret void
49907142b30SJingu Kang}
50007142b30SJingu Kang
50107142b30SJingu Kangdefine void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) {
50207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_both(
50307142b30SJingu Kang; CHECK-NEXT:  entry:
50407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
50507142b30SJingu Kang; CHECK:       loop.header:
50607142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
50707142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
50807142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
50907142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
51007142b30SJingu Kang; CHECK:       noclobber:
51107142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
51207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
51307142b30SJingu Kang; CHECK:       clobber:
51407142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
51507142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
51607142b30SJingu Kang; CHECK:       loop.latch:
51707142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
51807142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
51907142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
52007142b30SJingu Kang; CHECK:       exit:
52107142b30SJingu Kang; CHECK-NEXT:    ret void
52207142b30SJingu Kang;
52307142b30SJingu Kangentry:
52407142b30SJingu Kang  br label %loop.header
52507142b30SJingu Kang
52607142b30SJingu Kangloop.header:
52707142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
52807142b30SJingu Kang  %lv = load i32, i32* %ptr
52907142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
53007142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
53107142b30SJingu Kang
53207142b30SJingu Kangnoclobber:
53307142b30SJingu Kang  call void @clobber()
53407142b30SJingu Kang  br label %loop.latch
53507142b30SJingu Kang
53607142b30SJingu Kangclobber:
53707142b30SJingu Kang  call void @clobber()
53807142b30SJingu Kang  br label %loop.latch
53907142b30SJingu Kang
54007142b30SJingu Kangloop.latch:
54107142b30SJingu Kang  %c = icmp ult i32 %iv, %N
54207142b30SJingu Kang  %iv.next = add i32 %iv, 1
54307142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
54407142b30SJingu Kang
54507142b30SJingu Kangexit:
54607142b30SJingu Kang  ret void
54707142b30SJingu Kang}
54807142b30SJingu Kang
54907142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) {
55007142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber(
55107142b30SJingu Kang; CHECK-NEXT:  entry:
55207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
55307142b30SJingu Kang; CHECK:       loop.header:
55407142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
55507142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4
55607142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
55707142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
55807142b30SJingu Kang; CHECK:       noclobber:
55907142b30SJingu Kang; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]]
56007142b30SJingu Kang; CHECK-NEXT:    store i32 [[LV]], i32* [[GEP_1]], align 4
56107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
56207142b30SJingu Kang; CHECK:       clobber:
56307142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
56407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
56507142b30SJingu Kang; CHECK:       loop.latch:
56607142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
56707142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
56807142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
56907142b30SJingu Kang; CHECK:       exit:
57007142b30SJingu Kang; CHECK-NEXT:    ret i32 10
57107142b30SJingu Kang;
57207142b30SJingu Kangentry:
57307142b30SJingu Kang  br label %loop.header
57407142b30SJingu Kang
57507142b30SJingu Kangloop.header:
57607142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
57707142b30SJingu Kang  %lv = load i32, i32* %ptr.1
57807142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
57907142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
58007142b30SJingu Kang
58107142b30SJingu Kangnoclobber:
58207142b30SJingu Kang  %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
58307142b30SJingu Kang  store i32 %lv, i32* %gep.1
58407142b30SJingu Kang  br label %loop.latch
58507142b30SJingu Kang
58607142b30SJingu Kangclobber:
58707142b30SJingu Kang  call void @clobber()
58807142b30SJingu Kang  br label %loop.latch
58907142b30SJingu Kang
59007142b30SJingu Kangloop.latch:
59107142b30SJingu Kang  %c = icmp ult i32 %iv, %N
59207142b30SJingu Kang  %iv.next = add i32 %iv, 1
59307142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
59407142b30SJingu Kang
59507142b30SJingu Kangexit:
59607142b30SJingu Kang  ret i32 10
59707142b30SJingu Kang}
59807142b30SJingu Kang
59907142b30SJingu Kang; Make sure the duplicated instructions are moved to a preheader that always
60007142b30SJingu Kang; executes when the loop body also executes. Do not check the unswitched code,
60107142b30SJingu Kang; because it is already checked in the @partial_unswitch_true_successor test
60207142b30SJingu Kang; case.
60307142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) {
60407142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
60507142b30SJingu Kang; CHECK-NEXT:  entry:
60607142b30SJingu Kang; CHECK-NEXT:    [[EC:%.*]] = icmp ne i32* [[PTR:%.*]], null
60707142b30SJingu Kang; CHECK-NEXT:    br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
60807142b30SJingu Kang; CHECK:       loop.ph:
609f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR]], align 4
610f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
611f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]]
612f3a27511SJingu Kang; CHECK:       loop.ph.split.us:
613f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
614f3a27511SJingu Kang; CHECK:       loop.header.us:
615f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
616f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
617f3a27511SJingu Kang; CHECK:       noclobber.us:
618f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
619f3a27511SJingu Kang; CHECK:       loop.latch.us:
620f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
621f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
622f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]]
623f3a27511SJingu Kang; CHECK:       exit.loopexit.split.us:
624f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT_LOOPEXIT:%.*]]
625f3a27511SJingu Kang; CHECK:       loop.ph.split:
62607142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
62707142b30SJingu Kang; CHECK:       loop.header:
628f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
62907142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
63007142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
63107142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
63207142b30SJingu Kang; CHECK:       noclobber:
63307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
63407142b30SJingu Kang; CHECK:       clobber:
63507142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
63607142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
63707142b30SJingu Kang; CHECK:       loop.latch:
638f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
63907142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
640f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]]
641f3a27511SJingu Kang; CHECK:       exit.loopexit.split:
642f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT_LOOPEXIT]]
64307142b30SJingu Kang; CHECK:       exit.loopexit:
64407142b30SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
64507142b30SJingu Kang; CHECK:       exit:
64607142b30SJingu Kang; CHECK-NEXT:    ret i32 10
64707142b30SJingu Kang;
64807142b30SJingu Kang
64907142b30SJingu Kangentry:
65007142b30SJingu Kang  %ec = icmp ne i32* %ptr, null
65107142b30SJingu Kang  br i1 %ec, label %loop.ph, label %exit
65207142b30SJingu Kang
65307142b30SJingu Kangloop.ph:
65407142b30SJingu Kang  br label %loop.header
65507142b30SJingu Kang
65607142b30SJingu Kangloop.header:
65707142b30SJingu Kang  %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
65807142b30SJingu Kang  %lv = load i32, i32* %ptr
65907142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
66007142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
66107142b30SJingu Kang
66207142b30SJingu Kangnoclobber:
66307142b30SJingu Kang  br label %loop.latch
66407142b30SJingu Kang
66507142b30SJingu Kangclobber:
66607142b30SJingu Kang  call void @clobber()
66707142b30SJingu Kang  br label %loop.latch
66807142b30SJingu Kang
66907142b30SJingu Kangloop.latch:
67007142b30SJingu Kang  %c = icmp ult i32 %iv, %N
67107142b30SJingu Kang  %iv.next = add i32 %iv, 1
67207142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
67307142b30SJingu Kang
67407142b30SJingu Kangexit:
67507142b30SJingu Kang  ret i32 10
67607142b30SJingu Kang}
67707142b30SJingu Kang
67807142b30SJingu Kang; Make sure the duplicated instructions are hoisted just before the branch of
67907142b30SJingu Kang; the preheader. Do not check the unswitched code, because it is already checked
68007142b30SJingu Kang; in the @partial_unswitch_true_successor test case
68107142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) {
68207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
68307142b30SJingu Kang; CHECK-NEXT:  entry:
68407142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
685f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
686f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
687f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
688f3a27511SJingu Kang; CHECK:       entry.split.us:
689f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
690f3a27511SJingu Kang; CHECK:       loop.header.us:
691f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
692f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
693f3a27511SJingu Kang; CHECK:       noclobber.us:
694f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
695f3a27511SJingu Kang; CHECK:       loop.latch.us:
696f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
697f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
698f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
699f3a27511SJingu Kang; CHECK:       exit.split.us:
700f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
701f3a27511SJingu Kang; CHECK:       entry.split:
70207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
70307142b30SJingu Kang; CHECK:       loop.header:
704f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
705f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
70607142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
70707142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
70807142b30SJingu Kang; CHECK:       noclobber:
70907142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
71007142b30SJingu Kang; CHECK:       clobber:
71107142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
71207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
71307142b30SJingu Kang; CHECK:       loop.latch:
714f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
71507142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
716f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]]
717f3a27511SJingu Kang; CHECK:       exit.split:
718f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
71907142b30SJingu Kang; CHECK:       exit:
72007142b30SJingu Kang; CHECK-NEXT:    ret i32 10
72107142b30SJingu Kang;
72207142b30SJingu Kangentry:
72307142b30SJingu Kang  call void @clobber()
72407142b30SJingu Kang  br label %loop.header
72507142b30SJingu Kang
72607142b30SJingu Kangloop.header:
72707142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
72807142b30SJingu Kang  %lv = load i32, i32* %ptr
72907142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
73007142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
73107142b30SJingu Kang
73207142b30SJingu Kangnoclobber:
73307142b30SJingu Kang  br label %loop.latch
73407142b30SJingu Kang
73507142b30SJingu Kangclobber:
73607142b30SJingu Kang  call void @clobber()
73707142b30SJingu Kang  br label %loop.latch
73807142b30SJingu Kang
73907142b30SJingu Kangloop.latch:
74007142b30SJingu Kang  %c = icmp ult i32 %iv, %N
74107142b30SJingu Kang  %iv.next = add i32 %iv, 1
74207142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
74307142b30SJingu Kang
74407142b30SJingu Kangexit:
74507142b30SJingu Kang  ret i32 10
74607142b30SJingu Kang}
74707142b30SJingu Kang
74807142b30SJingu Kang; Make sure invariant instructions in the loop are also hoisted to the preheader.
74907142b30SJingu Kang; Do not check the unswitched code, because it is already checked in the
75007142b30SJingu Kang; @partial_unswitch_true_successor test case
75107142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) {
75207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
75307142b30SJingu Kang; CHECK-NEXT:  entry:
754f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 1
755f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
756f3a27511SJingu Kang; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100
757f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
758f3a27511SJingu Kang; CHECK:       entry.split.us:
759f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
760f3a27511SJingu Kang; CHECK:       loop.header.us:
761f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
762f3a27511SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
763f3a27511SJingu Kang; CHECK:       noclobber.us:
764f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
765f3a27511SJingu Kang; CHECK:       loop.latch.us:
766f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
767f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
768f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
769f3a27511SJingu Kang; CHECK:       exit.split.us:
770f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
771f3a27511SJingu Kang; CHECK:       entry.split:
77207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
77307142b30SJingu Kang; CHECK:       loop.header:
774f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
775f3a27511SJingu Kang; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[PTR]], i64 1
77607142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[GEP]], align 4
77707142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
77807142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
77907142b30SJingu Kang; CHECK:       noclobber:
78007142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
78107142b30SJingu Kang; CHECK:       clobber:
78207142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
78307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
78407142b30SJingu Kang; CHECK:       loop.latch:
785f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
78607142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
787f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]]
788f3a27511SJingu Kang; CHECK:       exit.split:
789f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
79007142b30SJingu Kang; CHECK:       exit:
79107142b30SJingu Kang; CHECK-NEXT:    ret i32 10
79207142b30SJingu Kang;
79307142b30SJingu Kangentry:
79407142b30SJingu Kang  br label %loop.header
79507142b30SJingu Kang
79607142b30SJingu Kangloop.header:
79707142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
79807142b30SJingu Kang  %gep = getelementptr i32, i32* %ptr, i64 1
79907142b30SJingu Kang  %lv = load i32, i32* %gep
80007142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
80107142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
80207142b30SJingu Kang
80307142b30SJingu Kangnoclobber:
80407142b30SJingu Kang  br label %loop.latch
80507142b30SJingu Kang
80607142b30SJingu Kangclobber:
80707142b30SJingu Kang  call void @clobber()
80807142b30SJingu Kang  br label %loop.latch
80907142b30SJingu Kang
81007142b30SJingu Kangloop.latch:
81107142b30SJingu Kang  %c = icmp ult i32 %iv, %N
81207142b30SJingu Kang  %iv.next = add i32 %iv, 1
81307142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
81407142b30SJingu Kang
81507142b30SJingu Kangexit:
81607142b30SJingu Kang  ret i32 10
81707142b30SJingu Kang}
81807142b30SJingu Kang
81907142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such
82007142b30SJingu Kang; loads is not safe.
82107142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) {
82207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered(
82307142b30SJingu Kang; CHECK-NEXT:  entry:
82407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
82507142b30SJingu Kang; CHECK:       loop.header:
82607142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
82707142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] unordered, align 4
82807142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
82907142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
83007142b30SJingu Kang; CHECK:       noclobber:
83107142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
83207142b30SJingu Kang; CHECK:       clobber:
83307142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
83407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
83507142b30SJingu Kang; CHECK:       loop.latch:
83607142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
83707142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
83807142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
83907142b30SJingu Kang; CHECK:       exit:
84007142b30SJingu Kang; CHECK-NEXT:    ret i32 10
84107142b30SJingu Kang;
84207142b30SJingu Kangentry:
84307142b30SJingu Kang  br label %loop.header
84407142b30SJingu Kang
84507142b30SJingu Kangloop.header:
84607142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
84707142b30SJingu Kang  %lv = load atomic i32, i32* %ptr unordered, align 4
84807142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
84907142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
85007142b30SJingu Kang
85107142b30SJingu Kangnoclobber:
85207142b30SJingu Kang  br label %loop.latch
85307142b30SJingu Kang
85407142b30SJingu Kangclobber:
85507142b30SJingu Kang  call void @clobber()
85607142b30SJingu Kang  br label %loop.latch
85707142b30SJingu Kang
85807142b30SJingu Kangloop.latch:
85907142b30SJingu Kang  %c = icmp ult i32 %iv, %N
86007142b30SJingu Kang  %iv.next = add i32 %iv, 1
86107142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
86207142b30SJingu Kang
86307142b30SJingu Kangexit:
86407142b30SJingu Kang  ret i32 10
86507142b30SJingu Kang}
86607142b30SJingu Kang
86707142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such
86807142b30SJingu Kang; loads is not safe.
86907142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) {
87007142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic(
87107142b30SJingu Kang; CHECK-NEXT:  entry:
87207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
87307142b30SJingu Kang; CHECK:       loop.header:
87407142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
87507142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] monotonic, align 4
87607142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
87707142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
87807142b30SJingu Kang; CHECK:       noclobber:
87907142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
88007142b30SJingu Kang; CHECK:       clobber:
88107142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
88207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
88307142b30SJingu Kang; CHECK:       loop.latch:
88407142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
88507142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
88607142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
88707142b30SJingu Kang; CHECK:       exit:
88807142b30SJingu Kang; CHECK-NEXT:    ret i32 10
88907142b30SJingu Kang;
89007142b30SJingu Kangentry:
89107142b30SJingu Kang  br label %loop.header
89207142b30SJingu Kang
89307142b30SJingu Kangloop.header:
89407142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
89507142b30SJingu Kang  %lv = load atomic i32, i32* %ptr monotonic, align 4
89607142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
89707142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
89807142b30SJingu Kang
89907142b30SJingu Kangnoclobber:
90007142b30SJingu Kang  br label %loop.latch
90107142b30SJingu Kang
90207142b30SJingu Kangclobber:
90307142b30SJingu Kang  call void @clobber()
90407142b30SJingu Kang  br label %loop.latch
90507142b30SJingu Kang
90607142b30SJingu Kangloop.latch:
90707142b30SJingu Kang  %c = icmp ult i32 %iv, %N
90807142b30SJingu Kang  %iv.next = add i32 %iv, 1
90907142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
91007142b30SJingu Kang
91107142b30SJingu Kangexit:
91207142b30SJingu Kang  ret i32 10
91307142b30SJingu Kang}
91407142b30SJingu Kang
91507142b30SJingu Kang
91607142b30SJingu Kangdeclare i32 @get_value()
91707142b30SJingu Kang
91807142b30SJingu Kang; Do not unswitch if the condition depends on a call, that may clobber memory.
91907142b30SJingu Kang; Duplicating such a call is not safe.
92007142b30SJingu Kangdefine i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) {
92107142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_cond_call(
92207142b30SJingu Kang; CHECK-NEXT:  entry:
92307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
92407142b30SJingu Kang; CHECK:       loop.header:
92507142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
92607142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = call i32 @get_value()
92707142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
92807142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
92907142b30SJingu Kang; CHECK:       noclobber:
93007142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
93107142b30SJingu Kang; CHECK:       clobber:
93207142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
93307142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
93407142b30SJingu Kang; CHECK:       loop.latch:
93507142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
93607142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
93707142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
93807142b30SJingu Kang; CHECK:       exit:
93907142b30SJingu Kang; CHECK-NEXT:    ret i32 10
94007142b30SJingu Kang;
94107142b30SJingu Kangentry:
94207142b30SJingu Kang  br label %loop.header
94307142b30SJingu Kang
94407142b30SJingu Kangloop.header:
94507142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
94607142b30SJingu Kang  %lv = call i32 @get_value()
94707142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
94807142b30SJingu Kang  br i1 %sc, label %noclobber, label %clobber
94907142b30SJingu Kang
95007142b30SJingu Kangnoclobber:
95107142b30SJingu Kang  br label %loop.latch
95207142b30SJingu Kang
95307142b30SJingu Kangclobber:
95407142b30SJingu Kang  call void @clobber()
95507142b30SJingu Kang  br label %loop.latch
95607142b30SJingu Kang
95707142b30SJingu Kangloop.latch:
95807142b30SJingu Kang  %c = icmp ult i32 %iv, %N
95907142b30SJingu Kang  %iv.next = add i32 %iv, 1
96007142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
96107142b30SJingu Kang
96207142b30SJingu Kangexit:
96307142b30SJingu Kang  ret i32 10
96407142b30SJingu Kang}
96507142b30SJingu Kang
96607142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) {
96707142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_exit(
96807142b30SJingu Kang; CHECK-NEXT:  entry:
96907142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
97007142b30SJingu Kang; CHECK:       loop.header:
97107142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
97207142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
97307142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
97407142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]]
97507142b30SJingu Kang; CHECK:       clobber:
97607142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
97707142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
97807142b30SJingu Kang; CHECK:       loop.latch:
97907142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
98007142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
98107142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]]
98207142b30SJingu Kang; CHECK:       exit:
98307142b30SJingu Kang; CHECK-NEXT:    ret i32 10
98407142b30SJingu Kang;
98507142b30SJingu Kangentry:
98607142b30SJingu Kang  br label %loop.header
98707142b30SJingu Kang
98807142b30SJingu Kangloop.header:
98907142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
99007142b30SJingu Kang  %lv = load i32, i32* %ptr
99107142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
99207142b30SJingu Kang  br i1 %sc, label %exit, label %clobber
99307142b30SJingu Kang
99407142b30SJingu Kangclobber:
99507142b30SJingu Kang  call void @clobber()
99607142b30SJingu Kang  br label %loop.latch
99707142b30SJingu Kang
99807142b30SJingu Kangloop.latch:
99907142b30SJingu Kang  %c = icmp ult i32 %iv, %N
100007142b30SJingu Kang  %iv.next = add i32 %iv, 1
100107142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
100207142b30SJingu Kang
100307142b30SJingu Kangexit:
100407142b30SJingu Kang  ret i32 10
100507142b30SJingu Kang}
100607142b30SJingu Kang
100707142b30SJingu Kangdefine i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) {
100807142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_same_successor(
100907142b30SJingu Kang; CHECK-NEXT:  entry:
101007142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
101107142b30SJingu Kang; CHECK:       loop.header:
101207142b30SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
101307142b30SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4
101407142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
101507142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]]
101607142b30SJingu Kang; CHECK:       noclobber:
101707142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
101807142b30SJingu Kang; CHECK:       loop.latch:
101907142b30SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
102007142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
102107142b30SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
102207142b30SJingu Kang; CHECK:       exit:
102307142b30SJingu Kang; CHECK-NEXT:    ret i32 10
102407142b30SJingu Kang;
102507142b30SJingu Kangentry:
102607142b30SJingu Kang  br label %loop.header
102707142b30SJingu Kang
102807142b30SJingu Kangloop.header:
102907142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
103007142b30SJingu Kang  %lv = load i32, i32* %ptr
103107142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
103207142b30SJingu Kang  br i1 %sc, label %noclobber, label %noclobber
103307142b30SJingu Kang
103407142b30SJingu Kangnoclobber:
103507142b30SJingu Kang  br label %loop.latch
103607142b30SJingu Kang
103707142b30SJingu Kangloop.latch:
103807142b30SJingu Kang  %c = icmp ult i32 %iv, %N
103907142b30SJingu Kang  %iv.next = add i32 %iv, 1
104007142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
104107142b30SJingu Kang
104207142b30SJingu Kangexit:
104307142b30SJingu Kang  ret i32 10
104407142b30SJingu Kang}
104507142b30SJingu Kang
104607142b30SJingu Kangdefine i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) {
104707142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_to_latch(
104807142b30SJingu Kang; CHECK-NEXT:  entry:
1049f3a27511SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
1050f3a27511SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
1051f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1052f3a27511SJingu Kang; CHECK:       entry.split.us:
1053f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1054f3a27511SJingu Kang; CHECK:       loop.header.us:
1055f3a27511SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1056f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1057f3a27511SJingu Kang; CHECK:       loop.latch.us:
1058f3a27511SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1059f3a27511SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1060f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1061f3a27511SJingu Kang; CHECK:       exit.split.us:
1062f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
1063f3a27511SJingu Kang; CHECK:       entry.split:
106407142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
106507142b30SJingu Kang; CHECK:       loop.header:
1066f3a27511SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1067f3a27511SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
106807142b30SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
106907142b30SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]]
107007142b30SJingu Kang; CHECK:       clobber:
107107142b30SJingu Kang; CHECK-NEXT:    call void @clobber()
107207142b30SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
107307142b30SJingu Kang; CHECK:       loop.latch:
1074f3a27511SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
107507142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1076f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]]
1077f3a27511SJingu Kang; CHECK:       exit.split:
1078f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
107907142b30SJingu Kang; CHECK:       exit:
108007142b30SJingu Kang; CHECK-NEXT:    ret i32 10
108107142b30SJingu Kang;
108207142b30SJingu Kangentry:
108307142b30SJingu Kang  br label %loop.header
108407142b30SJingu Kang
108507142b30SJingu Kangloop.header:
108607142b30SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
108707142b30SJingu Kang  %lv = load i32, i32* %ptr
108807142b30SJingu Kang  %sc = icmp eq i32 %lv, 100
108907142b30SJingu Kang  br i1 %sc, label %loop.latch, label %clobber
109007142b30SJingu Kang
109107142b30SJingu Kangclobber:
109207142b30SJingu Kang  call void @clobber()
109307142b30SJingu Kang  br label %loop.latch
109407142b30SJingu Kang
109507142b30SJingu Kangloop.latch:
109607142b30SJingu Kang  %c = icmp ult i32 %iv, %N
109707142b30SJingu Kang  %iv.next = add i32 %iv, 1
109807142b30SJingu Kang  br i1 %c, label %loop.header, label %exit
109907142b30SJingu Kang
110007142b30SJingu Kangexit:
110107142b30SJingu Kang  ret i32 10
110207142b30SJingu Kang}
1103f3a27511SJingu Kang
1104f3a27511SJingu Kang; There could be multiple unswitch candidates which include partially invariant
1105f3a27511SJingu Kang; condition. When the exiting block is selected as best unswitch one, clone loop
1106f3a27511SJingu Kang; blocks.
1107f3a27511SJingu Kangdefine i32 @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(i32 %0, i32 %1, i32* %ptr) {
1108f3a27511SJingu Kang; CHECK-LABEL: @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(
1109f3a27511SJingu Kang; CHECK-NEXT:  entry:
1110f3a27511SJingu Kang; CHECK-NEXT:    [[EXIT_COND:%.*]] = icmp ne i32 [[TMP0:%.*]], 0
1111f3a27511SJingu Kang; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[PTR:%.*]], align 16
1112f3a27511SJingu Kang; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 41
1113873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[TMP3]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]
1114873ff5a7SJingu Kang; CHECK:       entry.split.us:
1115873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]]
1116f3a27511SJingu Kang; CHECK:       entry.split.us.split.us:
1117f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_US_US:%.*]]
1118f3a27511SJingu Kang; CHECK:       loop.us.us:
1119f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXITING_US_US:%.*]]
1120f3a27511SJingu Kang; CHECK:       exiting.us.us:
1121f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_US_US]]
1122f3a27511SJingu Kang; CHECK:       entry.split.us.split:
1123f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP_US:%.*]]
1124f3a27511SJingu Kang; CHECK:       loop.us:
1125873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXITING_US:%.*]]
1126f3a27511SJingu Kang; CHECK:       exiting.us:
1127873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXIT_SPLIT_US:%.*]]
1128873ff5a7SJingu Kang; CHECK:       exit.split.us:
1129873ff5a7SJingu Kang; CHECK-NEXT:    [[RET_VAL_US:%.*]] = phi i32 [ 1, [[EXITING_US]] ]
1130873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
1131f3a27511SJingu Kang; CHECK:       entry.split:
1132f3a27511SJingu Kang; CHECK-NEXT:    br label [[LOOP:%.*]]
1133f3a27511SJingu Kang; CHECK:       loop:
1134f3a27511SJingu Kang; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]], align 16
1135f3a27511SJingu Kang; CHECK-NEXT:    [[IF_COND:%.*]] = icmp ult i32 [[VAL]], 41
1136f3a27511SJingu Kang; CHECK-NEXT:    br i1 [[IF_COND]], label [[IF_THEN:%.*]], label [[EXITING:%.*]]
1137f3a27511SJingu Kang; CHECK:       if.then:
1138873ff5a7SJingu Kang; CHECK-NEXT:    store i32 [[TMP1:%.*]], i32* [[PTR]], align 16
1139f3a27511SJingu Kang; CHECK-NEXT:    br label [[EXITING]]
1140f3a27511SJingu Kang; CHECK:       exiting:
1141873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]]
1142873ff5a7SJingu Kang; CHECK:       exit.split:
1143f3a27511SJingu Kang; CHECK-NEXT:    [[RET_VAL:%.*]] = phi i32 [ 1, [[EXITING]] ]
1144873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
1145873ff5a7SJingu Kang; CHECK:       exit:
1146873ff5a7SJingu Kang; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[RET_VAL]], [[EXIT_SPLIT]] ], [ [[RET_VAL_US]], [[EXIT_SPLIT_US]] ]
1147873ff5a7SJingu Kang; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]
1148f3a27511SJingu Kang;
1149f3a27511SJingu Kangentry:
1150f3a27511SJingu Kang  %exit.cond = icmp ne i32 %0, 0
1151f3a27511SJingu Kang  br label %loop
1152f3a27511SJingu Kang
1153f3a27511SJingu Kangloop:
1154f3a27511SJingu Kang  %val = load i32, i32* %ptr, align 16
1155f3a27511SJingu Kang  %if.cond = icmp ult i32 %val, 41
1156f3a27511SJingu Kang  br i1 %if.cond, label %if.then, label %exiting
1157f3a27511SJingu Kang
1158f3a27511SJingu Kangif.then:
1159f3a27511SJingu Kang  store i32 %1, i32* %ptr, align 16
1160f3a27511SJingu Kang  br label %exiting
1161f3a27511SJingu Kang
1162f3a27511SJingu Kangexiting:
1163f3a27511SJingu Kang  br i1 %exit.cond, label %loop, label %exit
1164f3a27511SJingu Kang
1165f3a27511SJingu Kangexit:
1166f3a27511SJingu Kang  %ret.val = phi i32 [ 1, %exiting ]
1167f3a27511SJingu Kang  ret i32 %ret.val
1168f3a27511SJingu Kang}
1169f3a27511SJingu Kang
1170873ff5a7SJingu Kang; The path with noclobber block is only duplicated so we need to calculate only
1171873ff5a7SJingu Kang; the cost of the path with noclobber.
1172873ff5a7SJingu Kangdefine i32 @partial_unswitch_true_successor_for_cost_calculation(i32* %ptr, i32 %N) {
1173873ff5a7SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_for_cost_calculation(
1174873ff5a7SJingu Kang; CHECK-NEXT:  entry:
1175873ff5a7SJingu Kang; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
1176873ff5a7SJingu Kang; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
1177873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
1178873ff5a7SJingu Kang; CHECK:       entry.split.us:
1179873ff5a7SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
1180873ff5a7SJingu Kang; CHECK:       loop.header.us:
1181873ff5a7SJingu Kang; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
1182873ff5a7SJingu Kang; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
1183873ff5a7SJingu Kang; CHECK:       noclobber.us:
1184873ff5a7SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
1185873ff5a7SJingu Kang; CHECK:       loop.latch.us:
1186873ff5a7SJingu Kang; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
1187873ff5a7SJingu Kang; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
1188873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
1189873ff5a7SJingu Kang; CHECK:       exit.split.us:
1190873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXIT:%.*]]
1191873ff5a7SJingu Kang; CHECK:       entry.split:
1192873ff5a7SJingu Kang; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1193873ff5a7SJingu Kang; CHECK:       loop.header:
1194873ff5a7SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1195873ff5a7SJingu Kang; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
1196873ff5a7SJingu Kang; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
1197873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
1198873ff5a7SJingu Kang; CHECK:       noclobber:
1199873ff5a7SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
1200873ff5a7SJingu Kang; CHECK:       clobber:
1201873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1202873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1203873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1204873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1205873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1206873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1207873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1208873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1209873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1210873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1211873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1212873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1213873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1214873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1215873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1216873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1217873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1218873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1219873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1220873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1221873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1222873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1223873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1224873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1225873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1226873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1227873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1228873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1229873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1230873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1231873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1232873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1233873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1234873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1235873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1236873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1237873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1238873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1239873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1240873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1241873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1242873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1243873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1244873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1245873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1246873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1247873ff5a7SJingu Kang; CHECK-NEXT:    call void @clobber()
1248873ff5a7SJingu Kang; CHECK-NEXT:    br label [[LOOP_LATCH]]
1249873ff5a7SJingu Kang; CHECK:       loop.latch:
1250873ff5a7SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
1251873ff5a7SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
1252873ff5a7SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]]
1253873ff5a7SJingu Kang; CHECK:       exit.split:
1254873ff5a7SJingu Kang; CHECK-NEXT:    br label [[EXIT]]
1255873ff5a7SJingu Kang; CHECK:       exit:
1256873ff5a7SJingu Kang; CHECK-NEXT:    ret i32 10
1257873ff5a7SJingu Kang;
1258873ff5a7SJingu Kangentry:
1259873ff5a7SJingu Kang  br label %loop.header
1260873ff5a7SJingu Kang
1261873ff5a7SJingu Kangloop.header:
1262873ff5a7SJingu Kang  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1263873ff5a7SJingu Kang  %lv = load i32, i32* %ptr
1264873ff5a7SJingu Kang  %sc = icmp eq i32 %lv, 100
1265873ff5a7SJingu Kang  br i1 %sc, label %noclobber, label %clobber
1266873ff5a7SJingu Kang
1267873ff5a7SJingu Kangnoclobber:
1268873ff5a7SJingu Kang  br label %loop.latch
1269873ff5a7SJingu Kang
1270873ff5a7SJingu Kangclobber:
1271873ff5a7SJingu Kang  call void @clobber()
1272873ff5a7SJingu Kang  call void @clobber()
1273873ff5a7SJingu Kang  call void @clobber()
1274873ff5a7SJingu Kang  call void @clobber()
1275873ff5a7SJingu Kang  call void @clobber()
1276873ff5a7SJingu Kang  call void @clobber()
1277873ff5a7SJingu Kang  call void @clobber()
1278873ff5a7SJingu Kang  call void @clobber()
1279873ff5a7SJingu Kang  call void @clobber()
1280873ff5a7SJingu Kang  call void @clobber()
1281873ff5a7SJingu Kang  call void @clobber()
1282873ff5a7SJingu Kang  call void @clobber()
1283873ff5a7SJingu Kang  call void @clobber()
1284873ff5a7SJingu Kang  call void @clobber()
1285873ff5a7SJingu Kang  call void @clobber()
1286873ff5a7SJingu Kang  call void @clobber()
1287873ff5a7SJingu Kang  call void @clobber()
1288873ff5a7SJingu Kang  call void @clobber()
1289873ff5a7SJingu Kang  call void @clobber()
1290873ff5a7SJingu Kang  call void @clobber()
1291873ff5a7SJingu Kang  call void @clobber()
1292873ff5a7SJingu Kang  call void @clobber()
1293873ff5a7SJingu Kang  call void @clobber()
1294873ff5a7SJingu Kang  call void @clobber()
1295873ff5a7SJingu Kang  call void @clobber()
1296873ff5a7SJingu Kang  call void @clobber()
1297873ff5a7SJingu Kang  call void @clobber()
1298873ff5a7SJingu Kang  call void @clobber()
1299873ff5a7SJingu Kang  call void @clobber()
1300873ff5a7SJingu Kang  call void @clobber()
1301873ff5a7SJingu Kang  call void @clobber()
1302873ff5a7SJingu Kang  call void @clobber()
1303873ff5a7SJingu Kang  call void @clobber()
1304873ff5a7SJingu Kang  call void @clobber()
1305873ff5a7SJingu Kang  call void @clobber()
1306873ff5a7SJingu Kang  call void @clobber()
1307873ff5a7SJingu Kang  call void @clobber()
1308873ff5a7SJingu Kang  call void @clobber()
1309873ff5a7SJingu Kang  call void @clobber()
1310873ff5a7SJingu Kang  call void @clobber()
1311873ff5a7SJingu Kang  call void @clobber()
1312873ff5a7SJingu Kang  call void @clobber()
1313873ff5a7SJingu Kang  call void @clobber()
1314873ff5a7SJingu Kang  call void @clobber()
1315873ff5a7SJingu Kang  call void @clobber()
1316873ff5a7SJingu Kang  call void @clobber()
1317873ff5a7SJingu Kang  call void @clobber()
1318873ff5a7SJingu Kang  br label %loop.latch
1319873ff5a7SJingu Kang
1320873ff5a7SJingu Kangloop.latch:
1321873ff5a7SJingu Kang  %c = icmp ult i32 %iv, %N
1322873ff5a7SJingu Kang  %iv.next = add i32 %iv, 1
1323873ff5a7SJingu Kang  br i1 %c, label %loop.header, label %exit
1324873ff5a7SJingu Kang
1325873ff5a7SJingu Kangexit:
1326873ff5a7SJingu Kang  ret i32 10
1327873ff5a7SJingu Kang}
1328873ff5a7SJingu Kang
1329f3a27511SJingu Kang; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[UNSWITCH_PARTIAL_DISABLE:![0-9]+]]}
1330f3a27511SJingu Kang; CHECK: [[UNSWITCH_PARTIAL_DISABLE]] = !{!"llvm.loop.unswitch.partial.disable"}
1331f3a27511SJingu Kang; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[UNSWITCH_PARTIAL_DISABLE]]}
1332f3a27511SJingu Kang; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[UNSWITCH_PARTIAL_DISABLE]]}
1333f3a27511SJingu Kang; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[UNSWITCH_PARTIAL_DISABLE]]}
1334f3a27511SJingu Kang; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[UNSWITCH_PARTIAL_DISABLE]]}
1335f3a27511SJingu Kang; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[UNSWITCH_PARTIAL_DISABLE]]}
1336f3a27511SJingu Kang; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[UNSWITCH_PARTIAL_DISABLE]]}
1337f3a27511SJingu Kang; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[UNSWITCH_PARTIAL_DISABLE]]}
1338f3a27511SJingu Kang; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[UNSWITCH_PARTIAL_DISABLE]]}
1339f3a27511SJingu Kang; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[UNSWITCH_PARTIAL_DISABLE]]}
1340873ff5a7SJingu Kang; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[UNSWITCH_PARTIAL_DISABLE]]}
1341