323 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; RUN: opt -p loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -S %s | FileCheck %s3 4define i32 @loop_with_at_least_2_iterations_via_guards_order_1(ptr %dst, i32 %n) {5; CHECK-LABEL: define i32 @loop_with_at_least_2_iterations_via_guards_order_1(6; CHECK-SAME: ptr [[DST:%.*]], i32 [[N:%.*]]) {7; CHECK-NEXT: [[ENTRY:.*:]]8; CHECK-NEXT: [[PRE_0:%.*]] = icmp ne i32 [[N]], 09; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i32 [[N]], 510; CHECK-NEXT: [[AND_PRE:%.*]] = and i1 [[PRE_0]], [[PRE_1]]11; CHECK-NEXT: br i1 [[AND_PRE]], label %[[PH:.*]], label %[[EXIT:.*]]12; CHECK: [[PH]]:13; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i6414; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[N_EXT]], 115; CHECK-NEXT: br label %[[VECTOR_PH:.*]]16; CHECK: [[VECTOR_PH]]:17; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 218; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]19; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]20; CHECK: [[VECTOR_BODY]]:21; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]22; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]23; CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[TMP1]], align 424; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 225; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]26; CHECK-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]27; CHECK: [[MIDDLE_BLOCK]]:28; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]29; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT_LOOPEXIT:.*]], label %[[SCALAR_PH:.*]]30; CHECK: [[SCALAR_PH]]:31; CHECK-NEXT: br label %[[LOOP:.*]]32; CHECK: [[LOOP]]:33; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[N_VEC]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]34; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]35; CHECK-NEXT: store i32 1, ptr [[GEP]], align 436; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 137; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N_EXT]]38; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]39; CHECK: [[EXIT_LOOPEXIT]]:40; CHECK-NEXT: br label %[[EXIT]]41; CHECK: [[EXIT]]:42; CHECK-NEXT: ret i32 043;44entry:45 %pre.0 = icmp ne i32 %n, 046 %pre.1 = icmp slt i32 %n, 547 %and.pre = and i1 %pre.0, %pre.148 br i1 %and.pre, label %ph, label %exit49 50ph: ; preds = %entry51 %n.ext = zext i32 %n to i6452 br label %loop53 54loop: ; preds = %loop, %ph55 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]56 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv57 store i32 1, ptr %gep58 %iv.next = add i64 %iv, 159 %ec = icmp eq i64 %iv, %n.ext60 br i1 %ec, label %exit, label %loop61 62exit: ; preds = %loop, %entry63 ret i32 064}65 66; Same as loop_with_at_least_2_iterations_via_guards_order_1 but with operands67; of the AND swapped.68; TODO: Should be able to prove that %min.iters.check is false.69define i32 @loop_with_at_least_2_iterations_via_guards_order_2(ptr %dst, i32 %n) {70; CHECK-LABEL: define i32 @loop_with_at_least_2_iterations_via_guards_order_2(71; CHECK-SAME: ptr [[DST:%.*]], i32 [[N:%.*]]) {72; CHECK-NEXT: [[ENTRY:.*:]]73; CHECK-NEXT: [[PRE_0:%.*]] = icmp ne i32 [[N]], 074; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i32 [[N]], 575; CHECK-NEXT: [[AND_PRE:%.*]] = and i1 [[PRE_1]], [[PRE_0]]76; CHECK-NEXT: br i1 [[AND_PRE]], label %[[PH:.*]], label %[[EXIT:.*]]77; CHECK: [[PH]]:78; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i6479; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[N_EXT]], 180; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 281; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]82; CHECK: [[VECTOR_PH]]:83; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 284; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]85; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]86; CHECK: [[VECTOR_BODY]]:87; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]88; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]89; CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[TMP1]], align 490; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 291; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]92; CHECK-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]93; CHECK: [[MIDDLE_BLOCK]]:94; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]95; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT_LOOPEXIT:.*]], label %[[SCALAR_PH]]96; CHECK: [[SCALAR_PH]]:97; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[PH]] ]98; CHECK-NEXT: br label %[[LOOP:.*]]99; CHECK: [[LOOP]]:100; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]101; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]102; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4103; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1104; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N_EXT]]105; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]106; CHECK: [[EXIT_LOOPEXIT]]:107; CHECK-NEXT: br label %[[EXIT]]108; CHECK: [[EXIT]]:109; CHECK-NEXT: ret i32 0110;111entry:112 %pre.0 = icmp ne i32 %n, 0113 %pre.1 = icmp slt i32 %n, 5114 %and.pre = and i1 %pre.1, %pre.0115 br i1 %and.pre, label %ph, label %exit116 117ph:118 %n.ext = zext i32 %n to i64119 br label %loop120 121loop:122 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]123 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv124 store i32 1, ptr %gep125 %iv.next = add i64 %iv, 1126 %ec = icmp eq i64 %iv, %n.ext127 br i1 %ec, label %exit, label %loop128 129exit:130 ret i32 0131}132 133; TODO: Should be able to prove min.iters.check is false, same as134; @loop_never_executes_precondition_order_1_predicates_flipped.135define void @loop_never_executes_precondition_order_1(i64 %start, ptr %dst) {136; CHECK-LABEL: define void @loop_never_executes_precondition_order_1(137; CHECK-SAME: i64 [[START:%.*]], ptr [[DST:%.*]]) {138; CHECK-NEXT: [[ENTRY:.*:]]139; CHECK-NEXT: [[PRE_0:%.*]] = icmp ugt i64 [[START]], 1140; CHECK-NEXT: br i1 [[PRE_0]], label %[[EXIT:.*]], label %[[PH:.*]]141; CHECK: [[PH]]:142; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[START]], 1143; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i64 [[MUL]], [[START]]144; CHECK-NEXT: br i1 [[PRE_1]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT]]145; CHECK: [[LOOP_PREHEADER]]:146; CHECK-NEXT: [[TMP0:%.*]] = sub i64 1, [[START]]147; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 2148; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]149; CHECK: [[VECTOR_PH]]:150; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 2151; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]152; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[START]], [[N_VEC]]153; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[START]], i64 0154; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer155; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[DOTSPLAT]], <i64 0, i64 1>156; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]157; CHECK: [[VECTOR_BODY]]:158; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]159; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ [[INDUCTION]], %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]160; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 [[START]], [[INDEX]]161; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[OFFSET_IDX]]162; CHECK-NEXT: store <2 x i64> [[VEC_IND]], ptr [[TMP2]], align 4163; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2164; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)165; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]166; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]167; CHECK: [[MIDDLE_BLOCK]]:168; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]169; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT_LOOPEXIT:.*]], label %[[SCALAR_PH]]170; CHECK: [[SCALAR_PH]]:171; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[TMP1]], %[[MIDDLE_BLOCK]] ], [ [[START]], %[[LOOP_PREHEADER]] ]172; CHECK-NEXT: br label %[[LOOP:.*]]173; CHECK: [[LOOP]]:174; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]175; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV]]176; CHECK-NEXT: store i64 [[IV]], ptr [[GEP]], align 4177; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1178; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 0179; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]180; CHECK: [[EXIT_LOOPEXIT]]:181; CHECK-NEXT: br label %[[EXIT]]182; CHECK: [[EXIT]]:183; CHECK-NEXT: ret void184;185entry:186 %pre.0 = icmp ugt i64 %start, 1187 br i1 %pre.0, label %exit, label %ph188 189ph:190 %mul = shl i64 %start, 1191 %pre.1 = icmp slt i64 %mul, %start192 br i1 %pre.1, label %loop, label %exit193 194loop:195 %iv = phi i64 [ %start, %ph ], [ %iv.next, %loop ]196 %gep = getelementptr inbounds i64, ptr %dst, i64 %iv197 store i64 %iv, ptr %gep198 %iv.next = add i64 %iv, 1199 %ec = icmp eq i64 %iv, 0200 br i1 %ec, label %exit, label %loop201 202exit:203 ret void204}205 206; TODO: Should be able to prove min.iters.check is false, same as207; @loop_never_executes_precondition_order_1_predicates_flipped.208define void @loop_never_executes_precondition_order_1_predicates_flipped(i64 %start, ptr %dst) {209; CHECK-LABEL: define void @loop_never_executes_precondition_order_1_predicates_flipped(210; CHECK-SAME: i64 [[START:%.*]], ptr [[DST:%.*]]) {211; CHECK-NEXT: [[ENTRY:.*:]]212; CHECK-NEXT: [[PRE_0:%.*]] = icmp ule i64 [[START]], 1213; CHECK-NEXT: br i1 [[PRE_0]], label %[[PH:.*]], label %[[EXIT:.*]]214; CHECK: [[PH]]:215; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[START]], 1216; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i64 [[MUL]], [[START]]217; CHECK-NEXT: br i1 [[PRE_1]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT]]218; CHECK: [[LOOP_PREHEADER]]:219; CHECK-NEXT: [[TMP0:%.*]] = sub i64 1, [[START]]220; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 2221; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]222; CHECK: [[VECTOR_PH]]:223; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 2224; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]225; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[START]], [[N_VEC]]226; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[START]], i64 0227; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer228; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[DOTSPLAT]], <i64 0, i64 1>229; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]230; CHECK: [[VECTOR_BODY]]:231; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]232; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ [[INDUCTION]], %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]233; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 [[START]], [[INDEX]]234; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[OFFSET_IDX]]235; CHECK-NEXT: store <2 x i64> [[VEC_IND]], ptr [[TMP2]], align 4236; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2237; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)238; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]239; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]240; CHECK: [[MIDDLE_BLOCK]]:241; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]242; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT_LOOPEXIT:.*]], label %[[SCALAR_PH]]243; CHECK: [[SCALAR_PH]]:244; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[TMP1]], %[[MIDDLE_BLOCK]] ], [ [[START]], %[[LOOP_PREHEADER]] ]245; CHECK-NEXT: br label %[[LOOP:.*]]246; CHECK: [[LOOP]]:247; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]248; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV]]249; CHECK-NEXT: store i64 [[IV]], ptr [[GEP]], align 4250; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1251; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 0252; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]], !llvm.loop [[LOOP9:![0-9]+]]253; CHECK: [[EXIT_LOOPEXIT]]:254; CHECK-NEXT: br label %[[EXIT]]255; CHECK: [[EXIT]]:256; CHECK-NEXT: ret void257;258entry:259 %pre.0 = icmp ule i64 %start, 1260 br i1 %pre.0, label %ph, label %exit261 262ph:263 %mul = shl i64 %start, 1264 %pre.1 = icmp slt i64 %mul, %start265 br i1 %pre.1, label %loop, label %exit266 267loop:268 %iv = phi i64 [ %start, %ph ], [ %iv.next, %loop ]269 %gep = getelementptr inbounds i64, ptr %dst, i64 %iv270 store i64 %iv, ptr %gep271 %iv.next = add i64 %iv, 1272 %ec = icmp eq i64 %iv, 0273 br i1 %ec, label %exit, label %loop274 275exit:276 ret void277}278 279define void @loop_never_executes_precondition_order_2_predicates_flipped(i64 %start, ptr %dst) {280; CHECK-LABEL: define void @loop_never_executes_precondition_order_2_predicates_flipped(281; CHECK-SAME: i64 [[START:%.*]], ptr [[DST:%.*]]) {282; CHECK-NEXT: [[ENTRY:.*:]]283; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[START]], 1284; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i64 [[MUL]], [[START]]285; CHECK-NEXT: br i1 [[PRE_1]], label %[[PH:.*]], label %[[EXIT:.*]]286; CHECK: [[PH]]:287; CHECK-NEXT: [[PRE_0:%.*]] = icmp ule i64 [[START]], 1288; CHECK-NEXT: br i1 [[PRE_0]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT]]289; CHECK: [[LOOP_PREHEADER]]:290; CHECK-NEXT: br label %[[LOOP:.*]]291; CHECK: [[LOOP]]:292; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]293; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV]]294; CHECK-NEXT: store i64 [[IV]], ptr [[GEP]], align 4295; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1296; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 0297; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP]]298; CHECK: [[EXIT_LOOPEXIT]]:299; CHECK-NEXT: br label %[[EXIT]]300; CHECK: [[EXIT]]:301; CHECK-NEXT: ret void302;303entry:304 %mul = shl i64 %start, 1305 %pre.1 = icmp slt i64 %mul, %start306 br i1 %pre.1, label %ph, label %exit307 308ph:309 %pre.0 = icmp ule i64 %start, 1310 br i1 %pre.0, label %loop, label %exit311 312loop:313 %iv = phi i64 [ %start, %ph ], [ %iv.next, %loop ]314 %gep = getelementptr inbounds i64, ptr %dst, i64 %iv315 store i64 %iv, ptr %gep316 %iv.next = add i64 %iv, 1317 %ec = icmp eq i64 %iv, 0318 br i1 %ec, label %exit, label %loop319 320exit:321 ret void322}323