736 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes="loop-reduce,loop-term-fold" -S | FileCheck %s3 4target datalayout = "e-p:64:64:64-n64"5 6define void @const_tripcount(ptr %a) {7; CHECK-LABEL: @const_tripcount(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8410; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 160011; CHECK-NEXT: br label [[FOR_BODY:%.*]]12; CHECK: for.body:13; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]14; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 415; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 416; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]17; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]18; CHECK: for.end:19; CHECK-NEXT: ret void20;21entry:22 %uglygep = getelementptr i8, ptr %a, i64 8423 br label %for.body24 25for.body: ; preds = %for.body, %entry26 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]27 %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]28 store i32 1, ptr %lsr.iv1, align 429 %lsr.iv.next = add nsw i64 %lsr.iv, -130 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 431 %exitcond.not = icmp eq i64 %lsr.iv.next, 032 br i1 %exitcond.not, label %for.end, label %for.body33 34for.end: ; preds = %for.body35 ret void36}37 38define void @runtime_tripcount(ptr %a, i32 %N) {39; CHECK-LABEL: @runtime_tripcount(40; CHECK-NEXT: entry:41; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 8442; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[N:%.*]], -143; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i6444; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP1]], 245; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 8846; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP3]]47; CHECK-NEXT: br label [[FOR_BODY:%.*]]48; CHECK: for.body:49; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]50; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 451; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 452; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]53; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]54; CHECK: for.end:55; CHECK-NEXT: ret void56;57entry:58 %uglygep = getelementptr i8, ptr %a, i32 8459 br label %for.body60 61for.body: ; preds = %for.body, %entry62 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]63 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ %N, %entry ]64 store i32 1, ptr %lsr.iv1, align 465 %lsr.iv.next = add nsw i32 %lsr.iv, -166 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 467 %exitcond.not = icmp eq i32 %lsr.iv.next, 068 br i1 %exitcond.not, label %for.end, label %for.body69 70for.end: ; preds = %for.body71 ret void72}73 74; In this case, the i8 IVs increment *isn't* nsw. As a result, a N of 075; is well defined, and thus the post-inc starts at 255.76define void @wrap_around(ptr %a, i8 %N) {77; CHECK-LABEL: @wrap_around(78; CHECK-NEXT: entry:79; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -180; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i6481; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP1]], 282; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 483; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 [[TMP3]]84; CHECK-NEXT: br label [[FOR_BODY:%.*]]85; CHECK: for.body:86; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[A]], [[ENTRY:%.*]] ]87; CHECK-NEXT: store i8 1, ptr [[LSR_IV1]], align 488; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 489; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]90; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]91; CHECK: for.end:92; CHECK-NEXT: ret void93;94entry:95 br label %for.body96 97for.body: ; preds = %for.body, %entry98 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]99 %lsr.iv = phi i8 [ %lsr.iv.next, %for.body ], [ %N, %entry ]100 store i8 1, ptr %lsr.iv1, align 4101 %lsr.iv.next = add i8 %lsr.iv, -1102 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4103 %exitcond.not = icmp eq i8 %lsr.iv.next, 0104 br i1 %exitcond.not, label %for.end, label %for.body105 106for.end: ; preds = %for.body107 ret void108}109 110; The replacing AddRec IV is a complicated AddRec. This tests whether111; the fold terminating condition transformation is writing new terminating112; condition in the correct type.113define void @ptr_of_ptr_addrec(ptr %ptrptr, i32 %length) {114; CHECK-LABEL: @ptr_of_ptr_addrec(115; CHECK-NEXT: entry:116; CHECK-NEXT: [[START_PTRPTR1:%.*]] = getelementptr inbounds ptr, ptr [[START_PTRPTR:%.*]]117; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1118; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64119; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP1]], 3120; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 8121; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[START_PTRPTR]], i64 [[TMP3]]122; CHECK-NEXT: br label [[FOR_BODY:%.*]]123; CHECK: for.body:124; CHECK-NEXT: [[IT_04:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[START_PTRPTR1]], [[ENTRY:%.*]] ]125; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[IT_04]], align 8126; CHECK-NEXT: tail call void @foo(ptr [[TMP4]])127; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr ptr, ptr [[IT_04]], i64 1128; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[INCDEC_PTR]], [[SCEVGEP]]129; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]130; CHECK: for.end:131; CHECK-NEXT: ret void132;133entry:134 %start.ptrptr = getelementptr inbounds ptr, ptr %ptrptr135 br label %for.body136 137for.body: ; preds = %entry, %for.body138 %i.05 = phi i32 [ %dec, %for.body ], [ %length, %entry ]139 %it.04 = phi ptr [ %incdec.ptr, %for.body ], [ %start.ptrptr, %entry ]140 %0 = load ptr, ptr %it.04, align 8141 tail call void @foo(ptr %0)142 %incdec.ptr = getelementptr inbounds ptr, ptr %it.04, i64 1143 %dec = add nsw i32 %i.05, -1144 %tobool.not = icmp eq i32 %dec, 0145 br i1 %tobool.not, label %for.end, label %for.body146 147for.end: ; preds = %for.body148 ret void149}150 151declare void @foo(ptr)152 153define void @iv_start_non_preheader(ptr %mark, i32 signext %length) {154; CHECK-LABEL: @iv_start_non_preheader(155; CHECK-NEXT: entry:156; CHECK-NEXT: [[TOBOOL_NOT3:%.*]] = icmp eq i32 [[LENGTH:%.*]], 0157; CHECK-NEXT: br i1 [[TOBOOL_NOT3]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]158; CHECK: for.body.preheader:159; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH]], -1160; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64161; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP1]], 3162; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 8163; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[MARK:%.*]], i64 [[TMP3]]164; CHECK-NEXT: br label [[FOR_BODY:%.*]]165; CHECK: for.cond.cleanup.loopexit:166; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]167; CHECK: for.cond.cleanup:168; CHECK-NEXT: ret void169; CHECK: for.body:170; CHECK-NEXT: [[DST_04:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[MARK]], [[FOR_BODY_PREHEADER]] ]171; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DST_04]], align 8172; CHECK-NEXT: [[TMP5:%.*]] = call ptr @foo(ptr [[TMP4]])173; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr ptr, ptr [[DST_04]], i64 1174; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[INCDEC_PTR]], [[SCEVGEP]]175; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]176;177entry:178 %tobool.not3 = icmp eq i32 %length, 0179 br i1 %tobool.not3, label %for.cond.cleanup, label %for.body180 181for.cond.cleanup: ; preds = %for.body, %entry182 ret void183 184for.body: ; preds = %entry, %for.body185 %i.05 = phi i32 [ %dec, %for.body ], [ %length, %entry ]186 %dst.04 = phi ptr [ %incdec.ptr, %for.body ], [ %mark, %entry ]187 %0 = load ptr, ptr %dst.04, align 8188 call ptr @foo(ptr %0)189 %incdec.ptr = getelementptr inbounds ptr, ptr %dst.04, i64 1190 %dec = add nsw i32 %i.05, -1191 %tobool.not = icmp eq i32 %dec, 0192 br i1 %tobool.not, label %for.cond.cleanup, label %for.body193}194 195; Consider the case where %a points to a buffer exactly 17 bytes long. The196; loop below will access bytes: 0, 4, 8, and 16. The key bit is that we197; advance the pointer IV by *4* each time, and thus on the iteration we write198; byte 16, %uglygep2 (the pointer increment) is past the end of the underlying199; storage and thus violates the inbounds requirements. As a result, %uglygep2200; is poison on the final iteration. If we insert a branch on that value201; (without stripping the poison flag), we have inserted undefined behavior202; where it did not previously exist.203define void @inbounds_poison_use(ptr %a) {204; CHECK-LABEL: @inbounds_poison_use(205; CHECK-NEXT: entry:206; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 16207; CHECK-NEXT: br label [[FOR_BODY:%.*]]208; CHECK: for.body:209; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[A]], [[ENTRY:%.*]] ]210; CHECK-NEXT: store i8 1, ptr [[LSR_IV1]], align 4211; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 4212; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]213; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]214; CHECK: for.end:215; CHECK-NEXT: ret void216;217entry:218 br label %for.body219 220for.body: ; preds = %for.body, %entry221 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]222 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 4, %entry ]223 store i8 1, ptr %lsr.iv1, align 4224 %lsr.iv.next = add nsw i32 %lsr.iv, -1225 %uglygep2 = getelementptr inbounds i8, ptr %lsr.iv1, i64 4226 %exitcond.not = icmp eq i32 %lsr.iv.next, 0227 br i1 %exitcond.not, label %for.end, label %for.body228 229for.end: ; preds = %for.body230 ret void231}232 233; In this case, the integer IV has a larger bitwidth than the pointer IV.234; This means that the smaller IV may wrap around multiple times before235; the original loop exit is taken.236define void @iv_size(ptr %a, i128 %N) {237; CHECK-LABEL: @iv_size(238; CHECK-NEXT: entry:239; CHECK-NEXT: br label [[FOR_BODY:%.*]]240; CHECK: for.body:241; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]242; CHECK-NEXT: [[LSR_IV:%.*]] = phi i128 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[N:%.*]], [[ENTRY]] ]243; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4244; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i128 [[LSR_IV]], -1245; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 4246; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i128 [[LSR_IV_NEXT]], 0247; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]248; CHECK: for.end:249; CHECK-NEXT: ret void250;251entry:252 br label %for.body253 254for.body: ; preds = %for.body, %entry255 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]256 %lsr.iv = phi i128 [ %lsr.iv.next, %for.body ], [ %N, %entry ]257 store i32 1, ptr %lsr.iv1, align 4258 %lsr.iv.next = add nsw i128 %lsr.iv, -1259 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4260 %exitcond.not = icmp eq i128 %lsr.iv.next, 0261 br i1 %exitcond.not, label %for.end, label %for.body262 263for.end: ; preds = %for.body264 ret void265}266 267; To check correct folding not equality terminating condition268; Due to SLE offset must be - 1600269define void @IcmpSle(ptr %a) {270; CHECK-LABEL: @IcmpSle(271; CHECK-NEXT: entry:272; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 84273; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 1600274; CHECK-NEXT: br label [[FOR_BODY:%.*]]275; CHECK: for.body:276; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]277; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4278; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 4279; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]280; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]281; CHECK: for.end:282; CHECK-NEXT: ret void283;284entry:285 %uglygep = getelementptr i8, ptr %a, i32 84286 br label %for.body287 288for.body: ; preds = %for.body, %entry289 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]290 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 379, %entry ]291 store i32 1, ptr %lsr.iv1, align 4292 %lsr.iv.next = add nsw i32 %lsr.iv, -1293 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 4294 %exitcond.not = icmp sle i32 %lsr.iv.next, 0295 br i1 %exitcond.not, label %for.end, label %for.body296 297for.end: ; preds = %for.body298 ret void299}300 301; Due to SLT offset must be - 1604302define void @IcmpSlt(ptr %a) {303; CHECK-LABEL: @IcmpSlt(304; CHECK-NEXT: entry:305; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 84306; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 1604307; CHECK-NEXT: br label [[FOR_BODY:%.*]]308; CHECK: for.body:309; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]310; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4311; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 4312; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]313; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]314; CHECK: for.end:315; CHECK-NEXT: ret void316;317entry:318 %uglygep = getelementptr i8, ptr %a, i32 84319 br label %for.body320 321for.body: ; preds = %for.body, %entry322 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]323 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 379, %entry ]324 store i32 1, ptr %lsr.iv1, align 4325 %lsr.iv.next = add nsw i32 %lsr.iv, -1326 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 4327 %exitcond.not = icmp slt i32 %lsr.iv.next, 0328 br i1 %exitcond.not, label %for.end, label %for.body329 330for.end: ; preds = %for.body331 ret void332}333 334; Invert predicate and branches335define void @IcmpSgt(ptr %a) {336; CHECK-LABEL: @IcmpSgt(337; CHECK-NEXT: entry:338; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 84339; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 1600340; CHECK-NEXT: br label [[FOR_BODY:%.*]]341; CHECK: for.body:342; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]343; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4344; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 4345; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]346; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]347; CHECK: for.end:348; CHECK-NEXT: ret void349;350entry:351 %uglygep = getelementptr i8, ptr %a, i32 84352 br label %for.body353 354for.body: ; preds = %for.body, %entry355 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]356 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 379, %entry ]357 store i32 1, ptr %lsr.iv1, align 4358 %lsr.iv.next = add nsw i32 %lsr.iv, -1359 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 4360 %exitcond.not = icmp sgt i32 %lsr.iv.next, 0361 br i1 %exitcond.not, label %for.body, label %for.end362 363for.end: ; preds = %for.body364 ret void365}366 367; Invert predicate and branches368define void @SeveralLoopLatch(ptr %a) {369; CHECK-LABEL: @SeveralLoopLatch(370; CHECK-NEXT: entry:371; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 84372; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 1600373; CHECK-NEXT: br label [[FOR_BODY:%.*]]374; CHECK: for.body:375; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[ANOTHER_BRANCH:%.*]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]376; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4377; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 4378; CHECK-NEXT: br label [[ANOTHER_BRANCH]]379; CHECK: another.branch:380; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]381; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]382; CHECK: for.end:383; CHECK-NEXT: ret void384;385entry:386 %uglygep = getelementptr i8, ptr %a, i32 84387 br label %for.body388 389for.body: ; preds = %another.branch, %entry390 %lsr.iv1 = phi ptr [ %uglygep2, %another.branch ], [ %uglygep, %entry ]391 %lsr.iv = phi i32 [ %lsr.iv.next, %another.branch ], [ 379, %entry ]392 store i32 1, ptr %lsr.iv1, align 4393 %lsr.iv.next = add nsw i32 %lsr.iv, -1394 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 4395 br label %another.branch396 397another.branch:398 %exitcond.not = icmp sgt i32 %lsr.iv.next, 0399 br i1 %exitcond.not, label %for.body, label %for.end400 401for.end: ; preds = %for.body402 ret void403}404 405; Invert branch in SeveralLoopLatch406define void @SeveralLoopLatch2(ptr %a) {407; CHECK-LABEL: @SeveralLoopLatch2(408; CHECK-NEXT: entry:409; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 84410; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 1600411; CHECK-NEXT: br label [[FOR_BODY:%.*]]412; CHECK: for.body:413; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[ANOTHER_BRANCH:%.*]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]414; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4415; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 4416; CHECK-NEXT: br label [[ANOTHER_BRANCH]]417; CHECK: another.branch:418; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]419; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]420; CHECK: for.end:421; CHECK-NEXT: ret void422;423entry:424 %uglygep = getelementptr i8, ptr %a, i32 84425 br label %for.body426 427for.body: ; preds = %another.branch, %entry428 %lsr.iv1 = phi ptr [ %uglygep2, %another.branch ], [ %uglygep, %entry ]429 %lsr.iv = phi i32 [ %lsr.iv.next, %another.branch ], [ 379, %entry ]430 store i32 1, ptr %lsr.iv1, align 4431 %lsr.iv.next = add nsw i32 %lsr.iv, -1432 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 4433 br label %another.branch434 435another.branch:436 %exitcond.not = icmp sle i32 %lsr.iv.next, 0437 br i1 %exitcond.not, label %for.end, label %for.body438 439for.end: ; preds = %for.body440 ret void441}442 443 444define void @non_branch_terminator(ptr %a) {445; CHECK-LABEL: @non_branch_terminator(446; CHECK-NEXT: entry:447; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84448; CHECK-NEXT: br label [[FOR_BODY:%.*]]449; CHECK: for.body:450; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i64 [ [[LSR_IV_NEXT3:%.*]], [[FOR_BODY]] ], [ 378, [[ENTRY:%.*]] ]451; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY]] ]452; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4453; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 4454; CHECK-NEXT: [[LSR_IV_NEXT3]] = add nsw i64 [[LSR_IV2]], -1455; CHECK-NEXT: switch i64 [[LSR_IV2]], label [[FOR_BODY]] [456; CHECK-NEXT: i64 0, label [[FOR_END:%.*]]457; CHECK-NEXT: ]458; CHECK: for.end:459; CHECK-NEXT: ret void460;461entry:462 %uglygep = getelementptr i8, ptr %a, i64 84463 br label %for.body464 465for.body: ; preds = %for.body, %entry466 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]467 %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]468 store i32 1, ptr %lsr.iv1, align 4469 %lsr.iv.next = add nsw i64 %lsr.iv, -1470 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4471 switch i64 %lsr.iv.next, label %for.body [i64 0, label %for.end]472 473for.end: ; preds = %for.body474 ret void475}476 477;; The next step of tests exercise various cases with the expansion478;; budget and different trip counts or estimated trip counts.479 480define void @profiled_short_tc(ptr %a, i32 %offset, i32 %n) {481; CHECK-LABEL: @profiled_short_tc(482; CHECK-NEXT: entry:483; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1484; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84485; CHECK-NEXT: br label [[FOR_BODY:%.*]]486; CHECK: for.body:487; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]488; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]489; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4490; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], 1491; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]492; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], [[N:%.*]]493; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]], !prof [[PROF0:![0-9]+]]494; CHECK: for.end:495; CHECK-NEXT: ret void496;497entry:498 %offset.nonzero = or i32 %offset, 1499 %uglygep = getelementptr i8, ptr %a, i64 84500 br label %for.body501 502for.body: ; preds = %for.body, %entry503 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]504 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]505 store i32 1, ptr %lsr.iv1, align 4506 %lsr.iv.next = add nsw i32 %lsr.iv, 1507 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero508 %exitcond.not = icmp eq i32 %lsr.iv.next, %n509 br i1 %exitcond.not, label %for.end, label %for.body, !prof !{!"branch_weights", i32 1, i32 3}510 511for.end: ; preds = %for.body512 ret void513}514 515define void @profiled_long_tc(ptr %a, i32 %offset, i32 %n) {516; CHECK-LABEL: @profiled_long_tc(517; CHECK-NEXT: entry:518; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1519; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84520; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1521; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64522; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1523; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[OFFSET_NONZERO]] to i64524; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP2]], [[TMP3]]525; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[TMP4]], 84526; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP5]]527; CHECK-NEXT: br label [[FOR_BODY:%.*]]528; CHECK: for.body:529; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]530; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4531; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]532; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]533; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]], !prof [[PROF1:![0-9]+]]534; CHECK: for.end:535; CHECK-NEXT: ret void536;537entry:538 %offset.nonzero = or i32 %offset, 1539 %uglygep = getelementptr i8, ptr %a, i64 84540 br label %for.body541 542for.body: ; preds = %for.body, %entry543 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]544 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]545 store i32 1, ptr %lsr.iv1, align 4546 %lsr.iv.next = add nsw i32 %lsr.iv, 1547 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero548 %exitcond.not = icmp eq i32 %lsr.iv.next, %n549 br i1 %exitcond.not, label %for.end, label %for.body, !prof !{!"branch_weights", i32 1, i32 300}550 551for.end: ; preds = %for.body552 ret void553}554 555define void @unknown_tc(ptr %a, i32 %offset, i32 %n) {556; CHECK-LABEL: @unknown_tc(557; CHECK-NEXT: entry:558; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1559; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84560; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1561; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64562; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1563; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[OFFSET_NONZERO]] to i64564; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP2]], [[TMP3]]565; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[TMP4]], 84566; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP5]]567; CHECK-NEXT: br label [[FOR_BODY:%.*]]568; CHECK: for.body:569; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]570; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4571; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]572; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]573; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]574; CHECK: for.end:575; CHECK-NEXT: ret void576;577entry:578 %offset.nonzero = or i32 %offset, 1579 %uglygep = getelementptr i8, ptr %a, i64 84580 br label %for.body581 582for.body: ; preds = %for.body, %entry583 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]584 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]585 store i32 1, ptr %lsr.iv1, align 4586 %lsr.iv.next = add nsw i32 %lsr.iv, 1587 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero588 %exitcond.not = icmp eq i32 %lsr.iv.next, %n589 br i1 %exitcond.not, label %for.end, label %for.body590 591for.end: ; preds = %for.body592 ret void593}594 595define void @unknown_tc2(ptr %a, i32 %offset, i32 %n, i32 %step) mustprogress {596; CHECK-LABEL: @unknown_tc2(597; CHECK-NEXT: entry:598; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1599; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84600; CHECK-NEXT: br label [[FOR_BODY:%.*]]601; CHECK: for.body:602; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]603; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]604; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4605; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], [[STEP:%.*]]606; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]607; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp sge i32 [[LSR_IV_NEXT]], [[N:%.*]]608; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]609; CHECK: for.end:610; CHECK-NEXT: ret void611;612entry:613 %offset.nonzero = or i32 %offset, 1614 %uglygep = getelementptr i8, ptr %a, i64 84615 br label %for.body616 617for.body: ; preds = %for.body, %entry618 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]619 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]620 store i32 1, ptr %lsr.iv1, align 4621 %lsr.iv.next = add nsw i32 %lsr.iv, %step622 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero623 %exitcond.not = icmp sge i32 %lsr.iv.next, %n624 br i1 %exitcond.not, label %for.end, label %for.body625 626for.end: ; preds = %for.body627 ret void628}629 630define void @small_tc_trivial_loop(ptr %a, i32 %offset) {631; CHECK-LABEL: @small_tc_trivial_loop(632; CHECK-NEXT: entry:633; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1634; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84635; CHECK-NEXT: br label [[FOR_BODY:%.*]]636; CHECK: for.body:637; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]638; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]639; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4640; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], 1641; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]642; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 1643; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]644; CHECK: for.end:645; CHECK-NEXT: ret void646;647entry:648 %offset.nonzero = or i32 %offset, 1649 %uglygep = getelementptr i8, ptr %a, i64 84650 br label %for.body651 652for.body: ; preds = %for.body, %entry653 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]654 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]655 store i32 1, ptr %lsr.iv1, align 4656 %lsr.iv.next = add nsw i32 %lsr.iv, 1657 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero658 %exitcond.not = icmp eq i32 %lsr.iv.next, 1659 br i1 %exitcond.not, label %for.end, label %for.body660 661for.end: ; preds = %for.body662 ret void663}664 665define void @small_tc_below_threshold(ptr %a, i32 %offset) {666; CHECK-LABEL: @small_tc_below_threshold(667; CHECK-NEXT: entry:668; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1669; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84670; CHECK-NEXT: br label [[FOR_BODY:%.*]]671; CHECK: for.body:672; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]673; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]674; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4675; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], 1676; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]677; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 2678; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]679; CHECK: for.end:680; CHECK-NEXT: ret void681;682entry:683 %offset.nonzero = or i32 %offset, 1684 %uglygep = getelementptr i8, ptr %a, i64 84685 br label %for.body686 687for.body: ; preds = %for.body, %entry688 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]689 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]690 store i32 1, ptr %lsr.iv1, align 4691 %lsr.iv.next = add nsw i32 %lsr.iv, 1692 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero693 %exitcond.not = icmp eq i32 %lsr.iv.next, 2694 br i1 %exitcond.not, label %for.end, label %for.body695 696for.end: ; preds = %for.body697 ret void698}699 700define void @small_tc_above_threshold(ptr %a, i32 %offset) {701; CHECK-LABEL: @small_tc_above_threshold(702; CHECK-NEXT: entry:703; CHECK-NEXT: [[OFFSET_NONZERO:%.*]] = or i32 [[OFFSET:%.*]], 1704; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 84705; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[OFFSET_NONZERO]] to i64706; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i64 [[TMP0]], 10707; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[TMP1]], 84708; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]709; CHECK-NEXT: br label [[FOR_BODY:%.*]]710; CHECK: for.body:711; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP2:%.*]], [[FOR_BODY]] ], [ [[UGLYGEP]], [[ENTRY:%.*]] ]712; CHECK-NEXT: store i32 1, ptr [[LSR_IV1]], align 4713; CHECK-NEXT: [[UGLYGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i32 [[OFFSET_NONZERO]]714; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[UGLYGEP2]], [[SCEVGEP]]715; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[FOR_END:%.*]], label [[FOR_BODY]]716; CHECK: for.end:717; CHECK-NEXT: ret void718;719entry:720 %offset.nonzero = or i32 %offset, 1721 %uglygep = getelementptr i8, ptr %a, i64 84722 br label %for.body723 724for.body: ; preds = %for.body, %entry725 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %uglygep, %entry ]726 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 0, %entry ]727 store i32 1, ptr %lsr.iv1, align 4728 %lsr.iv.next = add nsw i32 %lsr.iv, 1729 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i32 %offset.nonzero730 %exitcond.not = icmp eq i32 %lsr.iv.next, 10731 br i1 %exitcond.not, label %for.end, label %for.body732 733for.end: ; preds = %for.body734 ret void735}736