311 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=loop-vectorize,instcombine -force-vector-width=2 -force-vector-interleave=1 -enable-interleaved-mem-accesses < %s | FileCheck %s3; RUN: opt -S -passes=loop-vectorize,instcombine -force-vector-width=2 -force-vector-interleave=1 -enable-interleaved-mem-accesses -enable-masked-interleaved-mem-accesses < %s | FileCheck %s4 5target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"6%pair = type { i64, i64 }7 8; Ensure that we vectorize the interleaved load group even though the loop9; contains a conditional store. The store group contains gaps and is not10; vectorized.11;12;13;14;15;16 17define void @interleaved_with_cond_store_0(ptr %p, i64 %x, i64 %n) {18; CHECK-LABEL: @interleaved_with_cond_store_0(19; CHECK-NEXT: entry:20; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp slt i64 [[N:%.*]], 321; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]22; CHECK: vector.ph:23; CHECK-NEXT: [[DOTNEG:%.*]] = or i64 [[N]], -224; CHECK-NEXT: [[N_VEC:%.*]] = add nsw i64 [[DOTNEG]], [[N]]25; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 026; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer27; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]28; CHECK: vector.body:29; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]30; CHECK-NEXT: [[DOTSPLIT:%.*]] = getelementptr inbounds [[PAIR:%.*]], ptr [[P:%.*]], i64 [[INDEX]]31; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT]], i64 832; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <4 x i64>, ptr [[TMP0]], align 833; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <4 x i64> [[WIDE_VEC]], <4 x i64> poison, <2 x i32> <i32 0, i32 2>34; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[STRIDED_VEC]], [[BROADCAST_SPLAT]]35; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x i1> [[TMP1]], i64 036; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]37; CHECK: pred.store.if:38; CHECK-NEXT: [[DOTSPLIT3:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[INDEX]]39; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT3]], i64 840; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 041; CHECK-NEXT: store i64 [[TMP4]], ptr [[TMP3]], align 842; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]43; CHECK: pred.store.continue:44; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP1]], i64 145; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]46; CHECK: pred.store.if1:47; CHECK-NEXT: [[TMP6:%.*]] = getelementptr [[PAIR]], ptr [[P]], i64 [[INDEX]]48; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP6]], i64 2449; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 250; CHECK-NEXT: store i64 [[TMP8]], ptr [[TMP7]], align 851; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]]52; CHECK: pred.store.continue2:53; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 254; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]55; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]56; CHECK: middle.block:57; CHECK-NEXT: br label [[SCALAR_PH]]58; CHECK: scalar.ph:59; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]60; CHECK-NEXT: br label [[FOR_BODY:%.*]]61; CHECK: for.body:62; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[IF_MERGE:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]63; CHECK-NEXT: [[P_1_SPLIT:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[I]]64; CHECK-NEXT: [[P_1:%.*]] = getelementptr inbounds nuw i8, ptr [[P_1_SPLIT]], i64 865; CHECK-NEXT: [[TMP10:%.*]] = load i64, ptr [[P_1]], align 866; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], [[X]]67; CHECK-NEXT: br i1 [[TMP11]], label [[IF_THEN:%.*]], label [[IF_MERGE]]68; CHECK: if.then:69; CHECK-NEXT: store i64 [[TMP10]], ptr [[P_1]], align 870; CHECK-NEXT: br label [[IF_MERGE]]71; CHECK: if.merge:72; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 173; CHECK-NEXT: [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]74; CHECK-NEXT: br i1 [[COND]], label [[FOR_BODY]], label [[FOR_END:%.*]], !llvm.loop [[LOOP3:![0-9]+]]75; CHECK: for.end:76; CHECK-NEXT: ret void77;78entry:79 br label %for.body80 81for.body:82 %i = phi i64 [ %i.next, %if.merge ], [ 0, %entry ]83 %p.1 = getelementptr inbounds %pair, ptr %p, i64 %i, i32 184 %0 = load i64, ptr %p.1, align 885 %1 = icmp eq i64 %0, %x86 br i1 %1, label %if.then, label %if.merge87 88if.then:89 store i64 %0, ptr %p.1, align 890 br label %if.merge91 92if.merge:93 %i.next = add nuw nsw i64 %i, 194 %cond = icmp slt i64 %i.next, %n95 br i1 %cond, label %for.body, label %for.end96 97for.end:98 ret void99}100 101; Ensure that we don't form a single interleaved group for the two loads. The102; conditional store prevents the second load from being hoisted. The two load103; groups are separately vectorized. The store group contains gaps and is not104; vectorized.105;106;107;108;109;110;111 112define void @interleaved_with_cond_store_1(ptr %p, i64 %x, i64 %n) {113; CHECK-LABEL: @interleaved_with_cond_store_1(114; CHECK-NEXT: entry:115; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp slt i64 [[N:%.*]], 3116; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]117; CHECK: vector.ph:118; CHECK-NEXT: [[DOTNEG:%.*]] = or i64 [[N]], -2119; CHECK-NEXT: [[N_VEC:%.*]] = add nsw i64 [[DOTNEG]], [[N]]120; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0121; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer122; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]123; CHECK: vector.body:124; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]125; CHECK-NEXT: [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1126; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[PAIR:%.*]], ptr [[P:%.*]], i64 [[INDEX]]127; CHECK-NEXT: [[DOTSPLIT:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[INDEX]]128; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT]], i64 8129; CHECK-NEXT: [[DOTSPLIT5:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[TMP0]]130; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT5]], i64 8131; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8132; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <4 x i64> [[WIDE_VEC]], <4 x i64> poison, <2 x i32> <i32 0, i32 2>133; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <2 x i64> [[STRIDED_VEC]], [[BROADCAST_SPLAT]]134; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i64 0135; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]136; CHECK: pred.store.if:137; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[INDEX]]138; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 0139; CHECK-NEXT: store i64 [[TMP7]], ptr [[TMP6]], align 8140; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]141; CHECK: pred.store.continue:142; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP4]], i64 1143; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]144; CHECK: pred.store.if1:145; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[TMP0]]146; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 2147; CHECK-NEXT: store i64 [[TMP10]], ptr [[TMP9]], align 8148; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]]149; CHECK: pred.store.continue2:150; CHECK-NEXT: [[WIDE_VEC3:%.*]] = load <4 x i64>, ptr [[TMP1]], align 8151; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[WIDE_VEC3]], i64 0152; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[WIDE_VEC3]], i64 2153; CHECK-NEXT: store i64 [[TMP11]], ptr [[TMP2]], align 8154; CHECK-NEXT: store i64 [[TMP12]], ptr [[TMP3]], align 8155; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2156; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]157; CHECK-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]158; CHECK: middle.block:159; CHECK-NEXT: br label [[SCALAR_PH]]160; CHECK: scalar.ph:161; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]162; CHECK-NEXT: br label [[FOR_BODY:%.*]]163; CHECK: for.body:164; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[IF_MERGE:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]165; CHECK-NEXT: [[P_0:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[I]]166; CHECK-NEXT: [[P_1_SPLIT:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[I]]167; CHECK-NEXT: [[P_1:%.*]] = getelementptr inbounds nuw i8, ptr [[P_1_SPLIT]], i64 8168; CHECK-NEXT: [[TMP14:%.*]] = load i64, ptr [[P_1]], align 8169; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[TMP14]], [[X]]170; CHECK-NEXT: br i1 [[TMP15]], label [[IF_THEN:%.*]], label [[IF_MERGE]]171; CHECK: if.then:172; CHECK-NEXT: store i64 [[TMP14]], ptr [[P_0]], align 8173; CHECK-NEXT: br label [[IF_MERGE]]174; CHECK: if.merge:175; CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr [[P_0]], align 8176; CHECK-NEXT: store i64 [[TMP16]], ptr [[P_1]], align 8177; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1178; CHECK-NEXT: [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]179; CHECK-NEXT: br i1 [[COND]], label [[FOR_BODY]], label [[FOR_END:%.*]], !llvm.loop [[LOOP5:![0-9]+]]180; CHECK: for.end:181; CHECK-NEXT: ret void182;183entry:184 br label %for.body185 186for.body:187 %i = phi i64 [ %i.next, %if.merge ], [ 0, %entry ]188 %p.0 = getelementptr inbounds %pair, ptr %p, i64 %i, i32 0189 %p.1 = getelementptr inbounds %pair, ptr %p, i64 %i, i32 1190 %0 = load i64, ptr %p.1, align 8191 %1 = icmp eq i64 %0, %x192 br i1 %1, label %if.then, label %if.merge193 194if.then:195 store i64 %0, ptr %p.0, align 8196 br label %if.merge197 198if.merge:199 %2 = load i64, ptr %p.0, align 8200 store i64 %2, ptr %p.1, align 8201 %i.next = add nuw nsw i64 %i, 1202 %cond = icmp slt i64 %i.next, %n203 br i1 %cond, label %for.body, label %for.end204 205for.end:206 ret void207}208 209; Ensure that we don't create a single interleaved group for the two stores.210; The second store is conditional and we can't sink the first store inside the211; predicated block. The load group is vectorized, and the store groups contain212; gaps and are not vectorized.213;214;215;216;217;218 219define void @interleaved_with_cond_store_2(ptr %p, i64 %x, i64 %n) {220; CHECK-LABEL: @interleaved_with_cond_store_2(221; CHECK-NEXT: entry:222; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp slt i64 [[N:%.*]], 3223; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]224; CHECK: vector.ph:225; CHECK-NEXT: [[DOTNEG:%.*]] = or i64 [[N]], -2226; CHECK-NEXT: [[N_VEC:%.*]] = add nsw i64 [[DOTNEG]], [[N]]227; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0228; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer229; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]230; CHECK: vector.body:231; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]232; CHECK-NEXT: [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1233; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[PAIR:%.*]], ptr [[P:%.*]], i64 [[INDEX]]234; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[TMP0]]235; CHECK-NEXT: [[DOTSPLIT:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[INDEX]]236; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT]], i64 8237; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8238; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <4 x i64> [[WIDE_VEC]], <4 x i64> poison, <2 x i32> <i32 0, i32 2>239; CHECK-NEXT: store i64 [[X]], ptr [[TMP1]], align 8240; CHECK-NEXT: store i64 [[X]], ptr [[TMP2]], align 8241; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <2 x i64> [[STRIDED_VEC]], [[BROADCAST_SPLAT]]242; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i64 0243; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]244; CHECK: pred.store.if:245; CHECK-NEXT: [[DOTSPLIT3:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[INDEX]]246; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT3]], i64 8247; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 0248; CHECK-NEXT: store i64 [[TMP7]], ptr [[TMP6]], align 8249; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]250; CHECK: pred.store.continue:251; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP4]], i64 1252; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]253; CHECK: pred.store.if1:254; CHECK-NEXT: [[DOTSPLIT4:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[TMP0]]255; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTSPLIT4]], i64 8256; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[WIDE_VEC]], i64 2257; CHECK-NEXT: store i64 [[TMP10]], ptr [[TMP9]], align 8258; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]]259; CHECK: pred.store.continue2:260; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2261; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]262; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]263; CHECK: middle.block:264; CHECK-NEXT: br label [[SCALAR_PH]]265; CHECK: scalar.ph:266; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]267; CHECK-NEXT: br label [[FOR_BODY:%.*]]268; CHECK: for.body:269; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[IF_MERGE:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]270; CHECK-NEXT: [[P_0:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[I]]271; CHECK-NEXT: [[P_1_SPLIT:%.*]] = getelementptr inbounds [[PAIR]], ptr [[P]], i64 [[I]]272; CHECK-NEXT: [[P_1:%.*]] = getelementptr inbounds nuw i8, ptr [[P_1_SPLIT]], i64 8273; CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr [[P_1]], align 8274; CHECK-NEXT: store i64 [[X]], ptr [[P_0]], align 8275; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i64 [[TMP12]], [[X]]276; CHECK-NEXT: br i1 [[TMP13]], label [[IF_THEN:%.*]], label [[IF_MERGE]]277; CHECK: if.then:278; CHECK-NEXT: store i64 [[TMP12]], ptr [[P_1]], align 8279; CHECK-NEXT: br label [[IF_MERGE]]280; CHECK: if.merge:281; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1282; CHECK-NEXT: [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]283; CHECK-NEXT: br i1 [[COND]], label [[FOR_BODY]], label [[FOR_END:%.*]], !llvm.loop [[LOOP7:![0-9]+]]284; CHECK: for.end:285; CHECK-NEXT: ret void286;287entry:288 br label %for.body289 290for.body:291 %i = phi i64 [ %i.next, %if.merge ], [ 0, %entry ]292 %p.0 = getelementptr inbounds %pair, ptr %p, i64 %i, i32 0293 %p.1 = getelementptr inbounds %pair, ptr %p, i64 %i, i32 1294 %0 = load i64, ptr %p.1, align 8295 store i64 %x, ptr %p.0, align 8296 %1 = icmp eq i64 %0, %x297 br i1 %1, label %if.then, label %if.merge298 299if.then:300 store i64 %0, ptr %p.1, align 8301 br label %if.merge302 303if.merge:304 %i.next = add nuw nsw i64 %i, 1305 %cond = icmp slt i64 %i.next, %n306 br i1 %cond, label %for.body, label %for.end307 308for.end:309 ret void310}311