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