1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -mtriple=wasm32-unknown-unknown -passes=loop-unroll,simplifycfg,instcombine -S %s -o - | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 5 6define hidden void @compile_time_full(ptr nocapture %a, ptr nocapture readonly %b) { 7; CHECK-LABEL: @compile_time_full( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[B:%.*]], align 1 10; CHECK-NEXT: store i8 [[I]], ptr [[A:%.*]], align 1 11; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 1 12; CHECK-NEXT: [[I_1:%.*]] = load i8, ptr [[ARRAYIDX_1]], align 1 13; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 1 14; CHECK-NEXT: store i8 [[I_1]], ptr [[ARRAYIDX1_1]], align 1 15; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 2 16; CHECK-NEXT: [[I_2:%.*]] = load i8, ptr [[ARRAYIDX_2]], align 1 17; CHECK-NEXT: [[ARRAYIDX1_2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 2 18; CHECK-NEXT: store i8 [[I_2]], ptr [[ARRAYIDX1_2]], align 1 19; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 3 20; CHECK-NEXT: [[I_3:%.*]] = load i8, ptr [[ARRAYIDX_3]], align 1 21; CHECK-NEXT: [[ARRAYIDX1_3:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 3 22; CHECK-NEXT: store i8 [[I_3]], ptr [[ARRAYIDX1_3]], align 1 23; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 4 24; CHECK-NEXT: [[I_4:%.*]] = load i8, ptr [[ARRAYIDX_4]], align 1 25; CHECK-NEXT: [[ARRAYIDX1_4:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 4 26; CHECK-NEXT: store i8 [[I_4]], ptr [[ARRAYIDX1_4]], align 1 27; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 5 28; CHECK-NEXT: [[I_5:%.*]] = load i8, ptr [[ARRAYIDX_5]], align 1 29; CHECK-NEXT: [[ARRAYIDX1_5:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 5 30; CHECK-NEXT: store i8 [[I_5]], ptr [[ARRAYIDX1_5]], align 1 31; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 6 32; CHECK-NEXT: [[I_6:%.*]] = load i8, ptr [[ARRAYIDX_6]], align 1 33; CHECK-NEXT: [[ARRAYIDX1_6:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 6 34; CHECK-NEXT: store i8 [[I_6]], ptr [[ARRAYIDX1_6]], align 1 35; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 7 36; CHECK-NEXT: [[I_7:%.*]] = load i8, ptr [[ARRAYIDX_7]], align 1 37; CHECK-NEXT: [[ARRAYIDX1_7:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 7 38; CHECK-NEXT: store i8 [[I_7]], ptr [[ARRAYIDX1_7]], align 1 39; CHECK-NEXT: [[ARRAYIDX_8:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 8 40; CHECK-NEXT: [[I_8:%.*]] = load i8, ptr [[ARRAYIDX_8]], align 1 41; CHECK-NEXT: [[ARRAYIDX1_8:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 8 42; CHECK-NEXT: store i8 [[I_8]], ptr [[ARRAYIDX1_8]], align 1 43; CHECK-NEXT: [[ARRAYIDX_9:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 9 44; CHECK-NEXT: [[I_9:%.*]] = load i8, ptr [[ARRAYIDX_9]], align 1 45; CHECK-NEXT: [[ARRAYIDX1_9:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 9 46; CHECK-NEXT: store i8 [[I_9]], ptr [[ARRAYIDX1_9]], align 1 47; CHECK-NEXT: ret void 48; 49entry: 50 br label %for.body 51 52for.cond.cleanup: ; preds = %for.body 53 ret void 54 55for.body: ; preds = %for.body, %entry 56 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 57 %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06 58 %i = load i8, ptr %arrayidx, align 1 59 %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06 60 store i8 %i, ptr %arrayidx1, align 1 61 %inc = add nuw nsw i32 %i.06, 1 62 %exitcond.not = icmp eq i32 %inc, 10 63 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 64} 65 66define hidden void @compile_time_partial(ptr nocapture %a, ptr nocapture readonly %b) { 67; CHECK-LABEL: @compile_time_partial( 68; CHECK-NEXT: entry: 69; CHECK-NEXT: br label [[FOR_BODY:%.*]] 70; CHECK: for.cond.cleanup: 71; CHECK-NEXT: ret void 72; CHECK: for.body: 73; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_3:%.*]], [[FOR_BODY]] ] 74; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i16, ptr [[B:%.*]], i32 [[I_07]] 75; CHECK-NEXT: [[I:%.*]] = load i16, ptr [[ARRAYIDX]], align 2 76; CHECK-NEXT: [[ADD:%.*]] = add i16 [[I]], 1 77; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i16, ptr [[A:%.*]], i32 [[I_07]] 78; CHECK-NEXT: store i16 [[ADD]], ptr [[ARRAYIDX2]], align 2 79; CHECK-NEXT: [[INC:%.*]] = or disjoint i32 [[I_07]], 1 80; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC]] 81; CHECK-NEXT: [[I_1:%.*]] = load i16, ptr [[ARRAYIDX_1]], align 2 82; CHECK-NEXT: [[ADD_1:%.*]] = add i16 [[I_1]], 1 83; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC]] 84; CHECK-NEXT: store i16 [[ADD_1]], ptr [[ARRAYIDX2_1]], align 2 85; CHECK-NEXT: [[INC_1:%.*]] = or disjoint i32 [[I_07]], 2 86; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC_1]] 87; CHECK-NEXT: [[I_2:%.*]] = load i16, ptr [[ARRAYIDX_2]], align 2 88; CHECK-NEXT: [[ADD_2:%.*]] = add i16 [[I_2]], 1 89; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC_1]] 90; CHECK-NEXT: store i16 [[ADD_2]], ptr [[ARRAYIDX2_2]], align 2 91; CHECK-NEXT: [[INC_2:%.*]] = or disjoint i32 [[I_07]], 3 92; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC_2]] 93; CHECK-NEXT: [[I_3:%.*]] = load i16, ptr [[ARRAYIDX_3]], align 2 94; CHECK-NEXT: [[ADD_3:%.*]] = add i16 [[I_3]], 1 95; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC_2]] 96; CHECK-NEXT: store i16 [[ADD_3]], ptr [[ARRAYIDX2_3]], align 2 97; CHECK-NEXT: [[INC_3]] = add nuw nsw i32 [[I_07]], 4 98; CHECK-NEXT: [[EXITCOND_NOT_3:%.*]] = icmp eq i32 [[INC_3]], 1000 99; CHECK-NEXT: br i1 [[EXITCOND_NOT_3]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] 100; 101entry: 102 br label %for.body 103 104for.cond.cleanup: ; preds = %for.body 105 ret void 106 107for.body: ; preds = %for.body, %entry 108 %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 109 %arrayidx = getelementptr inbounds i16, ptr %b, i32 %i.07 110 %i = load i16, ptr %arrayidx, align 2 111 %add = add i16 %i, 1 112 %arrayidx2 = getelementptr inbounds i16, ptr %a, i32 %i.07 113 store i16 %add, ptr %arrayidx2, align 2 114 %inc = add nuw nsw i32 %i.07, 1 115 %exitcond.not = icmp eq i32 %inc, 1000 116 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 117} 118 119define hidden void @runtime(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 120; CHECK-LABEL: @runtime( 121; CHECK-NEXT: entry: 122; CHECK-NEXT: [[CMP8_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 123; CHECK-NEXT: br i1 [[CMP8_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 124; CHECK: for.body.preheader: 125; CHECK-NEXT: [[XTRAITER:%.*]] = and i32 [[N]], 1 126; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[N]], 1 127; CHECK-NEXT: br i1 [[TMP0]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_BODY_PREHEADER_NEW:%.*]] 128; CHECK: for.body.preheader.new: 129; CHECK-NEXT: [[UNROLL_ITER:%.*]] = and i32 [[N]], -2 130; CHECK-NEXT: br label [[FOR_BODY:%.*]] 131; CHECK: for.cond.cleanup.loopexit.unr-lcssa: 132; CHECK-NEXT: [[I_09_UNR:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_1:%.*]], [[FOR_BODY]] ] 133; CHECK-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i32 [[XTRAITER]], 0 134; CHECK-NEXT: br i1 [[LCMP_MOD_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY_EPIL:%.*]] 135; CHECK: for.body.epil: 136; CHECK-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[I_09_UNR]] 137; CHECK-NEXT: [[I_EPIL:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4 138; CHECK-NEXT: [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i32 [[I_09_UNR]] 139; CHECK-NEXT: [[I1_EPIL:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4 140; CHECK-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[I1_EPIL]], [[I_EPIL]] 141; CHECK-NEXT: [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_09_UNR]] 142; CHECK-NEXT: store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4 143; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 144; CHECK: for.cond.cleanup: 145; CHECK-NEXT: ret void 146; CHECK: for.body: 147; CHECK-NEXT: [[I_09:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1]], [[FOR_BODY]] ] 148; CHECK-NEXT: [[NITER:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[FOR_BODY]] ] 149; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]] 150; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 151; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]] 152; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 153; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]] 154; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]] 155; CHECK-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4 156; CHECK-NEXT: [[INC:%.*]] = or disjoint i32 [[I_09]], 1 157; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]] 158; CHECK-NEXT: [[I_1:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4 159; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]] 160; CHECK-NEXT: [[I1_1:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4 161; CHECK-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[I1_1]], [[I_1]] 162; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]] 163; CHECK-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4 164; CHECK-NEXT: [[INC_1]] = add nuw i32 [[I_09]], 2 165; CHECK-NEXT: [[NITER_NEXT_1]] = add i32 [[NITER]], 2 166; CHECK-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]] 167; CHECK-NEXT: br i1 [[NITER_NCMP_1]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]] 168; 169entry: 170 %cmp8.not = icmp eq i32 %N, 0 171 br i1 %cmp8.not, label %for.cond.cleanup, label %for.body 172 173for.cond.cleanup: ; preds = %for.body, %entry 174 ret void 175 176for.body: ; preds = %for.body, %entry 177 %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 178 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.09 179 %i = load i32, ptr %arrayidx, align 4 180 %arrayidx1 = getelementptr inbounds i32, ptr %c, i32 %i.09 181 %i1 = load i32, ptr %arrayidx1, align 4 182 %mul = mul nsw i32 %i1, %i 183 %arrayidx2 = getelementptr inbounds i32, ptr %a, i32 %i.09 184 store i32 %mul, ptr %arrayidx2, align 4 185 %inc = add nuw i32 %i.09, 1 186 %exitcond.not = icmp eq i32 %inc, %N 187 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 188} 189 190define hidden void @dont_unroll_call(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 191; CHECK-LABEL: @dont_unroll_call( 192; CHECK-NEXT: entry: 193; CHECK-NEXT: [[CMP12_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 194; CHECK-NEXT: br i1 [[CMP12_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] 195; CHECK: for.cond.cleanup: 196; CHECK-NEXT: ret void 197; CHECK: for.body: 198; CHECK-NEXT: [[I_013:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 199; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[I_013]] 200; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 201; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i32 [[I_013]] 202; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 203; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]] 204; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_013]] 205; CHECK-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4 206; CHECK-NEXT: [[TMP0:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 [[I_013]], i32 [[MUL]]) 207; CHECK-NEXT: [[INC]] = add nuw i32 [[I_013]], 1 208; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]] 209; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]] 210; 211entry: 212 %cmp12.not = icmp eq i32 %N, 0 213 br i1 %cmp12.not, label %for.cond.cleanup, label %for.body 214 215for.cond.cleanup: ; preds = %for.body, %entry 216 ret void 217 218for.body: ; preds = %for.body, %entry 219 %i.013 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 220 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.013 221 %i = load i32, ptr %arrayidx, align 4 222 %arrayidx1 = getelementptr inbounds i32, ptr %c, i32 %i.013 223 %i1 = load i32, ptr %arrayidx1, align 4 224 %mul = mul nsw i32 %i1, %i 225 %arrayidx2 = getelementptr inbounds i32, ptr %a, i32 %i.013 226 store i32 %mul, ptr %arrayidx2, align 4 227 call i32 (ptr, ...) @printf(ptr nonnull dereferenceable(1) @.str, i32 %i.013, i32 %mul) 228 %inc = add nuw i32 %i.013, 1 229 %exitcond.not = icmp eq i32 %inc, %N 230 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 231} 232 233define hidden void @dont_unroll_optsize(ptr nocapture %a, ptr nocapture readonly %b) #0 { 234; CHECK-LABEL: @dont_unroll_optsize( 235; CHECK-NEXT: entry: 236; CHECK-NEXT: br label [[FOR_BODY:%.*]] 237; CHECK: for.cond.cleanup: 238; CHECK-NEXT: ret void 239; CHECK: for.body: 240; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 241; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[B:%.*]], i32 [[I_06]] 242; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 243; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[I_06]] 244; CHECK-NEXT: store i8 [[I]], ptr [[ARRAYIDX1]], align 1 245; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 246; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 10 247; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] 248; 249entry: 250 br label %for.body 251 252for.cond.cleanup: ; preds = %for.body 253 ret void 254 255for.body: ; preds = %for.body, %entry 256 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 257 %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06 258 %i = load i8, ptr %arrayidx, align 1 259 %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06 260 store i8 %i, ptr %arrayidx1, align 1 261 %inc = add nuw nsw i32 %i.06, 1 262 %exitcond.not = icmp eq i32 %inc, 10 263 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 264} 265 266define hidden void @dont_unroll_minsize(ptr nocapture %a, ptr nocapture readonly %b) #1 { 267; CHECK-LABEL: @dont_unroll_minsize( 268; CHECK-NEXT: entry: 269; CHECK-NEXT: br label [[FOR_BODY:%.*]] 270; CHECK: for.cond.cleanup: 271; CHECK-NEXT: ret void 272; CHECK: for.body: 273; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 274; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[B:%.*]], i32 [[I_06]] 275; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 276; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[I_06]] 277; CHECK-NEXT: store i8 [[I]], ptr [[ARRAYIDX1]], align 1 278; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 279; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 10 280; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] 281; 282entry: 283 br label %for.body 284 285for.cond.cleanup: ; preds = %for.body 286 ret void 287 288for.body: ; preds = %for.body, %entry 289 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 290 %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06 291 %i = load i8, ptr %arrayidx, align 1 292 %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06 293 store i8 %i, ptr %arrayidx1, align 1 294 %inc = add nuw nsw i32 %i.06, 1 295 %exitcond.not = icmp eq i32 %inc, 10 296 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 297} 298 299attributes #0 = { optsize } 300attributes #1 = { minsize } 301 302@.str = private unnamed_addr constant [12 x i8] c"a[%d] = %d\0A\00", align 1 303declare i32 @printf(ptr nocapture readonly, ...) 304