199ac8868SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2a048e2faSPhilip Reames; RUN: opt -S -loop-vectorize -force-vector-width=2 < %s | FileCheck %s
34b33b238SPhilip Reames; RUN: opt -S -loop-vectorize -force-vector-width=2  -prefer-predicate-over-epilogue=predicate-dont-vectorize < %s | FileCheck --check-prefix TAILFOLD %s
44b33b238SPhilip Reames
5cee313d2SEric Christophertarget datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6cee313d2SEric Christopher
799ac8868SPhilip Reamesdefine void @bottom_tested(i16* %p, i32 %n) {
899ac8868SPhilip Reames; CHECK-LABEL: @bottom_tested(
999ac8868SPhilip Reames; CHECK-NEXT:  entry:
10b46c085dSRoman Lebedev; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
11b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
12b46c085dSRoman Lebedev; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 2
1399ac8868SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1499ac8868SPhilip Reames; CHECK:       vector.ph:
15b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
16b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[N_MOD_VF]]
1799ac8868SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1899ac8868SPhilip Reames; CHECK:       vector.body:
1999ac8868SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
20b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
21b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
22b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP2]]
23b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i32 0
24b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP5:%.*]] = bitcast i16* [[TMP4]] to <2 x i16>*
25b46c085dSRoman Lebedev; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP5]], align 4
2623c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
27b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
2872314466SPhilip Reames; CHECK-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
2999ac8868SPhilip Reames; CHECK:       middle.block:
30b46c085dSRoman Lebedev; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i32 [[TMP0]], [[N_VEC]]
3199ac8868SPhilip Reames; CHECK-NEXT:    br i1 [[CMP_N]], label [[IF_END:%.*]], label [[SCALAR_PH]]
3299ac8868SPhilip Reames; CHECK:       scalar.ph:
3399ac8868SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
3499ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
3599ac8868SPhilip Reames; CHECK:       for.cond:
3699ac8868SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_COND]] ]
3799ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
3899ac8868SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
3999ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
4099ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
4199ac8868SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
4272314466SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP2:![0-9]+]]
4399ac8868SPhilip Reames; CHECK:       if.end:
4499ac8868SPhilip Reames; CHECK-NEXT:    ret void
45cee313d2SEric Christopher;
464b33b238SPhilip Reames; TAILFOLD-LABEL: @bottom_tested(
474b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
48b46c085dSRoman Lebedev; TAILFOLD-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
49b46c085dSRoman Lebedev; TAILFOLD-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
504b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
514b33b238SPhilip Reames; TAILFOLD:       vector.ph:
52b46c085dSRoman Lebedev; TAILFOLD-NEXT:    [[N_RND_UP:%.*]] = add i32 [[TMP0]], 1
534b33b238SPhilip Reames; TAILFOLD-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 2
544b33b238SPhilip Reames; TAILFOLD-NEXT:    [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]
55b46c085dSRoman Lebedev; TAILFOLD-NEXT:    [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP0]], 1
56278aa65cSJuneyoung Lee; TAILFOLD-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i32 0
57278aa65cSJuneyoung Lee; TAILFOLD-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i32> [[BROADCAST_SPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
584b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[VECTOR_BODY:%.*]]
594b33b238SPhilip Reames; TAILFOLD:       vector.body:
604b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
614b33b238SPhilip Reames; TAILFOLD-NEXT:    [[VEC_IND:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE2]] ]
62c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP1:%.*]] = icmp ule <2 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
63c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[VEC_IND]] to <2 x i64>
64c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP3:%.*]] = extractelement <2 x i1> [[TMP1]], i32 0
65c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    br i1 [[TMP3]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
664b33b238SPhilip Reames; TAILFOLD:       pred.store.if:
67c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
68c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
69c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    store i16 0, i16* [[TMP5]], align 4
704b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[PRED_STORE_CONTINUE]]
714b33b238SPhilip Reames; TAILFOLD:       pred.store.continue:
72c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP6:%.*]] = extractelement <2 x i1> [[TMP1]], i32 1
73c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    br i1 [[TMP6]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
744b33b238SPhilip Reames; TAILFOLD:       pred.store.if1:
75c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP7:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
76c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[TMP7]]
77c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    store i16 0, i16* [[TMP8]], align 4
784b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[PRED_STORE_CONTINUE2]]
794b33b238SPhilip Reames; TAILFOLD:       pred.store.continue2:
804b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 2
814b33b238SPhilip Reames; TAILFOLD-NEXT:    [[VEC_IND_NEXT]] = add <2 x i32> [[VEC_IND]], <i32 2, i32 2>
82c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
83c230ab6dSFlorian Hahn; TAILFOLD-NEXT:    br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
844b33b238SPhilip Reames; TAILFOLD:       middle.block:
854b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 true, label [[IF_END:%.*]], label [[SCALAR_PH]]
864b33b238SPhilip Reames; TAILFOLD:       scalar.ph:
874b33b238SPhilip Reames; TAILFOLD-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
884b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
894b33b238SPhilip Reames; TAILFOLD:       for.cond:
904b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_COND]] ]
914b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
924b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
934b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
944b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
954b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
9672314466SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP2:![0-9]+]]
974b33b238SPhilip Reames; TAILFOLD:       if.end:
984b33b238SPhilip Reames; TAILFOLD-NEXT:    ret void
994b33b238SPhilip Reames;
10099ac8868SPhilip Reamesentry:
10199ac8868SPhilip Reames  br label %for.cond
102cee313d2SEric Christopher
10399ac8868SPhilip Reamesfor.cond:
10499ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
10599ac8868SPhilip Reames  %iprom = sext i32 %i to i64
10699ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
10799ac8868SPhilip Reames  store i16 0, i16* %b, align 4
10899ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
10999ac8868SPhilip Reames  %cmp = icmp slt i32 %i, %n
11099ac8868SPhilip Reames  br i1 %cmp, label %for.cond, label %if.end
111cee313d2SEric Christopher
11299ac8868SPhilip Reamesif.end:
11399ac8868SPhilip Reames  ret void
11499ac8868SPhilip Reames}
11599ac8868SPhilip Reames
11699ac8868SPhilip Reamesdefine void @early_exit(i16* %p, i32 %n) {
11799ac8868SPhilip Reames; CHECK-LABEL: @early_exit(
11899ac8868SPhilip Reames; CHECK-NEXT:  entry:
119b46c085dSRoman Lebedev; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
120b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
121b46c085dSRoman Lebedev; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
1224b33b238SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1234b33b238SPhilip Reames; CHECK:       vector.ph:
124b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
125b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
126b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
127b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
1284b33b238SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1294b33b238SPhilip Reames; CHECK:       vector.body:
1304b33b238SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
131b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
132c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
133c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
134c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
135c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
136c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
13723c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
138c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
139c230ab6dSFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
1404b33b238SPhilip Reames; CHECK:       middle.block:
14172314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
1424b33b238SPhilip Reames; CHECK:       scalar.ph:
1434b33b238SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1444b33b238SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
1454b33b238SPhilip Reames; CHECK:       for.cond:
1464b33b238SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
1474b33b238SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
14872314466SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
1494b33b238SPhilip Reames; CHECK:       for.body:
1504b33b238SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
1514b33b238SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
1524b33b238SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
1534b33b238SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
15472314466SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
1554b33b238SPhilip Reames; CHECK:       if.end:
1564b33b238SPhilip Reames; CHECK-NEXT:    ret void
1574b33b238SPhilip Reames;
1584b33b238SPhilip Reames; TAILFOLD-LABEL: @early_exit(
1594b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
1604b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
1614b33b238SPhilip Reames; TAILFOLD:       for.cond:
1624b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
1634b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
1644b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
1654b33b238SPhilip Reames; TAILFOLD:       for.body:
1664b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
1674b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
1684b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
1694b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
1704b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND]]
1714b33b238SPhilip Reames; TAILFOLD:       if.end:
1724b33b238SPhilip Reames; TAILFOLD-NEXT:    ret void
1734b33b238SPhilip Reames;
1744b33b238SPhilip Reamesentry:
1754b33b238SPhilip Reames  br label %for.cond
1764b33b238SPhilip Reames
1774b33b238SPhilip Reamesfor.cond:
1784b33b238SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1794b33b238SPhilip Reames  %cmp = icmp slt i32 %i, %n
1804b33b238SPhilip Reames  br i1 %cmp, label %for.body, label %if.end
1814b33b238SPhilip Reames
1824b33b238SPhilip Reamesfor.body:
1834b33b238SPhilip Reames  %iprom = sext i32 %i to i64
1844b33b238SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
1854b33b238SPhilip Reames  store i16 0, i16* %b, align 4
1864b33b238SPhilip Reames  %inc = add nsw i32 %i, 1
1874b33b238SPhilip Reames  br label %for.cond
1884b33b238SPhilip Reames
1894b33b238SPhilip Reamesif.end:
1904b33b238SPhilip Reames  ret void
1914b33b238SPhilip Reames}
1924b33b238SPhilip Reames
193145fe571SFlorian Hahndefine i32 @early_exit_with_live_out(i32* %ptr) {
194145fe571SFlorian Hahn; CHECK-LABEL: @early_exit_with_live_out(
195145fe571SFlorian Hahn; CHECK-NEXT:  entry:
196145fe571SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
197145fe571SFlorian Hahn; CHECK:       vector.ph:
198145fe571SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
199145fe571SFlorian Hahn; CHECK:       vector.body:
200145fe571SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
201145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
202145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 [[TMP0]]
203145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, i32* [[TMP1]], i32 0
204145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <2 x i32>*
205145fe571SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i32>, <2 x i32>* [[TMP3]], align 4
206145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP2]] to <2 x i32>*
207145fe571SFlorian Hahn; CHECK-NEXT:    store <2 x i32> <i32 10, i32 10>, <2 x i32>* [[TMP4]], align 4
208145fe571SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
209145fe571SFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 998
210145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
211145fe571SFlorian Hahn; CHECK:       middle.block:
212145fe571SFlorian Hahn; CHECK-NEXT:    br label [[SCALAR_PH]]
213145fe571SFlorian Hahn; CHECK:       scalar.ph:
214145fe571SFlorian Hahn; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 998, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
215145fe571SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
216145fe571SFlorian Hahn; CHECK:       loop.header:
217145fe571SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
218145fe571SFlorian Hahn; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[PTR]], i64 [[IV]]
219145fe571SFlorian Hahn; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[GEP]], align 4
220145fe571SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
221145fe571SFlorian Hahn; CHECK-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
222145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
223145fe571SFlorian Hahn; CHECK:       loop.latch:
224145fe571SFlorian Hahn; CHECK-NEXT:    store i32 10, i32* [[GEP]], align 4
225145fe571SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]], !llvm.loop [[LOOP7:![0-9]+]]
226145fe571SFlorian Hahn; CHECK:       exit:
227145fe571SFlorian Hahn; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[L]], [[LOOP_HEADER]] ]
228145fe571SFlorian Hahn; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
229145fe571SFlorian Hahn;
230145fe571SFlorian Hahn; TAILFOLD-LABEL: @early_exit_with_live_out(
231145fe571SFlorian Hahn; TAILFOLD-NEXT:  entry:
232145fe571SFlorian Hahn; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
233145fe571SFlorian Hahn; TAILFOLD:       loop.header:
234145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
235145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 [[IV]]
236145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[L:%.*]] = load i32, i32* [[GEP]], align 4
237145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
238145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
239145fe571SFlorian Hahn; TAILFOLD-NEXT:    br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
240145fe571SFlorian Hahn; TAILFOLD:       loop.latch:
241145fe571SFlorian Hahn; TAILFOLD-NEXT:    store i32 10, i32* [[GEP]], align 4
242145fe571SFlorian Hahn; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
243145fe571SFlorian Hahn; TAILFOLD:       exit:
244145fe571SFlorian Hahn; TAILFOLD-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[L]], [[LOOP_HEADER]] ]
245145fe571SFlorian Hahn; TAILFOLD-NEXT:    ret i32 [[RES_LCSSA]]
246145fe571SFlorian Hahn;
247145fe571SFlorian Hahnentry:
248145fe571SFlorian Hahn  br label %loop.header
249145fe571SFlorian Hahn
250145fe571SFlorian Hahnloop.header:
251145fe571SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
252145fe571SFlorian Hahn  %gep = getelementptr i32, i32* %ptr, i64 %iv
253145fe571SFlorian Hahn  %l = load i32, i32* %gep
254145fe571SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
255145fe571SFlorian Hahn  %ec = icmp eq i64 %iv.next, 1000
256145fe571SFlorian Hahn  br i1 %ec, label %exit, label %loop.latch
257145fe571SFlorian Hahn
258145fe571SFlorian Hahnloop.latch:
259145fe571SFlorian Hahn  store i32 10, i32* %gep
260145fe571SFlorian Hahn  br label %loop.header
261145fe571SFlorian Hahn
262145fe571SFlorian Hahnexit:
263145fe571SFlorian Hahn  %res.lcssa = phi i32 [ %l, %loop.header ]
264145fe571SFlorian Hahn  ret i32 %res.lcssa
265145fe571SFlorian Hahn}
266145fe571SFlorian Hahn
2674b33b238SPhilip Reames; Same as early_exit, but with optsize to prevent the use of
2684b33b238SPhilip Reames; a scalar epilogue.  -- Can't vectorize this in either case.
2694b33b238SPhilip Reamesdefine void @optsize(i16* %p, i32 %n) optsize {
2704b33b238SPhilip Reames; CHECK-LABEL: @optsize(
2714b33b238SPhilip Reames; CHECK-NEXT:  entry:
27299ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
27399ac8868SPhilip Reames; CHECK:       for.cond:
27499ac8868SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
27599ac8868SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
27699ac8868SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
27799ac8868SPhilip Reames; CHECK:       for.body:
27899ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
27999ac8868SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
28099ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
28199ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
28299ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND]]
28399ac8868SPhilip Reames; CHECK:       if.end:
28499ac8868SPhilip Reames; CHECK-NEXT:    ret void
28599ac8868SPhilip Reames;
2864b33b238SPhilip Reames; TAILFOLD-LABEL: @optsize(
2874b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
2884b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
2894b33b238SPhilip Reames; TAILFOLD:       for.cond:
2904b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
2914b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
2924b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
2934b33b238SPhilip Reames; TAILFOLD:       for.body:
2944b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
2954b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
2964b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
2974b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
2984b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND]]
2994b33b238SPhilip Reames; TAILFOLD:       if.end:
3004b33b238SPhilip Reames; TAILFOLD-NEXT:    ret void
3014b33b238SPhilip Reames;
302cee313d2SEric Christopherentry:
303cee313d2SEric Christopher  br label %for.cond
304cee313d2SEric Christopher
305cee313d2SEric Christopherfor.cond:
306cee313d2SEric Christopher  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
307cee313d2SEric Christopher  %cmp = icmp slt i32 %i, %n
308cee313d2SEric Christopher  br i1 %cmp, label %for.body, label %if.end
309cee313d2SEric Christopher
310cee313d2SEric Christopherfor.body:
311cee313d2SEric Christopher  %iprom = sext i32 %i to i64
31299ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
313cee313d2SEric Christopher  store i16 0, i16* %b, align 4
314cee313d2SEric Christopher  %inc = add nsw i32 %i, 1
315cee313d2SEric Christopher  br label %for.cond
316cee313d2SEric Christopher
317cee313d2SEric Christopherif.end:
318cee313d2SEric Christopher  ret void
319cee313d2SEric Christopher}
32099ac8868SPhilip Reames
32199ac8868SPhilip Reames
32299ac8868SPhilip Reames; multiple exit - no values inside the loop used outside
32399ac8868SPhilip Reamesdefine void @multiple_unique_exit(i16* %p, i32 %n) {
32499ac8868SPhilip Reames; CHECK-LABEL: @multiple_unique_exit(
32599ac8868SPhilip Reames; CHECK-NEXT:  entry:
326b46c085dSRoman Lebedev; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
327b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
328b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
329b46c085dSRoman Lebedev; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
3304b33b238SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
3314b33b238SPhilip Reames; CHECK:       vector.ph:
332b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
333b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
334b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
335b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
3364b33b238SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
3374b33b238SPhilip Reames; CHECK:       vector.body:
3384b33b238SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
339b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
340c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
341c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
342c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
343c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
344c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
34523c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
346c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
347145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
3484b33b238SPhilip Reames; CHECK:       middle.block:
34972314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
3504b33b238SPhilip Reames; CHECK:       scalar.ph:
3514b33b238SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
35299ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
35399ac8868SPhilip Reames; CHECK:       for.cond:
3544b33b238SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
3554b33b238SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
35672314466SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
35799ac8868SPhilip Reames; CHECK:       for.body:
35899ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
3594b33b238SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
36099ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
36199ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
36299ac8868SPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
363145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP9:![0-9]+]]
36499ac8868SPhilip Reames; CHECK:       if.end:
36599ac8868SPhilip Reames; CHECK-NEXT:    ret void
36699ac8868SPhilip Reames;
3674b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_unique_exit(
3684b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
3694b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
3704b33b238SPhilip Reames; TAILFOLD:       for.cond:
3714b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
3724b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
3734b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
3744b33b238SPhilip Reames; TAILFOLD:       for.body:
3754b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
3764b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
3774b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
3784b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
3794b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
3804b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
3814b33b238SPhilip Reames; TAILFOLD:       if.end:
3824b33b238SPhilip Reames; TAILFOLD-NEXT:    ret void
3834b33b238SPhilip Reames;
38499ac8868SPhilip Reamesentry:
38599ac8868SPhilip Reames  br label %for.cond
38699ac8868SPhilip Reames
38799ac8868SPhilip Reamesfor.cond:
38899ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
38999ac8868SPhilip Reames  %cmp = icmp slt i32 %i, %n
39099ac8868SPhilip Reames  br i1 %cmp, label %for.body, label %if.end
39199ac8868SPhilip Reames
39299ac8868SPhilip Reamesfor.body:
39399ac8868SPhilip Reames  %iprom = sext i32 %i to i64
39499ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
39599ac8868SPhilip Reames  store i16 0, i16* %b, align 4
39699ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
39799ac8868SPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
39899ac8868SPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end
39999ac8868SPhilip Reames
40099ac8868SPhilip Reamesif.end:
40199ac8868SPhilip Reames  ret void
40299ac8868SPhilip Reames}
40399ac8868SPhilip Reames
40499ac8868SPhilip Reames; multiple exit - with an lcssa phi
40599ac8868SPhilip Reamesdefine i32 @multiple_unique_exit2(i16* %p, i32 %n) {
40699ac8868SPhilip Reames; CHECK-LABEL: @multiple_unique_exit2(
40799ac8868SPhilip Reames; CHECK-NEXT:  entry:
408b46c085dSRoman Lebedev; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
409b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
410b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
411b46c085dSRoman Lebedev; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
4129f61fbd7SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
4139f61fbd7SPhilip Reames; CHECK:       vector.ph:
414b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
415b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
416b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
417b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
4189f61fbd7SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
4199f61fbd7SPhilip Reames; CHECK:       vector.body:
4209f61fbd7SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
421b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
422c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
423c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
424c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
425c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
426c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
42723c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
428c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
429145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
4309f61fbd7SPhilip Reames; CHECK:       middle.block:
43172314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
4329f61fbd7SPhilip Reames; CHECK:       scalar.ph:
4339f61fbd7SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
43499ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
43599ac8868SPhilip Reames; CHECK:       for.cond:
4369f61fbd7SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
4379f61fbd7SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
43872314466SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
43999ac8868SPhilip Reames; CHECK:       for.body:
44099ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
4419f61fbd7SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
44299ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
44399ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
44499ac8868SPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
445145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP11:![0-9]+]]
44699ac8868SPhilip Reames; CHECK:       if.end:
44772314466SPhilip Reames; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ], [ [[I]], [[FOR_COND]] ]
44899ac8868SPhilip Reames; CHECK-NEXT:    ret i32 [[I_LCSSA]]
44999ac8868SPhilip Reames;
4504b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_unique_exit2(
4514b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
4524b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
4534b33b238SPhilip Reames; TAILFOLD:       for.cond:
4544b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
4554b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
4564b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
4574b33b238SPhilip Reames; TAILFOLD:       for.body:
4584b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
4594b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
4604b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
4614b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
4624b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
4634b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
4644b33b238SPhilip Reames; TAILFOLD:       if.end:
4654b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ], [ [[I]], [[FOR_COND]] ]
4664b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
4674b33b238SPhilip Reames;
46899ac8868SPhilip Reamesentry:
46999ac8868SPhilip Reames  br label %for.cond
47099ac8868SPhilip Reames
47199ac8868SPhilip Reamesfor.cond:
47299ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
47399ac8868SPhilip Reames  %cmp = icmp slt i32 %i, %n
47499ac8868SPhilip Reames  br i1 %cmp, label %for.body, label %if.end
47599ac8868SPhilip Reames
47699ac8868SPhilip Reamesfor.body:
47799ac8868SPhilip Reames  %iprom = sext i32 %i to i64
47899ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
47999ac8868SPhilip Reames  store i16 0, i16* %b, align 4
48099ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
48199ac8868SPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
48299ac8868SPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end
48399ac8868SPhilip Reames
48499ac8868SPhilip Reamesif.end:
48599ac8868SPhilip Reames  ret i32 %i
48699ac8868SPhilip Reames}
48799ac8868SPhilip Reames
48899ac8868SPhilip Reames; multiple exit w/a non lcssa phi
48999ac8868SPhilip Reamesdefine i32 @multiple_unique_exit3(i16* %p, i32 %n) {
49099ac8868SPhilip Reames; CHECK-LABEL: @multiple_unique_exit3(
49199ac8868SPhilip Reames; CHECK-NEXT:  entry:
492b46c085dSRoman Lebedev; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
493b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
494b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
495b46c085dSRoman Lebedev; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
4969f61fbd7SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
4979f61fbd7SPhilip Reames; CHECK:       vector.ph:
498b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
499b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
500b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
501b46c085dSRoman Lebedev; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
5029f61fbd7SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
5039f61fbd7SPhilip Reames; CHECK:       vector.body:
5049f61fbd7SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
505b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
506c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
507c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
508c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
509c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
510c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
51123c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
512c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
513145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
5149f61fbd7SPhilip Reames; CHECK:       middle.block:
51572314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
5169f61fbd7SPhilip Reames; CHECK:       scalar.ph:
5179f61fbd7SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
51899ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
51999ac8868SPhilip Reames; CHECK:       for.cond:
5209f61fbd7SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
5219f61fbd7SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
52272314466SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
52399ac8868SPhilip Reames; CHECK:       for.body:
52499ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
5259f61fbd7SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
52699ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
52799ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
52899ac8868SPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
529145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]], !llvm.loop [[LOOP13:![0-9]+]]
53099ac8868SPhilip Reames; CHECK:       if.end:
53172314466SPhilip Reames; CHECK-NEXT:    [[EXIT:%.*]] = phi i32 [ 0, [[FOR_COND]] ], [ 1, [[FOR_BODY]] ]
53299ac8868SPhilip Reames; CHECK-NEXT:    ret i32 [[EXIT]]
53399ac8868SPhilip Reames;
5344b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_unique_exit3(
5354b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
5364b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
5374b33b238SPhilip Reames; TAILFOLD:       for.cond:
5384b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
5394b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
5404b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
5414b33b238SPhilip Reames; TAILFOLD:       for.body:
5424b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
5434b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
5444b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
5454b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
5464b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
5474b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END]]
5484b33b238SPhilip Reames; TAILFOLD:       if.end:
5494b33b238SPhilip Reames; TAILFOLD-NEXT:    [[EXIT:%.*]] = phi i32 [ 0, [[FOR_COND]] ], [ 1, [[FOR_BODY]] ]
5504b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 [[EXIT]]
5514b33b238SPhilip Reames;
55299ac8868SPhilip Reamesentry:
55399ac8868SPhilip Reames  br label %for.cond
55499ac8868SPhilip Reames
55599ac8868SPhilip Reamesfor.cond:
55699ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
55799ac8868SPhilip Reames  %cmp = icmp slt i32 %i, %n
55899ac8868SPhilip Reames  br i1 %cmp, label %for.body, label %if.end
55999ac8868SPhilip Reames
56099ac8868SPhilip Reamesfor.body:
56199ac8868SPhilip Reames  %iprom = sext i32 %i to i64
56299ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
56399ac8868SPhilip Reames  store i16 0, i16* %b, align 4
56499ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
56599ac8868SPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
56699ac8868SPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end
56799ac8868SPhilip Reames
56899ac8868SPhilip Reamesif.end:
56999ac8868SPhilip Reames  %exit = phi i32 [0, %for.cond], [1, %for.body]
57099ac8868SPhilip Reames  ret i32 %exit
57199ac8868SPhilip Reames}
57299ac8868SPhilip Reames
57399ac8868SPhilip Reames; multiple exits w/distinct target blocks
57499ac8868SPhilip Reamesdefine i32 @multiple_exit_blocks(i16* %p, i32 %n) {
57599ac8868SPhilip Reames; CHECK-LABEL: @multiple_exit_blocks(
57699ac8868SPhilip Reames; CHECK-NEXT:  entry:
57795346ba8SPhilip Reames; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
57895346ba8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
57995346ba8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
58095346ba8SPhilip Reames; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
58195346ba8SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
58295346ba8SPhilip Reames; CHECK:       vector.ph:
58395346ba8SPhilip Reames; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
58495346ba8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
58595346ba8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
58695346ba8SPhilip Reames; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
58795346ba8SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
58895346ba8SPhilip Reames; CHECK:       vector.body:
58995346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
59095346ba8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
591c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
592c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
593c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
594c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
595c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
59695346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
597c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
598145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
59995346ba8SPhilip Reames; CHECK:       middle.block:
60095346ba8SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
60195346ba8SPhilip Reames; CHECK:       scalar.ph:
60295346ba8SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
60399ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
60499ac8868SPhilip Reames; CHECK:       for.cond:
60595346ba8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
60695346ba8SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
60799ac8868SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
60899ac8868SPhilip Reames; CHECK:       for.body:
60999ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
61095346ba8SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
61199ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
61299ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
61399ac8868SPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
614145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP15:![0-9]+]]
61599ac8868SPhilip Reames; CHECK:       if.end:
61699ac8868SPhilip Reames; CHECK-NEXT:    ret i32 0
61799ac8868SPhilip Reames; CHECK:       if.end2:
61899ac8868SPhilip Reames; CHECK-NEXT:    ret i32 1
61999ac8868SPhilip Reames;
6204b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_exit_blocks(
6214b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
6224b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
6234b33b238SPhilip Reames; TAILFOLD:       for.cond:
6244b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
6254b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
6264b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
6274b33b238SPhilip Reames; TAILFOLD:       for.body:
6284b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
6294b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
6304b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
6314b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
6324b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
6334b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
6344b33b238SPhilip Reames; TAILFOLD:       if.end:
6354b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 0
6364b33b238SPhilip Reames; TAILFOLD:       if.end2:
6374b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 1
6384b33b238SPhilip Reames;
63999ac8868SPhilip Reamesentry:
64099ac8868SPhilip Reames  br label %for.cond
64199ac8868SPhilip Reames
64299ac8868SPhilip Reamesfor.cond:
64399ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
64499ac8868SPhilip Reames  %cmp = icmp slt i32 %i, %n
64599ac8868SPhilip Reames  br i1 %cmp, label %for.body, label %if.end
64699ac8868SPhilip Reames
64799ac8868SPhilip Reamesfor.body:
64899ac8868SPhilip Reames  %iprom = sext i32 %i to i64
64999ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
65099ac8868SPhilip Reames  store i16 0, i16* %b, align 4
65199ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
65299ac8868SPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
65399ac8868SPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end2
65499ac8868SPhilip Reames
65599ac8868SPhilip Reamesif.end:
65699ac8868SPhilip Reames  ret i32 0
65799ac8868SPhilip Reames
65899ac8868SPhilip Reamesif.end2:
65999ac8868SPhilip Reames  ret i32 1
66099ac8868SPhilip Reames}
66199ac8868SPhilip Reames
6628356610fSPhilip Reames; LCSSA, common value each exit
6638356610fSPhilip Reamesdefine i32 @multiple_exit_blocks2(i16* %p, i32 %n) {
6648356610fSPhilip Reames; CHECK-LABEL: @multiple_exit_blocks2(
6658356610fSPhilip Reames; CHECK-NEXT:  entry:
66695346ba8SPhilip Reames; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
66795346ba8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
66895346ba8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
66995346ba8SPhilip Reames; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
67095346ba8SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
67195346ba8SPhilip Reames; CHECK:       vector.ph:
67295346ba8SPhilip Reames; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
67395346ba8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
67495346ba8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
67595346ba8SPhilip Reames; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
67695346ba8SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
67795346ba8SPhilip Reames; CHECK:       vector.body:
67895346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
67995346ba8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
680c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
681c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
682c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
683c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
684c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
68595346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
686c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
687145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
68895346ba8SPhilip Reames; CHECK:       middle.block:
68995346ba8SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
69095346ba8SPhilip Reames; CHECK:       scalar.ph:
69195346ba8SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
6928356610fSPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
6938356610fSPhilip Reames; CHECK:       for.cond:
69495346ba8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
69595346ba8SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
6968356610fSPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
6978356610fSPhilip Reames; CHECK:       for.body:
6988356610fSPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
69995346ba8SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
7008356610fSPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
7018356610fSPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
7028356610fSPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
703145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP17:![0-9]+]]
7048356610fSPhilip Reames; CHECK:       if.end:
7058356610fSPhilip Reames; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
7068356610fSPhilip Reames; CHECK-NEXT:    ret i32 [[I_LCSSA]]
7078356610fSPhilip Reames; CHECK:       if.end2:
7088356610fSPhilip Reames; CHECK-NEXT:    [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ]
7098356610fSPhilip Reames; CHECK-NEXT:    ret i32 [[I_LCSSA1]]
7108356610fSPhilip Reames;
7118356610fSPhilip Reames; TAILFOLD-LABEL: @multiple_exit_blocks2(
7128356610fSPhilip Reames; TAILFOLD-NEXT:  entry:
7138356610fSPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
7148356610fSPhilip Reames; TAILFOLD:       for.cond:
7158356610fSPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
7168356610fSPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
7178356610fSPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
7188356610fSPhilip Reames; TAILFOLD:       for.body:
7198356610fSPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
7208356610fSPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
7218356610fSPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
7228356610fSPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
7238356610fSPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
7248356610fSPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
7258356610fSPhilip Reames; TAILFOLD:       if.end:
7268356610fSPhilip Reames; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
7278356610fSPhilip Reames; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
7288356610fSPhilip Reames; TAILFOLD:       if.end2:
7298356610fSPhilip Reames; TAILFOLD-NEXT:    [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ]
7308356610fSPhilip Reames; TAILFOLD-NEXT:    ret i32 [[I_LCSSA1]]
7318356610fSPhilip Reames;
7328356610fSPhilip Reamesentry:
7338356610fSPhilip Reames  br label %for.cond
7348356610fSPhilip Reames
7358356610fSPhilip Reamesfor.cond:
7368356610fSPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
7378356610fSPhilip Reames  %cmp = icmp slt i32 %i, %n
7388356610fSPhilip Reames  br i1 %cmp, label %for.body, label %if.end
7398356610fSPhilip Reames
7408356610fSPhilip Reamesfor.body:
7418356610fSPhilip Reames  %iprom = sext i32 %i to i64
7428356610fSPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
7438356610fSPhilip Reames  store i16 0, i16* %b, align 4
7448356610fSPhilip Reames  %inc = add nsw i32 %i, 1
7458356610fSPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
7468356610fSPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end2
7478356610fSPhilip Reames
7488356610fSPhilip Reamesif.end:
7498356610fSPhilip Reames  ret i32 %i
7508356610fSPhilip Reames
7518356610fSPhilip Reamesif.end2:
7528356610fSPhilip Reames  ret i32 %i
7538356610fSPhilip Reames}
7548356610fSPhilip Reames
7558356610fSPhilip Reames; LCSSA, distinct value each exit
7568356610fSPhilip Reamesdefine i32 @multiple_exit_blocks3(i16* %p, i32 %n) {
7578356610fSPhilip Reames; CHECK-LABEL: @multiple_exit_blocks3(
7588356610fSPhilip Reames; CHECK-NEXT:  entry:
75995346ba8SPhilip Reames; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
76095346ba8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SMAX]], i32 2096)
76195346ba8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 1
76295346ba8SPhilip Reames; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], 2
76395346ba8SPhilip Reames; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
76495346ba8SPhilip Reames; CHECK:       vector.ph:
76595346ba8SPhilip Reames; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 2
76695346ba8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[N_MOD_VF]], 0
76795346ba8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 2, i32 [[N_MOD_VF]]
76895346ba8SPhilip Reames; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP2]]
76995346ba8SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
77095346ba8SPhilip Reames; CHECK:       vector.body:
77195346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
77295346ba8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 0
773c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[TMP3]] to i64
774c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[TMP4]]
775c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP5]], i32 0
776c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i16* [[TMP6]] to <2 x i16>*
777c230ab6dSFlorian Hahn; CHECK-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP7]], align 4
77895346ba8SPhilip Reames; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
779*569d84feSFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
780*569d84feSFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
78195346ba8SPhilip Reames; CHECK:       middle.block:
78295346ba8SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
78395346ba8SPhilip Reames; CHECK:       scalar.ph:
78495346ba8SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
7858356610fSPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
7868356610fSPhilip Reames; CHECK:       for.cond:
78795346ba8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
78895346ba8SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
7898356610fSPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
7908356610fSPhilip Reames; CHECK:       for.body:
7918356610fSPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
79295346ba8SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 [[IPROM]]
7938356610fSPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
7948356610fSPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
7958356610fSPhilip Reames; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
796145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]], !llvm.loop [[LOOP19:![0-9]+]]
7978356610fSPhilip Reames; CHECK:       if.end:
7988356610fSPhilip Reames; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
7998356610fSPhilip Reames; CHECK-NEXT:    ret i32 [[I_LCSSA]]
8008356610fSPhilip Reames; CHECK:       if.end2:
8018356610fSPhilip Reames; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ]
8028356610fSPhilip Reames; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
8038356610fSPhilip Reames;
8048356610fSPhilip Reames; TAILFOLD-LABEL: @multiple_exit_blocks3(
8058356610fSPhilip Reames; TAILFOLD-NEXT:  entry:
8068356610fSPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
8078356610fSPhilip Reames; TAILFOLD:       for.cond:
8088356610fSPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
8098356610fSPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]]
8108356610fSPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]]
8118356610fSPhilip Reames; TAILFOLD:       for.body:
8128356610fSPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
8138356610fSPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
8148356610fSPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
8158356610fSPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
8168356610fSPhilip Reames; TAILFOLD-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 2096
8178356610fSPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]]
8188356610fSPhilip Reames; TAILFOLD:       if.end:
8198356610fSPhilip Reames; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ]
8208356610fSPhilip Reames; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
8218356610fSPhilip Reames; TAILFOLD:       if.end2:
8228356610fSPhilip Reames; TAILFOLD-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ]
8238356610fSPhilip Reames; TAILFOLD-NEXT:    ret i32 [[INC_LCSSA]]
8248356610fSPhilip Reames;
8258356610fSPhilip Reamesentry:
8268356610fSPhilip Reames  br label %for.cond
8278356610fSPhilip Reames
8288356610fSPhilip Reamesfor.cond:
8298356610fSPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
8308356610fSPhilip Reames  %cmp = icmp slt i32 %i, %n
8318356610fSPhilip Reames  br i1 %cmp, label %for.body, label %if.end
8328356610fSPhilip Reames
8338356610fSPhilip Reamesfor.body:
8348356610fSPhilip Reames  %iprom = sext i32 %i to i64
8358356610fSPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
8368356610fSPhilip Reames  store i16 0, i16* %b, align 4
8378356610fSPhilip Reames  %inc = add nsw i32 %i, 1
8388356610fSPhilip Reames  %cmp2 = icmp slt i32 %i, 2096
8398356610fSPhilip Reames  br i1 %cmp2, label %for.cond, label %if.end2
8408356610fSPhilip Reames
8418356610fSPhilip Reamesif.end:
8428356610fSPhilip Reames  ret i32 %i
8438356610fSPhilip Reames
8448356610fSPhilip Reamesif.end2:
8458356610fSPhilip Reames  ret i32 %inc
8468356610fSPhilip Reames}
8478356610fSPhilip Reames
84899ac8868SPhilip Reames; unique exit case but with a switch as two edges between the same pair of
84999ac8868SPhilip Reames; blocks is an often missed edge case
85099ac8868SPhilip Reamesdefine i32 @multiple_exit_switch(i16* %p, i32 %n) {
85199ac8868SPhilip Reames; CHECK-LABEL: @multiple_exit_switch(
85299ac8868SPhilip Reames; CHECK-NEXT:  entry:
85399ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
85499ac8868SPhilip Reames; CHECK:       for.cond:
85599ac8868SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
85699ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
85799ac8868SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
85899ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
85999ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
86099ac8868SPhilip Reames; CHECK-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
86199ac8868SPhilip Reames; CHECK-NEXT:    i32 2096, label [[IF_END:%.*]]
86299ac8868SPhilip Reames; CHECK-NEXT:    i32 2097, label [[IF_END]]
86399ac8868SPhilip Reames; CHECK-NEXT:    ]
86499ac8868SPhilip Reames; CHECK:       if.end:
86599ac8868SPhilip Reames; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ], [ [[I]], [[FOR_COND]] ]
86699ac8868SPhilip Reames; CHECK-NEXT:    ret i32 [[I_LCSSA]]
86799ac8868SPhilip Reames;
8684b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_exit_switch(
8694b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
8704b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
8714b33b238SPhilip Reames; TAILFOLD:       for.cond:
8724b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
8734b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
8744b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
8754b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
8764b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
8774b33b238SPhilip Reames; TAILFOLD-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
8784b33b238SPhilip Reames; TAILFOLD-NEXT:    i32 2096, label [[IF_END:%.*]]
8794b33b238SPhilip Reames; TAILFOLD-NEXT:    i32 2097, label [[IF_END]]
8804b33b238SPhilip Reames; TAILFOLD-NEXT:    ]
8814b33b238SPhilip Reames; TAILFOLD:       if.end:
8824b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ], [ [[I]], [[FOR_COND]] ]
8834b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 [[I_LCSSA]]
8844b33b238SPhilip Reames;
88599ac8868SPhilip Reamesentry:
88699ac8868SPhilip Reames  br label %for.cond
88799ac8868SPhilip Reames
88899ac8868SPhilip Reamesfor.cond:
88999ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
89099ac8868SPhilip Reames  %iprom = sext i32 %i to i64
89199ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
89299ac8868SPhilip Reames  store i16 0, i16* %b, align 4
89399ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
89499ac8868SPhilip Reames  switch i32 %i, label %for.cond [
89599ac8868SPhilip Reames  i32 2096, label %if.end
89699ac8868SPhilip Reames  i32 2097, label %if.end
89799ac8868SPhilip Reames  ]
89899ac8868SPhilip Reames
89999ac8868SPhilip Reamesif.end:
90099ac8868SPhilip Reames  ret i32 %i
90199ac8868SPhilip Reames}
90299ac8868SPhilip Reames
90399ac8868SPhilip Reames; multiple exit case but with a switch as multiple exiting edges from
90499ac8868SPhilip Reames; a single block is a commonly missed edge case
90599ac8868SPhilip Reamesdefine i32 @multiple_exit_switch2(i16* %p, i32 %n) {
90699ac8868SPhilip Reames; CHECK-LABEL: @multiple_exit_switch2(
90799ac8868SPhilip Reames; CHECK-NEXT:  entry:
90899ac8868SPhilip Reames; CHECK-NEXT:    br label [[FOR_COND:%.*]]
90999ac8868SPhilip Reames; CHECK:       for.cond:
91099ac8868SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
91199ac8868SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
91299ac8868SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
91399ac8868SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
91499ac8868SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I]], 1
91599ac8868SPhilip Reames; CHECK-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
91699ac8868SPhilip Reames; CHECK-NEXT:    i32 2096, label [[IF_END:%.*]]
91799ac8868SPhilip Reames; CHECK-NEXT:    i32 2097, label [[IF_END2:%.*]]
91899ac8868SPhilip Reames; CHECK-NEXT:    ]
91999ac8868SPhilip Reames; CHECK:       if.end:
92099ac8868SPhilip Reames; CHECK-NEXT:    ret i32 0
92199ac8868SPhilip Reames; CHECK:       if.end2:
92299ac8868SPhilip Reames; CHECK-NEXT:    ret i32 1
92399ac8868SPhilip Reames;
9244b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_exit_switch2(
9254b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
9264b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_COND:%.*]]
9274b33b238SPhilip Reames; TAILFOLD:       for.cond:
9284b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_COND]] ]
9294b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I]] to i64
9304b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
9314b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
9324b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I]], 1
9334b33b238SPhilip Reames; TAILFOLD-NEXT:    switch i32 [[I]], label [[FOR_COND]] [
9344b33b238SPhilip Reames; TAILFOLD-NEXT:    i32 2096, label [[IF_END:%.*]]
9354b33b238SPhilip Reames; TAILFOLD-NEXT:    i32 2097, label [[IF_END2:%.*]]
9364b33b238SPhilip Reames; TAILFOLD-NEXT:    ]
9374b33b238SPhilip Reames; TAILFOLD:       if.end:
9384b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 0
9394b33b238SPhilip Reames; TAILFOLD:       if.end2:
9404b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 1
9414b33b238SPhilip Reames;
94299ac8868SPhilip Reamesentry:
94399ac8868SPhilip Reames  br label %for.cond
94499ac8868SPhilip Reames
94599ac8868SPhilip Reamesfor.cond:
94699ac8868SPhilip Reames  %i = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
94799ac8868SPhilip Reames  %iprom = sext i32 %i to i64
94899ac8868SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
94999ac8868SPhilip Reames  store i16 0, i16* %b, align 4
95099ac8868SPhilip Reames  %inc = add nsw i32 %i, 1
95199ac8868SPhilip Reames  switch i32 %i, label %for.cond [
95299ac8868SPhilip Reames  i32 2096, label %if.end
95399ac8868SPhilip Reames  i32 2097, label %if.end2
95499ac8868SPhilip Reames  ]
95599ac8868SPhilip Reames
95699ac8868SPhilip Reamesif.end:
95799ac8868SPhilip Reames  ret i32 0
95899ac8868SPhilip Reames
95999ac8868SPhilip Reamesif.end2:
96099ac8868SPhilip Reames  ret i32 1
96199ac8868SPhilip Reames}
962f106b281SPhilip Reames
963f106b281SPhilip Reamesdefine i32 @multiple_latch1(i16* %p) {
964f106b281SPhilip Reames; CHECK-LABEL: @multiple_latch1(
965f106b281SPhilip Reames; CHECK-NEXT:  entry:
966f106b281SPhilip Reames; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
967f106b281SPhilip Reames; CHECK:       for.body:
968f106b281SPhilip Reames; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
969f106b281SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
970f106b281SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
971f106b281SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
972f106b281SPhilip Reames; CHECK:       for.second:
973f106b281SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
974f106b281SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
975f106b281SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
976f106b281SPhilip Reames; CHECK-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
977f106b281SPhilip Reames; CHECK-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
978f106b281SPhilip Reames; CHECK:       for.body.backedge:
979f106b281SPhilip Reames; CHECK-NEXT:    br label [[FOR_BODY]]
980f106b281SPhilip Reames; CHECK:       for.end:
981f106b281SPhilip Reames; CHECK-NEXT:    ret i32 0
982f106b281SPhilip Reames;
9834b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_latch1(
9844b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
9854b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_BODY:%.*]]
9864b33b238SPhilip Reames; TAILFOLD:       for.body:
9874b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
9884b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
9894b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
9904b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
9914b33b238SPhilip Reames; TAILFOLD:       for.second:
9924b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
9934b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
9944b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
9954b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
9964b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
9974b33b238SPhilip Reames; TAILFOLD:       for.body.backedge:
9984b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_BODY]]
9994b33b238SPhilip Reames; TAILFOLD:       for.end:
10004b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 0
10014b33b238SPhilip Reames;
1002f106b281SPhilip Reamesentry:
1003f106b281SPhilip Reames  br label %for.body
1004f106b281SPhilip Reames
1005f106b281SPhilip Reamesfor.body:
1006f106b281SPhilip Reames  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body.backedge]
1007f106b281SPhilip Reames  %inc = add nsw i32 %i.02, 1
1008f106b281SPhilip Reames  %cmp = icmp slt i32 %inc, 16
1009f106b281SPhilip Reames  br i1 %cmp, label %for.body.backedge, label %for.second
1010f106b281SPhilip Reames
1011f106b281SPhilip Reamesfor.second:
1012f106b281SPhilip Reames  %iprom = sext i32 %i.02 to i64
1013f106b281SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
1014f106b281SPhilip Reames  store i16 0, i16* %b, align 4
1015f106b281SPhilip Reames  %cmps = icmp sgt i32 %inc, 16
1016f106b281SPhilip Reames  br i1 %cmps, label %for.body.backedge, label %for.end
1017f106b281SPhilip Reames
1018f106b281SPhilip Reamesfor.body.backedge:
1019f106b281SPhilip Reames  br label %for.body
1020f106b281SPhilip Reames
1021f106b281SPhilip Reamesfor.end:
1022f106b281SPhilip Reames  ret i32 0
1023f106b281SPhilip Reames}
1024f106b281SPhilip Reames
1025f106b281SPhilip Reames
1026f106b281SPhilip Reames; two back branches - loop simplify with convert this to the same form
1027f106b281SPhilip Reames; as previous before vectorizer sees it, but show that.
1028f106b281SPhilip Reamesdefine i32 @multiple_latch2(i16* %p) {
1029f106b281SPhilip Reames; CHECK-LABEL: @multiple_latch2(
1030f106b281SPhilip Reames; CHECK-NEXT:  entry:
1031f106b281SPhilip Reames; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1032f106b281SPhilip Reames; CHECK:       for.body:
1033f106b281SPhilip Reames; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
1034f106b281SPhilip Reames; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
1035f106b281SPhilip Reames; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
1036f106b281SPhilip Reames; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
1037f106b281SPhilip Reames; CHECK:       for.body.backedge:
1038f106b281SPhilip Reames; CHECK-NEXT:    br label [[FOR_BODY]]
1039f106b281SPhilip Reames; CHECK:       for.second:
1040f106b281SPhilip Reames; CHECK-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
1041f106b281SPhilip Reames; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
1042f106b281SPhilip Reames; CHECK-NEXT:    store i16 0, i16* [[B]], align 4
1043f106b281SPhilip Reames; CHECK-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
1044f106b281SPhilip Reames; CHECK-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
1045f106b281SPhilip Reames; CHECK:       for.end:
1046f106b281SPhilip Reames; CHECK-NEXT:    ret i32 0
1047f106b281SPhilip Reames;
10484b33b238SPhilip Reames; TAILFOLD-LABEL: @multiple_latch2(
10494b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
10504b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_BODY:%.*]]
10514b33b238SPhilip Reames; TAILFOLD:       for.body:
10524b33b238SPhilip Reames; TAILFOLD-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
10534b33b238SPhilip Reames; TAILFOLD-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1
10544b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], 16
10554b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMP]], label [[FOR_BODY_BACKEDGE]], label [[FOR_SECOND:%.*]]
10564b33b238SPhilip Reames; TAILFOLD:       for.body.backedge:
10574b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[FOR_BODY]]
10584b33b238SPhilip Reames; TAILFOLD:       for.second:
10594b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IPROM:%.*]] = sext i32 [[I_02]] to i64
10604b33b238SPhilip Reames; TAILFOLD-NEXT:    [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]]
10614b33b238SPhilip Reames; TAILFOLD-NEXT:    store i16 0, i16* [[B]], align 4
10624b33b238SPhilip Reames; TAILFOLD-NEXT:    [[CMPS:%.*]] = icmp sgt i32 [[INC]], 16
10634b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[CMPS]], label [[FOR_BODY_BACKEDGE]], label [[FOR_END:%.*]]
10644b33b238SPhilip Reames; TAILFOLD:       for.end:
10654b33b238SPhilip Reames; TAILFOLD-NEXT:    ret i32 0
10664b33b238SPhilip Reames;
1067f106b281SPhilip Reamesentry:
1068f106b281SPhilip Reames  br label %for.body
1069f106b281SPhilip Reames
1070f106b281SPhilip Reamesfor.body:
1071f106b281SPhilip Reames  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ], [%inc, %for.second]
1072f106b281SPhilip Reames  %inc = add nsw i32 %i.02, 1
1073f106b281SPhilip Reames  %cmp = icmp slt i32 %inc, 16
1074f106b281SPhilip Reames  br i1 %cmp, label %for.body, label %for.second
1075f106b281SPhilip Reames
1076f106b281SPhilip Reamesfor.second:
1077f106b281SPhilip Reames  %iprom = sext i32 %i.02 to i64
1078f106b281SPhilip Reames  %b = getelementptr inbounds i16, i16* %p, i64 %iprom
1079f106b281SPhilip Reames  store i16 0, i16* %b, align 4
1080f106b281SPhilip Reames  %cmps = icmp sgt i32 %inc, 16
1081f106b281SPhilip Reames  br i1 %cmps, label %for.body, label %for.end
1082f106b281SPhilip Reames
1083f106b281SPhilip Reamesfor.end:
1084f106b281SPhilip Reames  ret i32 0
1085f106b281SPhilip Reames}
1086f106b281SPhilip Reames
10874b33b238SPhilip Reames
10884b33b238SPhilip Reames; Check interaction between block predication and early exits.  We need the
10894b33b238SPhilip Reames; condition on the early exit to remain dead (i.e. not be used when forming
10904b33b238SPhilip Reames; the predicate mask).
10914b33b238SPhilip Reamesdefine void @scalar_predication(float* %addr) {
10924b33b238SPhilip Reames; CHECK-LABEL: @scalar_predication(
10934b33b238SPhilip Reames; CHECK-NEXT:  entry:
10944b33b238SPhilip Reames; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
10954b33b238SPhilip Reames; CHECK:       vector.ph:
10964b33b238SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
10974b33b238SPhilip Reames; CHECK:       vector.body:
10984b33b238SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
10994b33b238SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
11004b33b238SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr float, float* [[ADDR:%.*]], i64 [[TMP0]]
11014b33b238SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr float, float* [[TMP1]], i32 0
11024b33b238SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[TMP2]] to <2 x float>*
11034b33b238SPhilip Reames; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, <2 x float>* [[TMP3]], align 4
11044b33b238SPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = fcmp oeq <2 x float> [[WIDE_LOAD]], zeroinitializer
11054b33b238SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = xor <2 x i1> [[TMP4]], <i1 true, i1 true>
11064b33b238SPhilip Reames; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x i1> [[TMP5]], i32 0
11074b33b238SPhilip Reames; CHECK-NEXT:    br i1 [[TMP6]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
11084b33b238SPhilip Reames; CHECK:       pred.store.if:
1109e90d55e1SFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr float, float* [[ADDR]], i64 [[TMP0]]
1110e90d55e1SFlorian Hahn; CHECK-NEXT:    store float 1.000000e+01, float* [[TMP7]], align 4
11114b33b238SPhilip Reames; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
11124b33b238SPhilip Reames; CHECK:       pred.store.continue:
1113e90d55e1SFlorian Hahn; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <2 x i1> [[TMP5]], i32 1
1114e90d55e1SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
11154b33b238SPhilip Reames; CHECK:       pred.store.if1:
1116e90d55e1SFlorian Hahn; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[INDEX]], 1
1117e90d55e1SFlorian Hahn; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr float, float* [[ADDR]], i64 [[TMP9]]
1118e90d55e1SFlorian Hahn; CHECK-NEXT:    store float 1.000000e+01, float* [[TMP10]], align 4
11194b33b238SPhilip Reames; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE2]]
11204b33b238SPhilip Reames; CHECK:       pred.store.continue2:
112123c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1122d652724cSPhilip Reames; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
1123145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
11244b33b238SPhilip Reames; CHECK:       middle.block:
112572314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
11264b33b238SPhilip Reames; CHECK:       scalar.ph:
11274b33b238SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
11284b33b238SPhilip Reames; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
11294b33b238SPhilip Reames; CHECK:       loop.header:
11304b33b238SPhilip Reames; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
11314b33b238SPhilip Reames; CHECK-NEXT:    [[GEP:%.*]] = getelementptr float, float* [[ADDR]], i64 [[IV]]
11324b33b238SPhilip Reames; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
113372314466SPhilip Reames; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]
11344b33b238SPhilip Reames; CHECK:       loop.body:
1135d652724cSPhilip Reames; CHECK-NEXT:    [[TMP12:%.*]] = load float, float* [[GEP]], align 4
1136d652724cSPhilip Reames; CHECK-NEXT:    [[PRED:%.*]] = fcmp oeq float [[TMP12]], 0.000000e+00
11374b33b238SPhilip Reames; CHECK-NEXT:    br i1 [[PRED]], label [[LOOP_LATCH]], label [[THEN:%.*]]
11384b33b238SPhilip Reames; CHECK:       then:
11394b33b238SPhilip Reames; CHECK-NEXT:    store float 1.000000e+01, float* [[GEP]], align 4
11404b33b238SPhilip Reames; CHECK-NEXT:    br label [[LOOP_LATCH]]
11414b33b238SPhilip Reames; CHECK:       loop.latch:
11424b33b238SPhilip Reames; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1143145fe571SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]], !llvm.loop [[LOOP21:![0-9]+]]
11444b33b238SPhilip Reames; CHECK:       exit:
11454b33b238SPhilip Reames; CHECK-NEXT:    ret void
11464b33b238SPhilip Reames;
11474b33b238SPhilip Reames; TAILFOLD-LABEL: @scalar_predication(
11484b33b238SPhilip Reames; TAILFOLD-NEXT:  entry:
11494b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
11504b33b238SPhilip Reames; TAILFOLD:       loop.header:
11514b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
11524b33b238SPhilip Reames; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr float, float* [[ADDR:%.*]], i64 [[IV]]
11534b33b238SPhilip Reames; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
11544b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]
11554b33b238SPhilip Reames; TAILFOLD:       loop.body:
11564b33b238SPhilip Reames; TAILFOLD-NEXT:    [[TMP0:%.*]] = load float, float* [[GEP]], align 4
11574b33b238SPhilip Reames; TAILFOLD-NEXT:    [[PRED:%.*]] = fcmp oeq float [[TMP0]], 0.000000e+00
11584b33b238SPhilip Reames; TAILFOLD-NEXT:    br i1 [[PRED]], label [[LOOP_LATCH]], label [[THEN:%.*]]
11594b33b238SPhilip Reames; TAILFOLD:       then:
11604b33b238SPhilip Reames; TAILFOLD-NEXT:    store float 1.000000e+01, float* [[GEP]], align 4
11614b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_LATCH]]
11624b33b238SPhilip Reames; TAILFOLD:       loop.latch:
11634b33b238SPhilip Reames; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
11644b33b238SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
11654b33b238SPhilip Reames; TAILFOLD:       exit:
11664b33b238SPhilip Reames; TAILFOLD-NEXT:    ret void
11674b33b238SPhilip Reames;
11684b33b238SPhilip Reamesentry:
11694b33b238SPhilip Reames  br label %loop.header
11704b33b238SPhilip Reames
11714b33b238SPhilip Reamesloop.header:
11724b33b238SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
11734b33b238SPhilip Reames  %gep = getelementptr float, float* %addr, i64 %iv
11744b33b238SPhilip Reames  %exitcond.not = icmp eq i64 %iv, 200
11754b33b238SPhilip Reames  br i1 %exitcond.not, label %exit, label %loop.body
11764b33b238SPhilip Reames
11774b33b238SPhilip Reamesloop.body:
11784b33b238SPhilip Reames  %0 = load float, float* %gep, align 4
11794b33b238SPhilip Reames  %pred = fcmp oeq float %0, 0.0
11804b33b238SPhilip Reames  br i1 %pred, label %loop.latch, label %then
11814b33b238SPhilip Reames
11824b33b238SPhilip Reamesthen:
11834b33b238SPhilip Reames  store float 10.0, float* %gep, align 4
11844b33b238SPhilip Reames  br label %loop.latch
11854b33b238SPhilip Reames
11864b33b238SPhilip Reamesloop.latch:
11874b33b238SPhilip Reames  %iv.next = add nuw nsw i64 %iv, 1
11884b33b238SPhilip Reames  br label %loop.header
11894b33b238SPhilip Reames
11904b33b238SPhilip Reamesexit:
11914b33b238SPhilip Reames  ret void
11924b33b238SPhilip Reames}
119386d6f7e9SPhilip Reames
11949f61fbd7SPhilip Reamesdefine i32 @me_reduction(i32* %addr) {
11959f61fbd7SPhilip Reames; CHECK-LABEL: @me_reduction(
119686d6f7e9SPhilip Reames; CHECK-NEXT:  entry:
11979f61fbd7SPhilip Reames; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
11989f61fbd7SPhilip Reames; CHECK:       vector.ph:
11999f61fbd7SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
12009f61fbd7SPhilip Reames; CHECK:       vector.body:
12019f61fbd7SPhilip Reames; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1202c230ab6dSFlorian Hahn; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <2 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
12039f61fbd7SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
1204c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, i32* [[ADDR:%.*]], i64 [[TMP0]]
1205c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, i32* [[TMP1]], i32 0
1206c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <2 x i32>*
1207c230ab6dSFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i32>, <2 x i32>* [[TMP3]], align 4
1208c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP4]] = add <2 x i32> [[VEC_PHI]], [[WIDE_LOAD]]
120923c2f2e6SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1210c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
1211145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
12129f61fbd7SPhilip Reames; CHECK:       middle.block:
1213c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[TMP4]])
121472314466SPhilip Reames; CHECK-NEXT:    br label [[SCALAR_PH]]
12159f61fbd7SPhilip Reames; CHECK:       scalar.ph:
12169f61fbd7SPhilip Reames; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1217c230ab6dSFlorian Hahn; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP6]], [[MIDDLE_BLOCK]] ]
121886d6f7e9SPhilip Reames; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
121986d6f7e9SPhilip Reames; CHECK:       loop.header:
12209f61fbd7SPhilip Reames; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12219f61fbd7SPhilip Reames; CHECK-NEXT:    [[ACCUM:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
12229f61fbd7SPhilip Reames; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[ADDR]], i64 [[IV]]
122386d6f7e9SPhilip Reames; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
122472314466SPhilip Reames; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
122586d6f7e9SPhilip Reames; CHECK:       loop.latch:
1226c230ab6dSFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[GEP]], align 4
1227c230ab6dSFlorian Hahn; CHECK-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP7]]
122886d6f7e9SPhilip Reames; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
122986d6f7e9SPhilip Reames; CHECK-NEXT:    [[EXITCOND2_NOT:%.*]] = icmp eq i64 [[IV]], 400
1230145fe571SFlorian Hahn; CHECK-NEXT:    br i1 [[EXITCOND2_NOT]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP23:![0-9]+]]
123186d6f7e9SPhilip Reames; CHECK:       exit:
123272314466SPhilip Reames; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ 0, [[LOOP_HEADER]] ], [ [[ACCUM_NEXT]], [[LOOP_LATCH]] ]
123386d6f7e9SPhilip Reames; CHECK-NEXT:    ret i32 [[LCSSA]]
123486d6f7e9SPhilip Reames;
12359f61fbd7SPhilip Reames; TAILFOLD-LABEL: @me_reduction(
123686d6f7e9SPhilip Reames; TAILFOLD-NEXT:  entry:
123786d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
123886d6f7e9SPhilip Reames; TAILFOLD:       loop.header:
123986d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
124086d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
124186d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[ADDR:%.*]], i64 [[IV]]
124286d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
124386d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
124486d6f7e9SPhilip Reames; TAILFOLD:       loop.latch:
124586d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[TMP0:%.*]] = load i32, i32* [[GEP]], align 4
124686d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
124786d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
124886d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[EXITCOND2_NOT:%.*]] = icmp eq i64 [[IV]], 400
124986d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br i1 [[EXITCOND2_NOT]], label [[EXIT]], label [[LOOP_HEADER]]
125086d6f7e9SPhilip Reames; TAILFOLD:       exit:
125186d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[LCSSA:%.*]] = phi i32 [ 0, [[LOOP_HEADER]] ], [ [[ACCUM_NEXT]], [[LOOP_LATCH]] ]
125286d6f7e9SPhilip Reames; TAILFOLD-NEXT:    ret i32 [[LCSSA]]
125386d6f7e9SPhilip Reames;
125486d6f7e9SPhilip Reamesentry:
125586d6f7e9SPhilip Reames  br label %loop.header
125686d6f7e9SPhilip Reames
125786d6f7e9SPhilip Reamesloop.header:
125886d6f7e9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
125986d6f7e9SPhilip Reames  %accum = phi i32 [0, %entry], [%accum.next, %loop.latch]
126086d6f7e9SPhilip Reames  %gep = getelementptr i32, i32* %addr, i64 %iv
126186d6f7e9SPhilip Reames  %exitcond.not = icmp eq i64 %iv, 200
126286d6f7e9SPhilip Reames  br i1 %exitcond.not, label %exit, label %loop.latch
126386d6f7e9SPhilip Reames
126486d6f7e9SPhilip Reamesloop.latch:
126586d6f7e9SPhilip Reames  %0 = load i32, i32* %gep, align 4
126686d6f7e9SPhilip Reames  %accum.next = add i32 %accum, %0
126786d6f7e9SPhilip Reames  %iv.next = add nuw nsw i64 %iv, 1
126886d6f7e9SPhilip Reames  %exitcond2.not = icmp eq i64 %iv, 400
126986d6f7e9SPhilip Reames  br i1 %exitcond2.not, label %exit, label %loop.header
127086d6f7e9SPhilip Reames
127186d6f7e9SPhilip Reamesexit:
127286d6f7e9SPhilip Reames  %lcssa = phi i32 [0, %loop.header], [%accum.next, %loop.latch]
127386d6f7e9SPhilip Reames  ret i32 %lcssa
127486d6f7e9SPhilip Reames}
127586d6f7e9SPhilip Reames
127686d6f7e9SPhilip Reames; TODO: The current definition of reduction is too strict, we can vectorize
127786d6f7e9SPhilip Reames; this.  There's an analogous single exit case where we extract the N-1
127886d6f7e9SPhilip Reames; value of the reduction that we can also handle.  If we fix the later, the
127986d6f7e9SPhilip Reames; multiple exit case probably falls out.
12809f61fbd7SPhilip Reamesdefine i32 @me_reduction2(i32* %addr) {
12819f61fbd7SPhilip Reames; CHECK-LABEL: @me_reduction2(
128286d6f7e9SPhilip Reames; CHECK-NEXT:  entry:
128386d6f7e9SPhilip Reames; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
128486d6f7e9SPhilip Reames; CHECK:       loop.header:
128586d6f7e9SPhilip Reames; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
128686d6f7e9SPhilip Reames; CHECK-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
128786d6f7e9SPhilip Reames; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[ADDR:%.*]], i64 [[IV]]
128886d6f7e9SPhilip Reames; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
128986d6f7e9SPhilip Reames; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
129086d6f7e9SPhilip Reames; CHECK:       loop.latch:
129186d6f7e9SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[GEP]], align 4
129286d6f7e9SPhilip Reames; CHECK-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
129386d6f7e9SPhilip Reames; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
129486d6f7e9SPhilip Reames; CHECK-NEXT:    br label [[LOOP_HEADER]]
129586d6f7e9SPhilip Reames; CHECK:       exit:
129686d6f7e9SPhilip Reames; CHECK-NEXT:    [[ACCUM_LCSSA:%.*]] = phi i32 [ [[ACCUM]], [[LOOP_HEADER]] ]
129786d6f7e9SPhilip Reames; CHECK-NEXT:    ret i32 [[ACCUM_LCSSA]]
129886d6f7e9SPhilip Reames;
12999f61fbd7SPhilip Reames; TAILFOLD-LABEL: @me_reduction2(
130086d6f7e9SPhilip Reames; TAILFOLD-NEXT:  entry:
130186d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_HEADER:%.*]]
130286d6f7e9SPhilip Reames; TAILFOLD:       loop.header:
130386d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
130486d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[ACCUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], [[LOOP_LATCH]] ]
130586d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[ADDR:%.*]], i64 [[IV]]
130686d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], 200
130786d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
130886d6f7e9SPhilip Reames; TAILFOLD:       loop.latch:
130986d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[TMP0:%.*]] = load i32, i32* [[GEP]], align 4
131086d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[ACCUM_NEXT]] = add i32 [[ACCUM]], [[TMP0]]
131186d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
131286d6f7e9SPhilip Reames; TAILFOLD-NEXT:    br label [[LOOP_HEADER]]
131386d6f7e9SPhilip Reames; TAILFOLD:       exit:
131486d6f7e9SPhilip Reames; TAILFOLD-NEXT:    [[ACCUM_LCSSA:%.*]] = phi i32 [ [[ACCUM]], [[LOOP_HEADER]] ]
131586d6f7e9SPhilip Reames; TAILFOLD-NEXT:    ret i32 [[ACCUM_LCSSA]]
131686d6f7e9SPhilip Reames;
131786d6f7e9SPhilip Reamesentry:
131886d6f7e9SPhilip Reames  br label %loop.header
131986d6f7e9SPhilip Reames
132086d6f7e9SPhilip Reamesloop.header:
132186d6f7e9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
132286d6f7e9SPhilip Reames  %accum = phi i32 [0, %entry], [%accum.next, %loop.latch]
132386d6f7e9SPhilip Reames  %gep = getelementptr i32, i32* %addr, i64 %iv
132486d6f7e9SPhilip Reames  %exitcond.not = icmp eq i64 %iv, 200
132586d6f7e9SPhilip Reames  br i1 %exitcond.not, label %exit, label %loop.latch
132686d6f7e9SPhilip Reames
132786d6f7e9SPhilip Reamesloop.latch:
132886d6f7e9SPhilip Reames  %0 = load i32, i32* %gep, align 4
132986d6f7e9SPhilip Reames  %accum.next = add i32 %accum, %0
133086d6f7e9SPhilip Reames  %iv.next = add nuw nsw i64 %iv, 1
133186d6f7e9SPhilip Reames  br label %loop.header
133286d6f7e9SPhilip Reames
133386d6f7e9SPhilip Reamesexit:
133486d6f7e9SPhilip Reames  ret i32 %accum
133586d6f7e9SPhilip Reames}
133686d6f7e9SPhilip Reames
1337