1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -loop-unroll -unroll-runtime=true -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s 3; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -loop-unroll -unroll-runtime=true -verify-dom-info -unroll-runtime-multi-exit=false -verify-loop-info -S | FileCheck %s -check-prefix=NOUNROLL 4 5; this tests when unrolling multiple exit loop occurs by default (i.e. without specifying -unroll-runtime-multi-exit) 6 7; the second exit block is a deopt block. The loop has one exiting block other than the latch. 8define i32 @test1(i32* nocapture %a, i64 %n) { 9; 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 13; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 14; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 15; CHECK-NEXT: br i1 [[TMP1]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] 16; CHECK: entry.new: 17; CHECK-NEXT: [[UNROLL_ITER:%.*]] = and i64 [[N]], -8 18; CHECK-NEXT: br label [[HEADER:%.*]] 19; CHECK: header: 20; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ] 21; CHECK-NEXT: [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ] 22; CHECK-NEXT: [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ] 23; CHECK-NEXT: br label [[FOR_EXITING_BLOCK:%.*]] 24; CHECK: for.exiting_block: 25; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 26; CHECK-NEXT: br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]] 27; CHECK: latch: 28; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] 29; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 30; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[SUM_02]] 31; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 1 32; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_1:%.*]] 33; CHECK: for.exiting_block.1: 34; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 35; CHECK-NEXT: br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]] 36; CHECK: latch.1: 37; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] 38; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 39; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i32 [[TMP3]], [[ADD]] 40; CHECK-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = or i64 [[INDVARS_IV]], 2 41; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_2:%.*]] 42; CHECK: for.exiting_block.2: 43; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 44; CHECK-NEXT: br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]] 45; CHECK: latch.2: 46; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] 47; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 48; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i32 [[TMP4]], [[ADD_1]] 49; CHECK-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = or i64 [[INDVARS_IV]], 3 50; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_3:%.*]] 51; CHECK: for.exiting_block.3: 52; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 53; CHECK-NEXT: br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]] 54; CHECK: latch.3: 55; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] 56; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 57; CHECK-NEXT: [[ADD_3:%.*]] = add nsw i32 [[TMP5]], [[ADD_2]] 58; CHECK-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = or i64 [[INDVARS_IV]], 4 59; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_4:%.*]] 60; CHECK: for.exiting_block.4: 61; CHECK-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 62; CHECK-NEXT: br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]] 63; CHECK: latch.4: 64; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] 65; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 66; CHECK-NEXT: [[ADD_4:%.*]] = add nsw i32 [[TMP6]], [[ADD_3]] 67; CHECK-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = or i64 [[INDVARS_IV]], 5 68; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_5:%.*]] 69; CHECK: for.exiting_block.5: 70; CHECK-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 71; CHECK-NEXT: br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]] 72; CHECK: latch.5: 73; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] 74; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 75; CHECK-NEXT: [[ADD_5:%.*]] = add nsw i32 [[TMP7]], [[ADD_4]] 76; CHECK-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = or i64 [[INDVARS_IV]], 6 77; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_6:%.*]] 78; CHECK: for.exiting_block.6: 79; CHECK-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 80; CHECK-NEXT: br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]] 81; CHECK: latch.6: 82; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] 83; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 84; CHECK-NEXT: [[ADD_6:%.*]] = add nsw i32 [[TMP8]], [[ADD_5]] 85; CHECK-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = or i64 [[INDVARS_IV]], 7 86; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_7:%.*]] 87; CHECK: for.exiting_block.7: 88; CHECK-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 89; CHECK-NEXT: br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]] 90; CHECK: latch.7: 91; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] 92; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 93; CHECK-NEXT: [[ADD_7]] = add nsw i32 [[TMP9]], [[ADD_6]] 94; CHECK-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8 95; CHECK-NEXT: [[NITER_NEXT_7]] = add i64 [[NITER]], 8 96; CHECK-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]] 97; CHECK-NEXT: br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]] 98; CHECK: latchexit.unr-lcssa.loopexit: 99; CHECK-NEXT: br label [[LATCHEXIT_UNR_LCSSA]] 100; CHECK: latchexit.unr-lcssa: 101; CHECK-NEXT: [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ] 102; CHECK-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ] 103; CHECK-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ] 104; CHECK-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 105; CHECK-NEXT: br i1 [[LCMP_MOD_NOT]], label [[LATCHEXIT:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]] 106; CHECK: header.epil.preheader: 107; CHECK-NEXT: br label [[HEADER_EPIL:%.*]] 108; CHECK: header.epil: 109; CHECK-NEXT: [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ] 110; CHECK-NEXT: [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ] 111; CHECK-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ], [ 0, [[HEADER_EPIL_PREHEADER]] ] 112; CHECK-NEXT: br label [[FOR_EXITING_BLOCK_EPIL:%.*]] 113; CHECK: for.exiting_block.epil: 114; CHECK-NEXT: [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42 115; CHECK-NEXT: br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]] 116; CHECK: latch.epil: 117; CHECK-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]] 118; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4 119; CHECK-NEXT: [[ADD_EPIL]] = add nsw i32 [[TMP10]], [[SUM_02_EPIL]] 120; CHECK-NEXT: [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1 121; CHECK-NEXT: [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1 122; CHECK-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_NEXT]], [[XTRAITER]] 123; CHECK-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop [[LOOP0:![0-9]+]] 124; CHECK: latchexit.epilog-lcssa: 125; CHECK-NEXT: br label [[LATCHEXIT]] 126; CHECK: latchexit: 127; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[LATCHEXIT_EPILOG_LCSSA]] ] 128; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] 129; CHECK: otherexit.loopexit: 130; CHECK-NEXT: [[SUM_02_LCSSA_PH:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1]], [[FOR_EXITING_BLOCK_2]] ], [ [[ADD_2]], [[FOR_EXITING_BLOCK_3]] ], [ [[ADD_3]], [[FOR_EXITING_BLOCK_4]] ], [ [[ADD_4]], [[FOR_EXITING_BLOCK_5]] ], [ [[ADD_5]], [[FOR_EXITING_BLOCK_6]] ], [ [[ADD_6]], [[FOR_EXITING_BLOCK_7]] ] 131; CHECK-NEXT: br label [[OTHEREXIT:%.*]] 132; CHECK: otherexit.loopexit3: 133; CHECK-NEXT: br label [[OTHEREXIT]] 134; CHECK: otherexit: 135; CHECK-NEXT: [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02_LCSSA_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_EPIL]], [[OTHEREXIT_LOOPEXIT3]] ] 136; CHECK-NEXT: [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ] 137; CHECK-NEXT: ret i32 [[RVAL]] 138; 139; NOUNROLL-LABEL: @test1( 140; NOUNROLL-NEXT: entry: 141; NOUNROLL-NEXT: br label [[HEADER:%.*]] 142; NOUNROLL: header: 143; NOUNROLL-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 144; NOUNROLL-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] 145; NOUNROLL-NEXT: br label [[FOR_EXITING_BLOCK:%.*]] 146; NOUNROLL: for.exiting_block: 147; NOUNROLL-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 148; NOUNROLL-NEXT: br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]] 149; NOUNROLL: latch: 150; NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] 151; NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 152; NOUNROLL-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] 153; NOUNROLL-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 154; NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] 155; NOUNROLL-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]] 156; NOUNROLL: latchexit: 157; NOUNROLL-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ] 158; NOUNROLL-NEXT: ret i32 [[SUM_0_LCSSA]] 159; NOUNROLL: otherexit: 160; NOUNROLL-NEXT: [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ] 161; NOUNROLL-NEXT: [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ] 162; NOUNROLL-NEXT: ret i32 [[RVAL]] 163; 164entry: 165 br label %header 166 167header: 168 %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] 169 %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] 170 br label %for.exiting_block 171 172for.exiting_block: 173 %cmp = icmp eq i64 %n, 42 174 br i1 %cmp, label %otherexit, label %latch 175 176latch: 177 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 178 %0 = load i32, i32* %arrayidx, align 4 179 %add = add nsw i32 %0, %sum.02 180 %indvars.iv.next = add i64 %indvars.iv, 1 181 %exitcond = icmp eq i64 %indvars.iv.next, %n 182 br i1 %exitcond, label %latchexit, label %header 183 184latchexit: ; preds = %latch 185 %sum.0.lcssa = phi i32 [ %add, %latch ] 186 ret i32 %sum.0.lcssa 187 188otherexit: 189 %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum.02) ] 190 ret i32 %rval 191} 192 193; the exit block is not a deopt block. 194define i32 @test2(i32* nocapture %a, i64 %n) { 195; 196; CHECK-LABEL: @test2( 197; CHECK-NEXT: entry: 198; CHECK-NEXT: br label [[HEADER:%.*]] 199; CHECK: header: 200; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 201; CHECK-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] 202; CHECK-NEXT: br label [[FOR_EXITING_BLOCK:%.*]] 203; CHECK: for.exiting_block: 204; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 205; CHECK-NEXT: br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]] 206; CHECK: latch: 207; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] 208; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 209; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] 210; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 211; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] 212; CHECK-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]] 213; CHECK: latchexit: 214; CHECK-NEXT: ret i32 [[ADD]] 215; CHECK: otherexit: 216; CHECK-NEXT: ret i32 [[SUM_02]] 217; 218; NOUNROLL-LABEL: @test2( 219; NOUNROLL-NEXT: entry: 220; NOUNROLL-NEXT: br label [[HEADER:%.*]] 221; NOUNROLL: header: 222; NOUNROLL-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 223; NOUNROLL-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] 224; NOUNROLL-NEXT: br label [[FOR_EXITING_BLOCK:%.*]] 225; NOUNROLL: for.exiting_block: 226; NOUNROLL-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 227; NOUNROLL-NEXT: br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]] 228; NOUNROLL: latch: 229; NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] 230; NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 231; NOUNROLL-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] 232; NOUNROLL-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 233; NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] 234; NOUNROLL-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]] 235; NOUNROLL: latchexit: 236; NOUNROLL-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ] 237; NOUNROLL-NEXT: ret i32 [[SUM_0_LCSSA]] 238; NOUNROLL: otherexit: 239; NOUNROLL-NEXT: [[RVAL:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ] 240; NOUNROLL-NEXT: ret i32 [[RVAL]] 241; 242entry: 243 br label %header 244 245header: 246 %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] 247 %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] 248 br label %for.exiting_block 249 250for.exiting_block: 251 %cmp = icmp eq i64 %n, 42 252 br i1 %cmp, label %otherexit, label %latch 253 254latch: 255 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 256 %0 = load i32, i32* %arrayidx, align 4 257 %add = add nsw i32 %0, %sum.02 258 %indvars.iv.next = add i64 %indvars.iv, 1 259 %exitcond = icmp eq i64 %indvars.iv.next, %n 260 br i1 %exitcond, label %latchexit, label %header 261 262latchexit: ; preds = %latch 263 %sum.0.lcssa = phi i32 [ %add, %latch ] 264 ret i32 %sum.0.lcssa 265 266otherexit: 267 %rval = phi i32 [%sum.02, %for.exiting_block ] 268 ret i32 %rval 269} 270declare i32 @llvm.experimental.deoptimize.i32(...) 271