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