[ValueTracking] test trunc to i1 as condition in dominating condition. (NFC)
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / loop-form.ll
blob730d488119d1396e5905e4dc4005d441396d8a26
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=loop-vectorize -force-vector-width=2 < %s | FileCheck %s
3 ; RUN: opt -S -passes=loop-vectorize -force-vector-width=2  -prefer-predicate-over-epilogue=predicate-dont-vectorize < %s | FileCheck --check-prefix TAILFOLD %s
5 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
7 define void @bottom_tested(ptr %p, i32 %n) {
8 ; CHECK-LABEL: @bottom_tested(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
11 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
12 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 2
13 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
14 ; CHECK:       vector.ph:
15 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
16 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[N_MOD_VF]]
17 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
18 ; CHECK:       vector.body:
19 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
20 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
21 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
22 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP2]]
23 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i16, ptr [[TMP3]], i32 0
24 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP4]], align 4
25 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
26 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
27 ; CHECK-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
28 ; CHECK:       middle.block:
29 ; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i32 [[TMP0]], [[N_VEC]]
30 ; CHECK-NEXT:    br i1 [[CMP_N]], label [[IF_END:%.*]], label [[SCALAR_PH]]
31 ; CHECK:       scalar.ph:
32 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
33 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
34 ; CHECK:       for.cond:
35 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_COND]] ]
36 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
37 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
38 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
39 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
40 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
41 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP3:![0-9]+]]
42 ; CHECK:       if.end:
43 ; CHECK-NEXT:    ret void
45 ; TAILFOLD-LABEL: @bottom_tested(
46 ; TAILFOLD-NEXT:  entry:
47 ; TAILFOLD-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
48 ; TAILFOLD-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
49 ; TAILFOLD-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
50 ; TAILFOLD:       vector.ph:
51 ; TAILFOLD-NEXT:    [[N_RND_UP:%.*]] = add i32 [[TMP0]], 1
52 ; TAILFOLD-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 2
53 ; TAILFOLD-NEXT:    [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]
54 ; TAILFOLD-NEXT:    [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP0]], 1
55 ; TAILFOLD-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i64 0
56 ; TAILFOLD-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i32> [[BROADCAST_SPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
57 ; TAILFOLD-NEXT:    br label [[VECTOR_BODY:%.*]]
58 ; TAILFOLD:       vector.body:
59 ; TAILFOLD-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
60 ; TAILFOLD-NEXT:    [[VEC_IND:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE2]] ]
61 ; TAILFOLD-NEXT:    [[TMP1:%.*]] = icmp ule <2 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
62 ; TAILFOLD-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[VEC_IND]] to <2 x i64>
63 ; TAILFOLD-NEXT:    [[TMP3:%.*]] = extractelement <2 x i1> [[TMP1]], i32 0
64 ; TAILFOLD-NEXT:    br i1 [[TMP3]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
65 ; TAILFOLD:       pred.store.if:
66 ; TAILFOLD-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
67 ; TAILFOLD-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
68 ; TAILFOLD-NEXT:    store i16 0, ptr [[TMP5]], align 4
69 ; TAILFOLD-NEXT:    br label [[PRED_STORE_CONTINUE]]
70 ; TAILFOLD:       pred.store.continue:
71 ; TAILFOLD-NEXT:    [[TMP6:%.*]] = extractelement <2 x i1> [[TMP1]], i32 1
72 ; TAILFOLD-NEXT:    br i1 [[TMP6]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
73 ; TAILFOLD:       pred.store.if1:
74 ; TAILFOLD-NEXT:    [[TMP7:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
75 ; TAILFOLD-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[TMP7]]
76 ; TAILFOLD-NEXT:    store i16 0, ptr [[TMP8]], align 4
77 ; TAILFOLD-NEXT:    br label [[PRED_STORE_CONTINUE2]]
78 ; TAILFOLD:       pred.store.continue2:
79 ; TAILFOLD-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
80 ; TAILFOLD-NEXT:    [[VEC_IND_NEXT]] = add <2 x i32> [[VEC_IND]], splat (i32 2)
81 ; TAILFOLD-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
82 ; TAILFOLD-NEXT:    br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
83 ; TAILFOLD:       middle.block:
84 ; TAILFOLD-NEXT:    br i1 true, label [[IF_END:%.*]], label [[SCALAR_PH]]
85 ; TAILFOLD:       scalar.ph:
86 ; TAILFOLD-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
87 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
88 ; TAILFOLD:       for.cond:
89 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_COND]] ]
90 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
91 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
92 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
93 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
94 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
95 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP3:![0-9]+]]
96 ; TAILFOLD:       if.end:
97 ; TAILFOLD-NEXT:    ret void
99 entry:
100   br label %for.cond
102 for.cond:
103   %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
104   %iprom = sext i32 %i to i64
105   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
106   store i16 0, ptr %b, align 4
107   %inc = add nsw i32 %i, 1
108   %cmp = icmp slt i32 %i, %n
109   br i1 %cmp, label %for.cond, label %if.end
111 if.end:
112   ret void
115 define void @early_exit(ptr %p, i32 %n) {
116 ; CHECK-LABEL: @early_exit(
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
119 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
120 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
121 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
122 ; CHECK:       vector.ph:
123 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
124 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
125 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
126 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
127 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
128 ; CHECK:       vector.body:
129 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
130 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
131 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
132 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
133 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
134 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
135 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
136 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
137 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
138 ; CHECK:       middle.block:
139 ; CHECK-NEXT:    br label [[SCALAR_PH]]
140 ; CHECK:       scalar.ph:
141 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
142 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
143 ; CHECK:       for.cond:
144 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
145 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
146 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
147 ; CHECK:       for.body:
148 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
149 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
150 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
151 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
152 ; CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
153 ; CHECK:       if.end:
154 ; CHECK-NEXT:    ret void
156 ; TAILFOLD-LABEL: @early_exit(
157 ; TAILFOLD-NEXT:  entry:
158 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
159 ; TAILFOLD:       for.cond:
160 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
161 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
162 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
163 ; TAILFOLD:       for.body:
164 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
165 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
166 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
167 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
168 ; TAILFOLD-NEXT:    br label [[FOR_COND]]
169 ; TAILFOLD:       if.end:
170 ; TAILFOLD-NEXT:    ret void
172 entry:
173   br label %for.cond
175 for.cond:
176   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
177   %cmp = icmp slt i32 %i, %n
178   br i1 %cmp, label %for.body, label %if.end
180 for.body:
181   %iprom = sext i32 %i to i64
182   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
183   store i16 0, ptr %b, align 4
184   %inc = add nsw i32 %i, 1
185   br label %for.cond
187 if.end:
188   ret void
191 define i32 @early_exit_with_live_out(ptr %ptr) {
192 ; CHECK-LABEL: @early_exit_with_live_out(
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
195 ; CHECK:       vector.ph:
196 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
197 ; CHECK:       vector.body:
198 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
199 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
200 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 [[TMP0]]
201 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, ptr [[TMP1]], i32 0
202 ; CHECK-NEXT:    store <2 x i32> splat (i32 10), ptr [[TMP2]], align 4
203 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
204 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 998
205 ; CHECK-NEXT:    br i1 [[TMP3]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
206 ; CHECK:       middle.block:
207 ; CHECK-NEXT:    br label [[SCALAR_PH]]
208 ; CHECK:       scalar.ph:
209 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 998, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
210 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
211 ; CHECK:       loop.header:
212 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
213 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[IV]]
214 ; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP]], align 4
215 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
216 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
217 ; CHECK-NEXT:    br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
218 ; CHECK:       loop.latch:
219 ; CHECK-NEXT:    store i32 10, ptr [[GEP]], align 4
220 ; CHECK-NEXT:    br label [[LOOP_HEADER]], !llvm.loop [[LOOP7:![0-9]+]]
221 ; CHECK:       exit:
222 ; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[L]], [[LOOP_HEADER]] ]
223 ; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
225 ; TAILFOLD-LABEL: @early_exit_with_live_out(
226 ; TAILFOLD-NEXT:  entry:
227 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
228 ; TAILFOLD:       loop.header:
229 ; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
230 ; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 [[IV]]
231 ; TAILFOLD-NEXT:    [[L:%.*]] = load i32, ptr [[GEP]], align 4
232 ; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
233 ; TAILFOLD-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
234 ; TAILFOLD-NEXT:    br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
235 ; TAILFOLD:       loop.latch:
236 ; TAILFOLD-NEXT:    store i32 10, ptr [[GEP]], align 4
237 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
238 ; TAILFOLD:       exit:
239 ; TAILFOLD-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[L]], [[LOOP_HEADER]] ]
240 ; TAILFOLD-NEXT:    ret i32 [[RES_LCSSA]]
242 entry:
243   br label %loop.header
245 loop.header:
246   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
247   %gep = getelementptr i32, ptr %ptr, i64 %iv
248   %l = load i32, ptr %gep
249   %iv.next = add nuw nsw i64 %iv, 1
250   %ec = icmp eq i64 %iv.next, 1000
251   br i1 %ec, label %exit, label %loop.latch
253 loop.latch:
254   store i32 10, ptr %gep
255   br label %loop.header
257 exit:
258   %res.lcssa = phi i32 [ %l, %loop.header ]
259   ret i32 %res.lcssa
262 ; Same as early_exit, but with optsize to prevent the use of
263 ; a scalar epilogue.  -- Can't vectorize this in either case.
264 define void @optsize(ptr %p, i32 %n) optsize {
265 ; CHECK-LABEL: @optsize(
266 ; CHECK-NEXT:  entry:
267 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
268 ; CHECK:       for.cond:
269 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
270 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
271 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
272 ; CHECK:       for.body:
273 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
274 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
275 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
276 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
277 ; CHECK-NEXT:    br label [[FOR_COND]]
278 ; CHECK:       if.end:
279 ; CHECK-NEXT:    ret void
281 ; TAILFOLD-LABEL: @optsize(
282 ; TAILFOLD-NEXT:  entry:
283 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
284 ; TAILFOLD:       for.cond:
285 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
286 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
287 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
288 ; TAILFOLD:       for.body:
289 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
290 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
291 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
292 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
293 ; TAILFOLD-NEXT:    br label [[FOR_COND]]
294 ; TAILFOLD:       if.end:
295 ; TAILFOLD-NEXT:    ret void
297 entry:
298   br label %for.cond
300 for.cond:
301   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
302   %cmp = icmp slt i32 %i, %n
303   br i1 %cmp, label %for.body, label %if.end
305 for.body:
306   %iprom = sext i32 %i to i64
307   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
308   store i16 0, ptr %b, align 4
309   %inc = add nsw i32 %i, 1
310   br label %for.cond
312 if.end:
313   ret void
317 ; multiple exit - no values inside the loop used outside
318 define void @multiple_unique_exit(ptr %p, i32 %n) {
319 ; CHECK-LABEL: @multiple_unique_exit(
320 ; CHECK-NEXT:  entry:
321 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
322 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
323 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
324 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
325 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
326 ; CHECK:       vector.ph:
327 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
328 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
329 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
330 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
331 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
332 ; CHECK:       vector.body:
333 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
334 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
335 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
336 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
337 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
338 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
339 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
340 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
341 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
342 ; CHECK:       middle.block:
343 ; CHECK-NEXT:    br label [[SCALAR_PH]]
344 ; CHECK:       scalar.ph:
345 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
346 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
347 ; CHECK:       for.cond:
348 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
349 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
350 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
351 ; CHECK:       for.body:
352 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
353 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
354 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
355 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
356 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
357 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP9:![0-9]+]]
358 ; CHECK:       if.end:
359 ; CHECK-NEXT:    ret void
361 ; TAILFOLD-LABEL: @multiple_unique_exit(
362 ; TAILFOLD-NEXT:  entry:
363 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
364 ; TAILFOLD:       for.cond:
365 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
366 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
367 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
368 ; TAILFOLD:       for.body:
369 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
370 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
371 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
372 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
373 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
374 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
375 ; TAILFOLD:       if.end:
376 ; TAILFOLD-NEXT:    ret void
378 entry:
379   br label %for.cond
381 for.cond:
382   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
383   %cmp = icmp slt i32 %i, %n
384   br i1 %cmp, label %for.body, label %if.end
386 for.body:
387   %iprom = sext i32 %i to i64
388   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
389   store i16 0, ptr %b, align 4
390   %inc = add nsw i32 %i, 1
391   %cmp2 = icmp slt i32 %i, 2096
392   br i1 %cmp2, label %for.cond, label %if.end
394 if.end:
395   ret void
398 ; multiple exit - with an lcssa phi
399 define i32 @multiple_unique_exit2(ptr %p, i32 %n) {
400 ; CHECK-LABEL: @multiple_unique_exit2(
401 ; CHECK-NEXT:  entry:
402 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
403 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
404 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
405 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
406 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
407 ; CHECK:       vector.ph:
408 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
409 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
410 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
411 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
412 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
413 ; CHECK:       vector.body:
414 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
415 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
416 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
417 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
418 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
419 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
420 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
421 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
422 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
423 ; CHECK:       middle.block:
424 ; CHECK-NEXT:    br label [[SCALAR_PH]]
425 ; CHECK:       scalar.ph:
426 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
427 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
428 ; CHECK:       for.cond:
429 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
430 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
431 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
432 ; CHECK:       for.body:
433 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
434 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
435 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
436 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
437 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
438 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP11:![0-9]+]]
439 ; CHECK:       if.end:
440 ; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ], [ [[I]], [[FOR_COND]] ]
441 ; CHECK-NEXT:    ret i32 [[I_LCSSA]]
443 ; TAILFOLD-LABEL: @multiple_unique_exit2(
444 ; TAILFOLD-NEXT:  entry:
445 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
446 ; TAILFOLD:       for.cond:
447 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
448 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
449 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
450 ; TAILFOLD:       for.body:
451 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
452 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
453 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
454 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
455 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
456 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
457 ; TAILFOLD:       if.end:
458 ; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ], [ [[I]], [[FOR_COND]] ]
459 ; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
461 entry:
462   br label %for.cond
464 for.cond:
465   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
466   %cmp = icmp slt i32 %i, %n
467   br i1 %cmp, label %for.body, label %if.end
469 for.body:
470   %iprom = sext i32 %i to i64
471   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
472   store i16 0, ptr %b, align 4
473   %inc = add nsw i32 %i, 1
474   %cmp2 = icmp slt i32 %i, 2096
475   br i1 %cmp2, label %for.cond, label %if.end
477 if.end:
478   ret i32 %i
481 ; multiple exit w/a non lcssa phi
482 define i32 @multiple_unique_exit3(ptr %p, i32 %n) {
483 ; CHECK-LABEL: @multiple_unique_exit3(
484 ; CHECK-NEXT:  entry:
485 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
486 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
487 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
488 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
489 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
490 ; CHECK:       vector.ph:
491 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
492 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
493 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
494 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
495 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
496 ; CHECK:       vector.body:
497 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
498 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
499 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
500 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
501 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
502 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
503 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
504 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
505 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
506 ; CHECK:       middle.block:
507 ; CHECK-NEXT:    br label [[SCALAR_PH]]
508 ; CHECK:       scalar.ph:
509 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
510 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
511 ; CHECK:       for.cond:
512 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
513 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
514 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
515 ; CHECK:       for.body:
516 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
517 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
518 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
519 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
520 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
521 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP13:![0-9]+]]
522 ; CHECK:       if.end:
523 ; CHECK-NEXT:    [[EXIT:%.*]] = phi i32 [ 0, [[FOR_COND]] ], [ 1, [[FOR_BODY]] ]
524 ; CHECK-NEXT:    ret i32 [[EXIT]]
526 ; TAILFOLD-LABEL: @multiple_unique_exit3(
527 ; TAILFOLD-NEXT:  entry:
528 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
529 ; TAILFOLD:       for.cond:
530 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
531 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
532 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
533 ; TAILFOLD:       for.body:
534 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
535 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
536 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
537 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
538 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
539 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
540 ; TAILFOLD:       if.end:
541 ; TAILFOLD-NEXT:    [[EXIT:%.*]] = phi i32 [ 0, [[FOR_COND]] ], [ 1, [[FOR_BODY]] ]
542 ; TAILFOLD-NEXT:    ret i32 [[EXIT]]
544 entry:
545   br label %for.cond
547 for.cond:
548   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
549   %cmp = icmp slt i32 %i, %n
550   br i1 %cmp, label %for.body, label %if.end
552 for.body:
553   %iprom = sext i32 %i to i64
554   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
555   store i16 0, ptr %b, align 4
556   %inc = add nsw i32 %i, 1
557   %cmp2 = icmp slt i32 %i, 2096
558   br i1 %cmp2, label %for.cond, label %if.end
560 if.end:
561   %exit = phi i32 [0, %for.cond], [1, %for.body]
562   ret i32 %exit
565 ; multiple exits w/distinct target blocks
566 define i32 @multiple_exit_blocks(ptr %p, i32 %n) {
567 ; CHECK-LABEL: @multiple_exit_blocks(
568 ; CHECK-NEXT:  entry:
569 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
570 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
571 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
572 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
573 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
574 ; CHECK:       vector.ph:
575 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
576 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
577 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
578 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
579 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
580 ; CHECK:       vector.body:
581 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
582 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
583 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
584 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
585 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
586 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
587 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
588 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
589 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
590 ; CHECK:       middle.block:
591 ; CHECK-NEXT:    br label [[SCALAR_PH]]
592 ; CHECK:       scalar.ph:
593 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
594 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
595 ; CHECK:       for.cond:
596 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
597 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
598 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
599 ; CHECK:       for.body:
600 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
601 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
602 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
603 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
604 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
605 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP15:![0-9]+]]
606 ; CHECK:       if.end:
607 ; CHECK-NEXT:    ret i32 0
608 ; CHECK:       if.end2:
609 ; CHECK-NEXT:    ret i32 1
611 ; TAILFOLD-LABEL: @multiple_exit_blocks(
612 ; TAILFOLD-NEXT:  entry:
613 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
614 ; TAILFOLD:       for.cond:
615 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
616 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
617 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
618 ; TAILFOLD:       for.body:
619 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
620 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
621 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
622 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
623 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
624 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
625 ; TAILFOLD:       if.end:
626 ; TAILFOLD-NEXT:    ret i32 0
627 ; TAILFOLD:       if.end2:
628 ; TAILFOLD-NEXT:    ret i32 1
630 entry:
631   br label %for.cond
633 for.cond:
634   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
635   %cmp = icmp slt i32 %i, %n
636   br i1 %cmp, label %for.body, label %if.end
638 for.body:
639   %iprom = sext i32 %i to i64
640   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
641   store i16 0, ptr %b, align 4
642   %inc = add nsw i32 %i, 1
643   %cmp2 = icmp slt i32 %i, 2096
644   br i1 %cmp2, label %for.cond, label %if.end2
646 if.end:
647   ret i32 0
649 if.end2:
650   ret i32 1
653 ; LCSSA, common value each exit
654 define i32 @multiple_exit_blocks2(ptr %p, i32 %n) {
655 ; CHECK-LABEL: @multiple_exit_blocks2(
656 ; CHECK-NEXT:  entry:
657 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
658 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
659 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
660 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
661 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
662 ; CHECK:       vector.ph:
663 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
664 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
665 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
666 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
667 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
668 ; CHECK:       vector.body:
669 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
670 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
671 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
672 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
673 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
674 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
675 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
676 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
677 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
678 ; CHECK:       middle.block:
679 ; CHECK-NEXT:    br label [[SCALAR_PH]]
680 ; CHECK:       scalar.ph:
681 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
682 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
683 ; CHECK:       for.cond:
684 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
685 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
686 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
687 ; CHECK:       for.body:
688 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
689 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
690 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
691 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
692 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
693 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP17:![0-9]+]]
694 ; CHECK:       if.end:
695 ; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
696 ; CHECK-NEXT:    ret i32 [[I_LCSSA]]
697 ; CHECK:       if.end2:
698 ; CHECK-NEXT:    [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ]
699 ; CHECK-NEXT:    ret i32 [[I_LCSSA1]]
701 ; TAILFOLD-LABEL: @multiple_exit_blocks2(
702 ; TAILFOLD-NEXT:  entry:
703 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
704 ; TAILFOLD:       for.cond:
705 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
706 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
707 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
708 ; TAILFOLD:       for.body:
709 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
710 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
711 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
712 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
713 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
714 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
715 ; TAILFOLD:       if.end:
716 ; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
717 ; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
718 ; TAILFOLD:       if.end2:
719 ; TAILFOLD-NEXT:    [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ]
720 ; TAILFOLD-NEXT:    ret i32 [[I_LCSSA1]]
722 entry:
723   br label %for.cond
725 for.cond:
726   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
727   %cmp = icmp slt i32 %i, %n
728   br i1 %cmp, label %for.body, label %if.end
730 for.body:
731   %iprom = sext i32 %i to i64
732   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
733   store i16 0, ptr %b, align 4
734   %inc = add nsw i32 %i, 1
735   %cmp2 = icmp slt i32 %i, 2096
736   br i1 %cmp2, label %for.cond, label %if.end2
738 if.end:
739   ret i32 %i
741 if.end2:
742   ret i32 %i
745 ; LCSSA, distinct value each exit
746 define i32 @multiple_exit_blocks3(ptr %p, i32 %n) {
747 ; CHECK-LABEL: @multiple_exit_blocks3(
748 ; CHECK-NEXT:  entry:
749 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
750 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
751 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
752 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
753 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
754 ; CHECK:       vector.ph:
755 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
756 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
757 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
758 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
759 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
760 ; CHECK:       vector.body:
761 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
762 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
763 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
764 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[TMP4]]
765 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
766 ; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr [[TMP6]], align 4
767 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
768 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
769 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
770 ; CHECK:       middle.block:
771 ; CHECK-NEXT:    br label [[SCALAR_PH]]
772 ; CHECK:       scalar.ph:
773 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
774 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
775 ; CHECK:       for.cond:
776 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
777 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
778 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
779 ; CHECK:       for.body:
780 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
781 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 [[IPROM]]
782 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
783 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
784 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
785 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP19:![0-9]+]]
786 ; CHECK:       if.end:
787 ; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
788 ; CHECK-NEXT:    ret i32 [[I_LCSSA]]
789 ; CHECK:       if.end2:
790 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ]
791 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
793 ; TAILFOLD-LABEL: @multiple_exit_blocks3(
794 ; TAILFOLD-NEXT:  entry:
795 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
796 ; TAILFOLD:       for.cond:
797 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
798 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
799 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
800 ; TAILFOLD:       for.body:
801 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
802 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
803 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
804 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
805 ; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
806 ; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
807 ; TAILFOLD:       if.end:
808 ; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
809 ; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
810 ; TAILFOLD:       if.end2:
811 ; TAILFOLD-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ]
812 ; TAILFOLD-NEXT:    ret i32 [[INC_LCSSA]]
814 entry:
815   br label %for.cond
817 for.cond:
818   %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
819   %cmp = icmp slt i32 %i, %n
820   br i1 %cmp, label %for.body, label %if.end
822 for.body:
823   %iprom = sext i32 %i to i64
824   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
825   store i16 0, ptr %b, align 4
826   %inc = add nsw i32 %i, 1
827   %cmp2 = icmp slt i32 %i, 2096
828   br i1 %cmp2, label %for.cond, label %if.end2
830 if.end:
831   ret i32 %i
833 if.end2:
834   ret i32 %inc
837 ; unique exit case but with a switch as two edges between the same pair of
838 ; blocks is an often missed edge case
839 define i32 @multiple_exit_switch(ptr %p, i32 %n) {
840 ; CHECK-LABEL: @multiple_exit_switch(
841 ; CHECK-NEXT:  entry:
842 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
843 ; CHECK:       for.cond:
844 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
845 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
846 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
847 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
848 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
849 ; CHECK-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
850 ; CHECK-NEXT:      i32 2096, label [[IF_END:%.*]]
851 ; CHECK-NEXT:      i32 2097, label [[IF_END]]
852 ; CHECK-NEXT:    ]
853 ; CHECK:       if.end:
854 ; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ], [ [[I]], [[FOR_COND]] ]
855 ; CHECK-NEXT:    ret i32 [[I_LCSSA]]
857 ; TAILFOLD-LABEL: @multiple_exit_switch(
858 ; TAILFOLD-NEXT:  entry:
859 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
860 ; TAILFOLD:       for.cond:
861 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
862 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
863 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
864 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
865 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
866 ; TAILFOLD-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
867 ; TAILFOLD-NEXT:      i32 2096, label [[IF_END:%.*]]
868 ; TAILFOLD-NEXT:      i32 2097, label [[IF_END]]
869 ; TAILFOLD-NEXT:    ]
870 ; TAILFOLD:       if.end:
871 ; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ], [ [[I]], [[FOR_COND]] ]
872 ; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
874 entry:
875   br label %for.cond
877 for.cond:
878   %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
879   %iprom = sext i32 %i to i64
880   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
881   store i16 0, ptr %b, align 4
882   %inc = add nsw i32 %i, 1
883   switch i32 %i, label %for.cond [
884   i32 2096, label %if.end
885   i32 2097, label %if.end
886   ]
888 if.end:
889   ret i32 %i
892 ; multiple exit case but with a switch as multiple exiting edges from
893 ; a single block is a commonly missed edge case
894 define i32 @multiple_exit_switch2(ptr %p, i32 %n) {
895 ; CHECK-LABEL: @multiple_exit_switch2(
896 ; CHECK-NEXT:  entry:
897 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
898 ; CHECK:       for.cond:
899 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
900 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
901 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
902 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
903 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
904 ; CHECK-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
905 ; CHECK-NEXT:      i32 2096, label [[IF_END:%.*]]
906 ; CHECK-NEXT:      i32 2097, label [[IF_END2:%.*]]
907 ; CHECK-NEXT:    ]
908 ; CHECK:       if.end:
909 ; CHECK-NEXT:    ret i32 0
910 ; CHECK:       if.end2:
911 ; CHECK-NEXT:    ret i32 1
913 ; TAILFOLD-LABEL: @multiple_exit_switch2(
914 ; TAILFOLD-NEXT:  entry:
915 ; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
916 ; TAILFOLD:       for.cond:
917 ; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
918 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
919 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
920 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
921 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
922 ; TAILFOLD-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
923 ; TAILFOLD-NEXT:      i32 2096, label [[IF_END:%.*]]
924 ; TAILFOLD-NEXT:      i32 2097, label [[IF_END2:%.*]]
925 ; TAILFOLD-NEXT:    ]
926 ; TAILFOLD:       if.end:
927 ; TAILFOLD-NEXT:    ret i32 0
928 ; TAILFOLD:       if.end2:
929 ; TAILFOLD-NEXT:    ret i32 1
931 entry:
932   br label %for.cond
934 for.cond:
935   %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
936   %iprom = sext i32 %i to i64
937   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
938   store i16 0, ptr %b, align 4
939   %inc = add nsw i32 %i, 1
940   switch i32 %i, label %for.cond [
941   i32 2096, label %if.end
942   i32 2097, label %if.end2
943   ]
945 if.end:
946   ret i32 0
948 if.end2:
949   ret i32 1
952 define i32 @multiple_latch1(ptr %p) {
953 ; CHECK-LABEL: @multiple_latch1(
954 ; CHECK-NEXT:  entry:
955 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
956 ; CHECK:       for.body:
957 ; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
958 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
959 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
960 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
961 ; CHECK:       for.second:
962 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
963 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
964 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
965 ; CHECK-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
966 ; CHECK-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
967 ; CHECK:       for.body.backedge:
968 ; CHECK-NEXT:    br label [[FOR_BODY]]
969 ; CHECK:       for.end:
970 ; CHECK-NEXT:    ret i32 0
972 ; TAILFOLD-LABEL: @multiple_latch1(
973 ; TAILFOLD-NEXT:  entry:
974 ; TAILFOLD-NEXT:    br label [[FOR_BODY:%.*]]
975 ; TAILFOLD:       for.body:
976 ; TAILFOLD-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
977 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
978 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
979 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
980 ; TAILFOLD:       for.second:
981 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
982 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
983 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
984 ; TAILFOLD-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
985 ; TAILFOLD-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
986 ; TAILFOLD:       for.body.backedge:
987 ; TAILFOLD-NEXT:    br label [[FOR_BODY]]
988 ; TAILFOLD:       for.end:
989 ; TAILFOLD-NEXT:    ret i32 0
991 entry:
992   br label %for.body
994 for.body:
995   %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body.backedge]
996   %inc = add nsw i32 %i.02, 1
997   %cmp = icmp slt i32 %inc, 16
998   br i1 %cmp, label %for.body.backedge, label %for.second
1000 for.second:
1001   %iprom = sext i32 %i.02 to i64
1002   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
1003   store i16 0, ptr %b, align 4
1004   %cmps = icmp sgt i32 %inc, 16
1005   br i1 %cmps, label %for.body.backedge, label %for.end
1007 for.body.backedge:
1008   br label %for.body
1010 for.end:
1011   ret i32 0
1015 ; two back branches - loop simplify with convert this to the same form
1016 ; as previous before vectorizer sees it, but show that.
1017 define i32 @multiple_latch2(ptr %p) {
1018 ; CHECK-LABEL: @multiple_latch2(
1019 ; CHECK-NEXT:  entry:
1020 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1021 ; CHECK:       for.body:
1022 ; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
1023 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
1024 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
1025 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
1026 ; CHECK:       for.body.backedge:
1027 ; CHECK-NEXT:    br label [[FOR_BODY]]
1028 ; CHECK:       for.second:
1029 ; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
1030 ; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
1031 ; CHECK-NEXT:    store i16 0, ptr [[B]], align 4
1032 ; CHECK-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
1033 ; CHECK-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
1034 ; CHECK:       for.end:
1035 ; CHECK-NEXT:    ret i32 0
1037 ; TAILFOLD-LABEL: @multiple_latch2(
1038 ; TAILFOLD-NEXT:  entry:
1039 ; TAILFOLD-NEXT:    br label [[FOR_BODY:%.*]]
1040 ; TAILFOLD:       for.body:
1041 ; TAILFOLD-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
1042 ; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
1043 ; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
1044 ; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
1045 ; TAILFOLD:       for.body.backedge:
1046 ; TAILFOLD-NEXT:    br label [[FOR_BODY]]
1047 ; TAILFOLD:       for.second:
1048 ; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
1049 ; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 [[IPROM]]
1050 ; TAILFOLD-NEXT:    store i16 0, ptr [[B]], align 4
1051 ; TAILFOLD-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
1052 ; TAILFOLD-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
1053 ; TAILFOLD:       for.end:
1054 ; TAILFOLD-NEXT:    ret i32 0
1056 entry:
1057   br label %for.body
1059 for.body:
1060   %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ], [%inc, %for.second]
1061   %inc = add nsw i32 %i.02, 1
1062   %cmp = icmp slt i32 %inc, 16
1063   br i1 %cmp, label %for.body, label %for.second
1065 for.second:
1066   %iprom = sext i32 %i.02 to i64
1067   %b = getelementptr inbounds i16, ptr %p, i64 %iprom
1068   store i16 0, ptr %b, align 4
1069   %cmps = icmp sgt i32 %inc, 16
1070   br i1 %cmps, label %for.body, label %for.end
1072 for.end:
1073   ret i32 0
1077 ; Check interaction between block predication and early exits.  We need the
1078 ; condition on the early exit to remain dead (i.e. not be used when forming
1079 ; the predicate mask).
1080 define void @scalar_predication(ptr %addr) {
1081 ; CHECK-LABEL: @scalar_predication(
1082 ; CHECK-NEXT:  entry:
1083 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1084 ; CHECK:       vector.ph:
1085 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1086 ; CHECK:       vector.body:
1087 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
1088 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
1089 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr float, ptr [[ADDR:%.*]], i64 [[TMP0]]
1090 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr float, ptr [[TMP1]], i32 0
1091 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP2]], align 4
1092 ; CHECK-NEXT:    [[TMP3:%.*]] = fcmp oeq <2 x float> [[WIDE_LOAD]], zeroinitializer
1093 ; CHECK-NEXT:    [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1094 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1095 ; CHECK-NEXT:    br i1 [[TMP5]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
1096 ; CHECK:       pred.store.if:
1097 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr float, ptr [[ADDR]], i64 [[TMP0]]
1098 ; CHECK-NEXT:    store float 1.000000e+01, ptr [[TMP6]], align 4
1099 ; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
1100 ; CHECK:       pred.store.continue:
1101 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1102 ; CHECK-NEXT:    br i1 [[TMP7]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
1103 ; CHECK:       pred.store.if1:
1104 ; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[INDEX]], 1
1105 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr float, ptr [[ADDR]], i64 [[TMP8]]
1106 ; CHECK-NEXT:    store float 1.000000e+01, ptr [[TMP9]], align 4
1107 ; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE2]]
1108 ; CHECK:       pred.store.continue2:
1109 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1110 ; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
1111 ; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
1112 ; CHECK:       middle.block:
1113 ; CHECK-NEXT:    br label [[SCALAR_PH]]
1114 ; CHECK:       scalar.ph:
1115 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1116 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1117 ; CHECK:       loop.header:
1118 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1119 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr float, ptr [[ADDR]], i64 [[IV]]
1120 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1121 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]
1122 ; CHECK:       loop.body:
1123 ; CHECK-NEXT:    [[TMP11:%.*]] = load float, ptr [[GEP]], align 4
1124 ; CHECK-NEXT:    [[PRED:%.*]] = fcmp oeq float [[TMP11]], 0.000000e+00
1125 ; CHECK-NEXT:    br i1 [[PRED]], label [[LOOP_LATCH]], label [[THEN:%.*]]
1126 ; CHECK:       then:
1127 ; CHECK-NEXT:    store float 1.000000e+01, ptr [[GEP]], align 4
1128 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
1129 ; CHECK:       loop.latch:
1130 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1131 ; CHECK-NEXT:    br label [[LOOP_HEADER]], !llvm.loop [[LOOP21:![0-9]+]]
1132 ; CHECK:       exit:
1133 ; CHECK-NEXT:    ret void
1135 ; TAILFOLD-LABEL: @scalar_predication(
1136 ; TAILFOLD-NEXT:  entry:
1137 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
1138 ; TAILFOLD:       loop.header:
1139 ; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1140 ; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr float, ptr [[ADDR:%.*]], i64 [[IV]]
1141 ; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1142 ; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]
1143 ; TAILFOLD:       loop.body:
1144 ; TAILFOLD-NEXT:    [[TMP0:%.*]] = load float, ptr [[GEP]], align 4
1145 ; TAILFOLD-NEXT:    [[PRED:%.*]] = fcmp oeq float [[TMP0]], 0.000000e+00
1146 ; TAILFOLD-NEXT:    br i1 [[PRED]], label [[LOOP_LATCH]], label [[THEN:%.*]]
1147 ; TAILFOLD:       then:
1148 ; TAILFOLD-NEXT:    store float 1.000000e+01, ptr [[GEP]], align 4
1149 ; TAILFOLD-NEXT:    br label [[LOOP_LATCH]]
1150 ; TAILFOLD:       loop.latch:
1151 ; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1152 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
1153 ; TAILFOLD:       exit:
1154 ; TAILFOLD-NEXT:    ret void
1156 entry:
1157   br label %loop.header
1159 loop.header:
1160   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1161   %gep = getelementptr float, ptr %addr, i64 %iv
1162   %exitcond.not = icmp eq i64 %iv, 200
1163   br i1 %exitcond.not, label %exit, label %loop.body
1165 loop.body:
1166   %0 = load float, ptr %gep, align 4
1167   %pred = fcmp oeq float %0, 0.0
1168   br i1 %pred, label %loop.latch, label %then
1170 then:
1171   store float 10.0, ptr %gep, align 4
1172   br label %loop.latch
1174 loop.latch:
1175   %iv.next = add nuw nsw i64 %iv, 1
1176   br label %loop.header
1178 exit:
1179   ret void
1182 define i32 @me_reduction(ptr %addr) {
1183 ; CHECK-LABEL: @me_reduction(
1184 ; CHECK-NEXT:  entry:
1185 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1186 ; CHECK:       vector.ph:
1187 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1188 ; CHECK:       vector.body:
1189 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1190 ; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <2 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[VECTOR_BODY]] ]
1191 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
1192 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[ADDR:%.*]], i64 [[TMP0]]
1193 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, ptr [[TMP1]], i32 0
1194 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1195 ; CHECK-NEXT:    [[TMP3]] = add <2 x i32> [[VEC_PHI]], [[WIDE_LOAD]]
1196 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1197 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
1198 ; CHECK-NEXT:    br i1 [[TMP4]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
1199 ; CHECK:       middle.block:
1200 ; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[TMP3]])
1201 ; CHECK-NEXT:    br label [[SCALAR_PH]]
1202 ; CHECK:       scalar.ph:
1203 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1204 ; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP5]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
1205 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1206 ; CHECK:       loop.header:
1207 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1208 ; CHECK-NEXT:    [[ACCUM:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
1209 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[ADDR]], i64 [[IV]]
1210 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1211 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
1212 ; CHECK:       loop.latch:
1213 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[GEP]], align 4
1214 ; CHECK-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP6]]
1215 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1216 ; CHECK-NEXT:    [[EXITCOND2_NOT:%.*]] = icmp eq i64 [[IV]], 400
1217 ; CHECK-NEXT:    br i1 [[EXITCOND2_NOT]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP23:![0-9]+]]
1218 ; CHECK:       exit:
1219 ; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ 0, [[LOOP_HEADER]] ], [ [[ACCUM_NEXT]], [[LOOP_LATCH]] ]
1220 ; CHECK-NEXT:    ret i32 [[LCSSA]]
1222 ; TAILFOLD-LABEL: @me_reduction(
1223 ; TAILFOLD-NEXT:  entry:
1224 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
1225 ; TAILFOLD:       loop.header:
1226 ; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1227 ; TAILFOLD-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
1228 ; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[ADDR:%.*]], i64 [[IV]]
1229 ; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1230 ; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
1231 ; TAILFOLD:       loop.latch:
1232 ; TAILFOLD-NEXT:    [[TMP0:%.*]] = load i32, ptr [[GEP]], align 4
1233 ; TAILFOLD-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
1234 ; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1235 ; TAILFOLD-NEXT:    [[EXITCOND2_NOT:%.*]] = icmp eq i64 [[IV]], 400
1236 ; TAILFOLD-NEXT:    br i1 [[EXITCOND2_NOT]], label [[EXIT]], label [[LOOP_HEADER]]
1237 ; TAILFOLD:       exit:
1238 ; TAILFOLD-NEXT:    [[LCSSA:%.*]] = phi i32 [ 0, [[LOOP_HEADER]] ], [ [[ACCUM_NEXT]], [[LOOP_LATCH]] ]
1239 ; TAILFOLD-NEXT:    ret i32 [[LCSSA]]
1241 entry:
1242   br label %loop.header
1244 loop.header:
1245   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1246   %accum = phi i32 [0, %entry], [%accum.next, %loop.latch]
1247   %gep = getelementptr i32, ptr %addr, i64 %iv
1248   %exitcond.not = icmp eq i64 %iv, 200
1249   br i1 %exitcond.not, label %exit, label %loop.latch
1251 loop.latch:
1252   %0 = load i32, ptr %gep, align 4
1253   %accum.next = add i32 %accum, %0
1254   %iv.next = add nuw nsw i64 %iv, 1
1255   %exitcond2.not = icmp eq i64 %iv, 400
1256   br i1 %exitcond2.not, label %exit, label %loop.header
1258 exit:
1259   %lcssa = phi i32 [0, %loop.header], [%accum.next, %loop.latch]
1260   ret i32 %lcssa
1263 ; TODO: The current definition of reduction is too strict, we can vectorize
1264 ; this.  There's an analogous single exit case where we extract the N-1
1265 ; value of the reduction that we can also handle.  If we fix the later, the
1266 ; multiple exit case probably falls out.
1267 define i32 @me_reduction2(ptr %addr) {
1268 ; CHECK-LABEL: @me_reduction2(
1269 ; CHECK-NEXT:  entry:
1270 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1271 ; CHECK:       loop.header:
1272 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1273 ; CHECK-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
1274 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[ADDR:%.*]], i64 [[IV]]
1275 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1276 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
1277 ; CHECK:       loop.latch:
1278 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[GEP]], align 4
1279 ; CHECK-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
1280 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1281 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
1282 ; CHECK:       exit:
1283 ; CHECK-NEXT:    [[ACCUM_LCSSA:%.*]] = phi i32 [ [[ACCUM]], [[LOOP_HEADER]] ]
1284 ; CHECK-NEXT:    ret i32 [[ACCUM_LCSSA]]
1286 ; TAILFOLD-LABEL: @me_reduction2(
1287 ; TAILFOLD-NEXT:  entry:
1288 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
1289 ; TAILFOLD:       loop.header:
1290 ; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
1291 ; TAILFOLD-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
1292 ; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[ADDR:%.*]], i64 [[IV]]
1293 ; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
1294 ; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
1295 ; TAILFOLD:       loop.latch:
1296 ; TAILFOLD-NEXT:    [[TMP0:%.*]] = load i32, ptr [[GEP]], align 4
1297 ; TAILFOLD-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
1298 ; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1299 ; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
1300 ; TAILFOLD:       exit:
1301 ; TAILFOLD-NEXT:    [[ACCUM_LCSSA:%.*]] = phi i32 [ [[ACCUM]], [[LOOP_HEADER]] ]
1302 ; TAILFOLD-NEXT:    ret i32 [[ACCUM_LCSSA]]
1304 entry:
1305   br label %loop.header
1307 loop.header:
1308   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1309   %accum = phi i32 [0, %entry], [%accum.next, %loop.latch]
1310   %gep = getelementptr i32, ptr %addr, i64 %iv
1311   %exitcond.not = icmp eq i64 %iv, 200
1312   br i1 %exitcond.not, label %exit, label %loop.latch
1314 loop.latch:
1315   %0 = load i32, ptr %gep, align 4
1316   %accum.next = add i32 %accum, %0
1317   %iv.next = add nuw nsw i64 %iv, 1
1318   br label %loop.header
1320 exit:
1321   ret i32 %accum