1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -passes=irce -S -verify-loop-info -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s 3 4define void @test_inc_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 5; CHECK-LABEL: define void @test_inc_eq( 6; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[CMP16:%.*]] = icmp sgt i32 [[N]], 0 9; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 10; CHECK: for.body.preheader: 11; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512) 12; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]] 13; CHECK-NEXT: br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 14; CHECK: for.body.preheader1: 15; CHECK-NEXT: br label [[FOR_BODY:%.*]] 16; CHECK: for.cond.cleanup.loopexit.loopexit: 17; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 18; CHECK: for.cond.cleanup.loopexit: 19; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 20; CHECK: for.cond.cleanup: 21; CHECK-NEXT: ret void 22; CHECK: for.body: 23; CHECK-NEXT: [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ] 24; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512 25; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]] 26; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 27; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]] 28; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 29; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 30; CHECK: if.then: 31; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]] 32; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 33; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 34; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]] 35; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4 36; CHECK-NEXT: br label [[FOR_INC]] 37; CHECK: if.else: 38; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] 39; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 40; CHECK-NEXT: store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4 41; CHECK-NEXT: br label [[FOR_INC]] 42; CHECK: for.inc: 43; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_017]], 1 44; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]] 45; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]] 46; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true 47; CHECK-NEXT: br i1 [[TMP5]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]] 48; CHECK: main.exit.selector: 49; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ] 50; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]] 51; CHECK-NEXT: br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 52; CHECK: main.pseudo.exit: 53; CHECK-NEXT: [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 54; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 55; CHECK-NEXT: br label [[POSTLOOP:%.*]] 56; CHECK: postloop: 57; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 58; CHECK: for.body.postloop: 59; CHECK-NEXT: [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ] 60; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512 61; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]] 62; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 63; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]] 64; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 65; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]] 66; CHECK: if.else.postloop: 67; CHECK-NEXT: [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP8]], [[TMP7]] 68; CHECK-NEXT: [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 69; CHECK-NEXT: store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4 70; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 71; CHECK: if.then.postloop: 72; CHECK-NEXT: [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP7]], [[TMP8]] 73; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 74; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 75; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP9]] 76; CHECK-NEXT: store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 77; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 78; CHECK: for.inc.postloop: 79; CHECK-NEXT: [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1 80; CHECK-NEXT: [[EXITCOND_POSTLOOP:%.*]] = icmp eq i32 [[INC_POSTLOOP]], [[N]] 81; CHECK-NEXT: br i1 [[EXITCOND_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]] 82; 83entry: 84 %cmp16 = icmp sgt i32 %N, 0 85 br i1 %cmp16, label %for.body, label %for.cond.cleanup 86 87for.cond.cleanup: 88 ret void 89 90for.body: 91 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 92 %cmp1 = icmp ult i32 %i.017, 512 93 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017 94 %0 = load i32, ptr %arrayidx, align 4 95 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017 96 %1 = load i32, ptr %arrayidx2, align 4 97 br i1 %cmp1, label %if.then, label %if.else 98 99if.then: 100 %sub = sub i32 %0, %1 101 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017 102 %2 = load i32, ptr %arrayidx3, align 4 103 %add = add nsw i32 %sub, %2 104 store i32 %add, ptr %arrayidx3, align 4 105 br label %for.inc 106 107if.else: 108 %add6 = add nsw i32 %1, %0 109 %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017 110 store i32 %add6, ptr %arrayidx7, align 4 111 br label %for.inc 112 113for.inc: 114 %inc = add nuw nsw i32 %i.017, 1 115 %exitcond = icmp eq i32 %inc, %N 116 br i1 %exitcond, label %for.cond.cleanup, label %for.body 117} 118 119define void @test_inc_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 120; CHECK-LABEL: define void @test_inc_ne( 121; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) { 122; CHECK-NEXT: entry: 123; CHECK-NEXT: [[CMP16:%.*]] = icmp sgt i32 [[N]], 0 124; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 125; CHECK: for.body.preheader: 126; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512) 127; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]] 128; CHECK-NEXT: br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 129; CHECK: for.body.preheader1: 130; CHECK-NEXT: br label [[FOR_BODY:%.*]] 131; CHECK: for.cond.cleanup.loopexit.loopexit: 132; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 133; CHECK: for.cond.cleanup.loopexit: 134; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 135; CHECK: for.cond.cleanup: 136; CHECK-NEXT: ret void 137; CHECK: for.body: 138; CHECK-NEXT: [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ] 139; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512 140; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]] 141; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 142; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]] 143; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 144; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 145; CHECK: if.then: 146; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]] 147; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 148; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 149; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]] 150; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4 151; CHECK-NEXT: br label [[FOR_INC]] 152; CHECK: if.else: 153; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] 154; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 155; CHECK-NEXT: store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4 156; CHECK-NEXT: br label [[FOR_INC]] 157; CHECK: for.inc: 158; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_017]], 1 159; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[N]] 160; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]] 161; CHECK-NEXT: br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 162; CHECK: main.exit.selector: 163; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ] 164; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]] 165; CHECK-NEXT: br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 166; CHECK: main.pseudo.exit: 167; CHECK-NEXT: [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 168; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 169; CHECK-NEXT: br label [[POSTLOOP:%.*]] 170; CHECK: postloop: 171; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 172; CHECK: for.body.postloop: 173; CHECK-NEXT: [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ] 174; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512 175; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]] 176; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 177; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]] 178; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 179; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]] 180; CHECK: if.else.postloop: 181; CHECK-NEXT: [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]] 182; CHECK-NEXT: [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 183; CHECK-NEXT: store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4 184; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 185; CHECK: if.then.postloop: 186; CHECK-NEXT: [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]] 187; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 188; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 189; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]] 190; CHECK-NEXT: store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 191; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 192; CHECK: for.inc.postloop: 193; CHECK-NEXT: [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1 194; CHECK-NEXT: [[EXITCOND_POSTLOOP:%.*]] = icmp ne i32 [[INC_POSTLOOP]], [[N]] 195; CHECK-NEXT: br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 196; 197entry: 198 %cmp16 = icmp sgt i32 %N, 0 199 br i1 %cmp16, label %for.body, label %for.cond.cleanup 200 201for.cond.cleanup: 202 ret void 203 204for.body: 205 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 206 %cmp1 = icmp ult i32 %i.017, 512 207 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017 208 %0 = load i32, ptr %arrayidx, align 4 209 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017 210 %1 = load i32, ptr %arrayidx2, align 4 211 br i1 %cmp1, label %if.then, label %if.else 212 213if.then: 214 %sub = sub i32 %0, %1 215 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017 216 %2 = load i32, ptr %arrayidx3, align 4 217 %add = add nsw i32 %sub, %2 218 store i32 %add, ptr %arrayidx3, align 4 219 br label %for.inc 220 221if.else: 222 %add6 = add nsw i32 %1, %0 223 %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017 224 store i32 %add6, ptr %arrayidx7, align 4 225 br label %for.inc 226 227for.inc: 228 %inc = add nuw nsw i32 %i.017, 1 229 %exitcond = icmp ne i32 %inc, %N 230 br i1 %exitcond, label %for.body, label %for.cond.cleanup 231} 232 233define void @test_inc_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 234; CHECK-LABEL: define void @test_inc_slt( 235; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) { 236; CHECK-NEXT: entry: 237; CHECK-NEXT: [[CMP16:%.*]] = icmp sgt i32 [[N]], 0 238; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 239; CHECK: for.body.preheader: 240; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[N]], i32 512) 241; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 0) 242; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]] 243; CHECK-NEXT: br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 244; CHECK: for.body.preheader1: 245; CHECK-NEXT: br label [[FOR_BODY:%.*]] 246; CHECK: for.cond.cleanup.loopexit.loopexit: 247; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 248; CHECK: for.cond.cleanup.loopexit: 249; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 250; CHECK: for.cond.cleanup: 251; CHECK-NEXT: ret void 252; CHECK: for.body: 253; CHECK-NEXT: [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ] 254; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512 255; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]] 256; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 257; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]] 258; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 259; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 260; CHECK: if.then: 261; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]] 262; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 263; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 264; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]] 265; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4 266; CHECK-NEXT: br label [[FOR_INC]] 267; CHECK: if.else: 268; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] 269; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 270; CHECK-NEXT: store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4 271; CHECK-NEXT: br label [[FOR_INC]] 272; CHECK: for.inc: 273; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_017]], 1 274; CHECK-NEXT: [[EXITCOND:%.*]] = icmp slt i32 [[INC]], [[N]] 275; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[INC]], [[EXIT_MAINLOOP_AT]] 276; CHECK-NEXT: br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 277; CHECK: main.exit.selector: 278; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ] 279; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[INC_LCSSA]], [[N]] 280; CHECK-NEXT: br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 281; CHECK: main.pseudo.exit: 282; CHECK-NEXT: [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 283; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 284; CHECK-NEXT: br label [[POSTLOOP:%.*]] 285; CHECK: postloop: 286; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 287; CHECK: for.body.postloop: 288; CHECK-NEXT: [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ] 289; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512 290; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]] 291; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 292; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]] 293; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 294; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]] 295; CHECK: if.else.postloop: 296; CHECK-NEXT: [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]] 297; CHECK-NEXT: [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 298; CHECK-NEXT: store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4 299; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 300; CHECK: if.then.postloop: 301; CHECK-NEXT: [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]] 302; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 303; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 304; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]] 305; CHECK-NEXT: store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 306; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 307; CHECK: for.inc.postloop: 308; CHECK-NEXT: [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1 309; CHECK-NEXT: [[EXITCOND_POSTLOOP:%.*]] = icmp slt i32 [[INC_POSTLOOP]], [[N]] 310; CHECK-NEXT: br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 311; 312entry: 313 %cmp16 = icmp sgt i32 %N, 0 314 br i1 %cmp16, label %for.body, label %for.cond.cleanup 315 316for.cond.cleanup: 317 ret void 318 319for.body: 320 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 321 %cmp1 = icmp ult i32 %i.017, 512 322 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017 323 %0 = load i32, ptr %arrayidx, align 4 324 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017 325 %1 = load i32, ptr %arrayidx2, align 4 326 br i1 %cmp1, label %if.then, label %if.else 327 328if.then: 329 %sub = sub i32 %0, %1 330 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017 331 %2 = load i32, ptr %arrayidx3, align 4 332 %add = add nsw i32 %sub, %2 333 store i32 %add, ptr %arrayidx3, align 4 334 br label %for.inc 335 336if.else: 337 %add6 = add nsw i32 %1, %0 338 %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017 339 store i32 %add6, ptr %arrayidx7, align 4 340 br label %for.inc 341 342for.inc: 343 %inc = add nuw nsw i32 %i.017, 1 344 %exitcond = icmp slt i32 %inc, %N 345 br i1 %exitcond, label %for.body, label %for.cond.cleanup 346} 347 348define void @test_inc_ult(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) { 349; CHECK-LABEL: define void @test_inc_ult( 350; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) { 351; CHECK-NEXT: entry: 352; CHECK-NEXT: [[CMP16:%.*]] = icmp ugt i32 [[N]], 0 353; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 354; CHECK: for.body.preheader: 355; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512) 356; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]] 357; CHECK-NEXT: br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 358; CHECK: for.body.preheader1: 359; CHECK-NEXT: br label [[FOR_BODY:%.*]] 360; CHECK: for.cond.cleanup.loopexit.loopexit: 361; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 362; CHECK: for.cond.cleanup.loopexit: 363; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 364; CHECK: for.cond.cleanup: 365; CHECK-NEXT: ret void 366; CHECK: for.body: 367; CHECK-NEXT: [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ] 368; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512 369; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]] 370; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 371; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]] 372; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 373; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 374; CHECK: if.then: 375; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]] 376; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 377; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 378; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]] 379; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4 380; CHECK-NEXT: br label [[FOR_INC]] 381; CHECK: if.else: 382; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] 383; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]] 384; CHECK-NEXT: store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4 385; CHECK-NEXT: br label [[FOR_INC]] 386; CHECK: for.inc: 387; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_017]], 1 388; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ult i32 [[INC]], [[N]] 389; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]] 390; CHECK-NEXT: br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 391; CHECK: main.exit.selector: 392; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ] 393; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]] 394; CHECK-NEXT: br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 395; CHECK: main.pseudo.exit: 396; CHECK-NEXT: [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 397; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 398; CHECK-NEXT: br label [[POSTLOOP:%.*]] 399; CHECK: postloop: 400; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 401; CHECK: for.body.postloop: 402; CHECK-NEXT: [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ] 403; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512 404; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]] 405; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 406; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]] 407; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 408; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]] 409; CHECK: if.else.postloop: 410; CHECK-NEXT: [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]] 411; CHECK-NEXT: [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 412; CHECK-NEXT: store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4 413; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 414; CHECK: if.then.postloop: 415; CHECK-NEXT: [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]] 416; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]] 417; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 418; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]] 419; CHECK-NEXT: store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 420; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 421; CHECK: for.inc.postloop: 422; CHECK-NEXT: [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1 423; CHECK-NEXT: [[EXITCOND_POSTLOOP:%.*]] = icmp ult i32 [[INC_POSTLOOP]], [[N]] 424; CHECK-NEXT: br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 425; 426entry: 427 %cmp16 = icmp ugt i32 %N, 0 428 br i1 %cmp16, label %for.body, label %for.cond.cleanup 429 430for.cond.cleanup: 431 ret void 432 433for.body: 434 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 435 %cmp1 = icmp ult i32 %i.017, 512 436 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017 437 %0 = load i32, ptr %arrayidx, align 4 438 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017 439 %1 = load i32, ptr %arrayidx2, align 4 440 br i1 %cmp1, label %if.then, label %if.else 441 442if.then: 443 %sub = sub i32 %0, %1 444 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017 445 %2 = load i32, ptr %arrayidx3, align 4 446 %add = add nsw i32 %sub, %2 447 store i32 %add, ptr %arrayidx3, align 4 448 br label %for.inc 449 450if.else: 451 %add6 = add nsw i32 %1, %0 452 %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017 453 store i32 %add6, ptr %arrayidx7, align 4 454 br label %for.inc 455 456for.inc: 457 %inc = add nuw nsw i32 %i.017, 1 458 %exitcond = icmp ult i32 %inc, %N 459 br i1 %exitcond, label %for.body, label %for.cond.cleanup 460} 461 462define void @signed_var_imm_dec_sgt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { 463; CHECK-LABEL: define void @signed_var_imm_dec_sgt( 464; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) { 465; CHECK-NEXT: entry: 466; CHECK-NEXT: [[CMP14:%.*]] = icmp slt i32 [[M]], 1024 467; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 468; CHECK: for.body.preheader: 469; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[M]], 1 470; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024) 471; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1 472; CHECK-NEXT: [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0) 473; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1 474; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]] 475; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] 476; CHECK: for.body.preloop.preheader: 477; CHECK-NEXT: br label [[FOR_BODY_PRELOOP:%.*]] 478; CHECK: for.cond.cleanup.loopexit.loopexit: 479; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 480; CHECK: for.cond.cleanup.loopexit: 481; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 482; CHECK: for.cond.cleanup: 483; CHECK-NEXT: ret void 484; CHECK: mainloop: 485; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]] 486; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 487; CHECK: for.body.preheader3: 488; CHECK-NEXT: br label [[FOR_BODY:%.*]] 489; CHECK: for.body: 490; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ] 491; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 492; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] 493; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 494; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] 495; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 496; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]] 497; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] 498; CHECK-NEXT: br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]] 499; CHECK: if.else: 500; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 501; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]] 502; CHECK-NEXT: br label [[FOR_INC]] 503; CHECK: for.inc: 504; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] 505; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 506; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 507; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[M]] 508; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]] 509; CHECK-NEXT: br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 510; CHECK: main.exit.selector: 511; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ] 512; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]] 513; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 514; CHECK: main.pseudo.exit: 515; CHECK-NEXT: [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 516; CHECK-NEXT: [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 517; CHECK-NEXT: br label [[POSTLOOP:%.*]] 518; CHECK: for.body.preloop: 519; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ] 520; CHECK-NEXT: [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024 521; CHECK-NEXT: [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]] 522; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4 523; CHECK-NEXT: [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]] 524; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4 525; CHECK-NEXT: [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]] 526; CHECK-NEXT: [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]] 527; CHECK-NEXT: br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]] 528; CHECK: if.else.preloop: 529; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4 530; CHECK-NEXT: [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]] 531; CHECK-NEXT: br label [[FOR_INC_PRELOOP]] 532; CHECK: for.inc.preloop: 533; CHECK-NEXT: [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ] 534; CHECK-NEXT: store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4 535; CHECK-NEXT: [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1 536; CHECK-NEXT: [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[M]] 537; CHECK-NEXT: [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]] 538; CHECK-NEXT: br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 539; CHECK: preloop.exit.selector: 540; CHECK-NEXT: [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ] 541; CHECK-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]] 542; CHECK-NEXT: br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 543; CHECK: preloop.pseudo.exit: 544; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 545; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 546; CHECK-NEXT: br label [[MAINLOOP]] 547; CHECK: postloop: 548; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 549; CHECK: for.body.postloop: 550; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ] 551; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024 552; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]] 553; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 554; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]] 555; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 556; CHECK-NEXT: [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]] 557; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]] 558; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]] 559; CHECK: if.else.postloop: 560; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 561; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]] 562; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 563; CHECK: for.inc.postloop: 564; CHECK-NEXT: [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ] 565; CHECK-NEXT: store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 566; CHECK-NEXT: [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1 567; CHECK-NEXT: [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[DEC_POSTLOOP]], [[M]] 568; CHECK-NEXT: br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 569; 570entry: 571 %cmp14 = icmp slt i32 %M, 1024 572 br i1 %cmp14, label %for.body, label %for.cond.cleanup 573 574for.cond.cleanup: ; preds = %for.inc, %entry 575 ret void 576 577for.body: ; preds = %entry, %for.inc 578 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 579 %cmp1 = icmp slt i32 %iv, 1024 580 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv 581 %0 = load i32, ptr %arrayidx, align 4 582 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv 583 %1 = load i32, ptr %arrayidx2, align 4 584 %mul = mul nsw i32 %1, %0 585 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv 586 br i1 %cmp1, label %for.inc, label %if.else 587 588if.else: ; preds = %for.body 589 %2 = load i32, ptr %arrayidx3, align 4 590 %add = add nsw i32 %2, %mul 591 br label %for.inc 592 593for.inc: ; preds = %for.body, %if.else 594 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 595 store i32 %storemerge, ptr %arrayidx3, align 4 596 %dec = add nsw i32 %iv, -1 597 %cmp = icmp sgt i32 %dec, %M 598 br i1 %cmp, label %for.body, label %for.cond.cleanup 599} 600 601define void @signed_var_imm_dec_sge(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { 602; CHECK-LABEL: define void @signed_var_imm_dec_sge( 603; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) { 604; CHECK-NEXT: entry: 605; CHECK-NEXT: [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024 606; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 607; CHECK: for.body.preheader: 608; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[M]], 1 609; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1025) 610; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1 611; CHECK-NEXT: [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1) 612; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1 613; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 1025, [[EXIT_PRELOOP_AT]] 614; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] 615; CHECK: for.body.preloop.preheader: 616; CHECK-NEXT: br label [[FOR_BODY_PRELOOP:%.*]] 617; CHECK: for.cond.cleanup.loopexit.loopexit: 618; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 619; CHECK: for.cond.cleanup.loopexit: 620; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 621; CHECK: for.cond.cleanup: 622; CHECK-NEXT: ret void 623; CHECK: mainloop: 624; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]] 625; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 626; CHECK: for.body.preheader3: 627; CHECK-NEXT: br label [[FOR_BODY:%.*]] 628; CHECK: for.body: 629; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ] 630; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 631; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] 632; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 633; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] 634; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 635; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]] 636; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] 637; CHECK-NEXT: br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]] 638; CHECK: if.else: 639; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 640; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]] 641; CHECK-NEXT: br label [[FOR_INC]] 642; CHECK: for.inc: 643; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] 644; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 645; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 646; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[IV]], [[M]] 647; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[IV]], [[EXIT_MAINLOOP_AT]] 648; CHECK-NEXT: br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 649; CHECK: main.exit.selector: 650; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ] 651; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[FOR_INC]] ] 652; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[IV_LCSSA]], [[M]] 653; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 654; CHECK: main.pseudo.exit: 655; CHECK-NEXT: [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 656; CHECK-NEXT: [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 657; CHECK-NEXT: br label [[POSTLOOP:%.*]] 658; CHECK: for.body.preloop: 659; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ] 660; CHECK-NEXT: [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024 661; CHECK-NEXT: [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]] 662; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4 663; CHECK-NEXT: [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]] 664; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4 665; CHECK-NEXT: [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]] 666; CHECK-NEXT: [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]] 667; CHECK-NEXT: br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]] 668; CHECK: if.else.preloop: 669; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4 670; CHECK-NEXT: [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]] 671; CHECK-NEXT: br label [[FOR_INC_PRELOOP]] 672; CHECK: for.inc.preloop: 673; CHECK-NEXT: [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ] 674; CHECK-NEXT: store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4 675; CHECK-NEXT: [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1 676; CHECK-NEXT: [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[M]] 677; CHECK-NEXT: [[TMP11:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[EXIT_PRELOOP_AT]] 678; CHECK-NEXT: br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 679; CHECK: preloop.exit.selector: 680; CHECK-NEXT: [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ] 681; CHECK-NEXT: [[IV_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IV_PRELOOP]], [[FOR_INC_PRELOOP]] ] 682; CHECK-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[IV_PRELOOP_LCSSA]], [[M]] 683; CHECK-NEXT: br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 684; CHECK: preloop.pseudo.exit: 685; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 686; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ 1025, [[FOR_BODY_PREHEADER]] ], [ [[IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 687; CHECK-NEXT: br label [[MAINLOOP]] 688; CHECK: postloop: 689; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 690; CHECK: for.body.postloop: 691; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ] 692; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024 693; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]] 694; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 695; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]] 696; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 697; CHECK-NEXT: [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]] 698; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]] 699; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]] 700; CHECK: if.else.postloop: 701; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 702; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]] 703; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 704; CHECK: for.inc.postloop: 705; CHECK-NEXT: [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ] 706; CHECK-NEXT: store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 707; CHECK-NEXT: [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1 708; CHECK-NEXT: [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[IV_POSTLOOP]], [[M]] 709; CHECK-NEXT: br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 710; 711entry: 712 %cmp14 = icmp sgt i32 %M, 1024 713 br i1 %cmp14, label %for.cond.cleanup, label %for.body 714 715for.cond.cleanup: ; preds = %for.inc, %entry 716 ret void 717 718for.body: ; preds = %entry, %for.inc 719 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 720 %cmp1 = icmp slt i32 %iv, 1024 721 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv 722 %0 = load i32, ptr %arrayidx, align 4 723 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv 724 %1 = load i32, ptr %arrayidx2, align 4 725 %mul = mul nsw i32 %1, %0 726 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv 727 br i1 %cmp1, label %for.inc, label %if.else 728 729if.else: ; preds = %for.body 730 %2 = load i32, ptr %arrayidx3, align 4 731 %add = add nsw i32 %2, %mul 732 br label %for.inc 733 734for.inc: ; preds = %for.body, %if.else 735 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 736 store i32 %storemerge, ptr %arrayidx3, align 4 737 %dec = add nsw i32 %iv, -1 738 %cmp = icmp sgt i32 %iv, %M 739 br i1 %cmp, label %for.body, label %for.cond.cleanup 740} 741 742define void @signed_var_imm_dec_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { 743; CHECK-LABEL: define void @signed_var_imm_dec_slt( 744; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) { 745; CHECK-NEXT: entry: 746; CHECK-NEXT: [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024 747; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 748; CHECK: for.body.preheader: 749; CHECK-NEXT: br label [[FOR_BODY:%.*]] 750; CHECK: for.cond.cleanup.loopexit: 751; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 752; CHECK: for.cond.cleanup: 753; CHECK-NEXT: ret void 754; CHECK: for.body: 755; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ 1024, [[FOR_BODY_PREHEADER]] ] 756; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 757; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] 758; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 759; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] 760; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 761; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]] 762; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] 763; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_INC]], label [[IF_ELSE:%.*]] 764; CHECK: if.else: 765; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 766; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[MUL]] 767; CHECK-NEXT: br label [[FOR_INC]] 768; CHECK: for.inc: 769; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] 770; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 771; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 772; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], [[M]] 773; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 774; 775entry: 776 %cmp14 = icmp sgt i32 %M, 1024 777 br i1 %cmp14, label %for.cond.cleanup, label %for.body 778 779for.cond.cleanup: ; preds = %for.inc, %entry 780 ret void 781 782for.body: ; preds = %entry, %for.inc 783 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 784 %cmp1 = icmp slt i32 %iv, 1024 785 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv 786 %0 = load i32, ptr %arrayidx, align 4 787 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv 788 %1 = load i32, ptr %arrayidx2, align 4 789 %mul = mul nsw i32 %1, %0 790 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv 791 br i1 %cmp1, label %for.inc, label %if.else 792 793if.else: ; preds = %for.body 794 %2 = load i32, ptr %arrayidx3, align 4 795 %add = add nsw i32 %2, %mul 796 br label %for.inc 797 798for.inc: ; preds = %for.body, %if.else 799 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 800 store i32 %storemerge, ptr %arrayidx3, align 4 801 %dec = add nsw i32 %iv, -1 802 %cmp = icmp slt i32 %iv, %M 803 br i1 %cmp, label %for.cond.cleanup, label %for.body 804} 805 806define void @signed_var_imm_dec_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { 807; CHECK-LABEL: define void @signed_var_imm_dec_ne( 808; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) { 809; CHECK-NEXT: entry: 810; CHECK-NEXT: [[CMP14:%.*]] = icmp slt i32 [[M]], 1024 811; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 812; CHECK: for.body.preheader: 813; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[M]], 1 814; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024) 815; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1 816; CHECK-NEXT: [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0) 817; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1 818; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]] 819; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] 820; CHECK: for.body.preloop.preheader: 821; CHECK-NEXT: br label [[FOR_BODY_PRELOOP:%.*]] 822; CHECK: for.cond.cleanup.loopexit.loopexit: 823; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 824; CHECK: for.cond.cleanup.loopexit: 825; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 826; CHECK: for.cond.cleanup: 827; CHECK-NEXT: ret void 828; CHECK: mainloop: 829; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]] 830; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 831; CHECK: for.body.preheader3: 832; CHECK-NEXT: br label [[FOR_BODY:%.*]] 833; CHECK: for.body: 834; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ] 835; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 836; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] 837; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 838; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] 839; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 840; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]] 841; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] 842; CHECK-NEXT: br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]] 843; CHECK: if.else: 844; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 845; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]] 846; CHECK-NEXT: br label [[FOR_INC]] 847; CHECK: for.inc: 848; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] 849; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 850; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 851; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[DEC]], [[M]] 852; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]] 853; CHECK-NEXT: br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]] 854; CHECK: main.exit.selector: 855; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ] 856; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]] 857; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 858; CHECK: main.pseudo.exit: 859; CHECK-NEXT: [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 860; CHECK-NEXT: [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 861; CHECK-NEXT: br label [[POSTLOOP:%.*]] 862; CHECK: for.body.preloop: 863; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ] 864; CHECK-NEXT: [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024 865; CHECK-NEXT: [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]] 866; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4 867; CHECK-NEXT: [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]] 868; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4 869; CHECK-NEXT: [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]] 870; CHECK-NEXT: [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]] 871; CHECK-NEXT: br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]] 872; CHECK: if.else.preloop: 873; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4 874; CHECK-NEXT: [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]] 875; CHECK-NEXT: br label [[FOR_INC_PRELOOP]] 876; CHECK: for.inc.preloop: 877; CHECK-NEXT: [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ] 878; CHECK-NEXT: store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4 879; CHECK-NEXT: [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1 880; CHECK-NEXT: [[CMP_PRELOOP:%.*]] = icmp ne i32 [[DEC_PRELOOP]], [[M]] 881; CHECK-NEXT: [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]] 882; CHECK-NEXT: br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP13:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 883; CHECK: preloop.exit.selector: 884; CHECK-NEXT: [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ] 885; CHECK-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]] 886; CHECK-NEXT: br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 887; CHECK: preloop.pseudo.exit: 888; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 889; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 890; CHECK-NEXT: br label [[MAINLOOP]] 891; CHECK: postloop: 892; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 893; CHECK: for.body.postloop: 894; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ] 895; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024 896; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]] 897; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 898; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]] 899; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 900; CHECK-NEXT: [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]] 901; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]] 902; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]] 903; CHECK: if.else.postloop: 904; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 905; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]] 906; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 907; CHECK: for.inc.postloop: 908; CHECK-NEXT: [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ] 909; CHECK-NEXT: store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 910; CHECK-NEXT: [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1 911; CHECK-NEXT: [[CMP_POSTLOOP:%.*]] = icmp ne i32 [[DEC_POSTLOOP]], [[M]] 912; CHECK-NEXT: br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 913; 914entry: 915 %cmp14 = icmp slt i32 %M, 1024 916 br i1 %cmp14, label %for.body, label %for.cond.cleanup 917 918for.cond.cleanup: ; preds = %for.inc, %entry 919 ret void 920 921for.body: ; preds = %entry, %for.inc 922 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 923 %cmp1 = icmp slt i32 %iv, 1024 924 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv 925 %0 = load i32, ptr %arrayidx, align 4 926 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv 927 %1 = load i32, ptr %arrayidx2, align 4 928 %mul = mul nsw i32 %1, %0 929 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv 930 br i1 %cmp1, label %for.inc, label %if.else 931 932if.else: ; preds = %for.body 933 %2 = load i32, ptr %arrayidx3, align 4 934 %add = add nsw i32 %2, %mul 935 br label %for.inc 936 937for.inc: ; preds = %for.body, %if.else 938 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 939 store i32 %storemerge, ptr %arrayidx3, align 4 940 %dec = add nsw i32 %iv, -1 941 %cmp = icmp ne i32 %dec, %M 942 br i1 %cmp, label %for.body, label %for.cond.cleanup 943} 944 945define void @signed_var_imm_dec_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { 946; CHECK-LABEL: define void @signed_var_imm_dec_eq( 947; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) { 948; CHECK-NEXT: entry: 949; CHECK-NEXT: [[CMP14:%.*]] = icmp slt i32 [[M]], 1024 950; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 951; CHECK: for.body.preheader: 952; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[M]], 1 953; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024) 954; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1 955; CHECK-NEXT: [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0) 956; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1 957; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]] 958; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] 959; CHECK: for.body.preloop.preheader: 960; CHECK-NEXT: br label [[FOR_BODY_PRELOOP:%.*]] 961; CHECK: for.cond.cleanup.loopexit.loopexit: 962; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 963; CHECK: for.cond.cleanup.loopexit: 964; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 965; CHECK: for.cond.cleanup: 966; CHECK-NEXT: ret void 967; CHECK: mainloop: 968; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]] 969; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] 970; CHECK: for.body.preheader3: 971; CHECK-NEXT: br label [[FOR_BODY:%.*]] 972; CHECK: for.body: 973; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ] 974; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 975; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] 976; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 977; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] 978; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 979; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]] 980; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] 981; CHECK-NEXT: br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]] 982; CHECK: if.else: 983; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 984; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]] 985; CHECK-NEXT: br label [[FOR_INC]] 986; CHECK: for.inc: 987; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] 988; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 989; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 990; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DEC]], [[M]] 991; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]] 992; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true 993; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]] 994; CHECK: main.exit.selector: 995; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ] 996; CHECK-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]] 997; CHECK-NEXT: br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 998; CHECK: main.pseudo.exit: 999; CHECK-NEXT: [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 1000; CHECK-NEXT: [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] 1001; CHECK-NEXT: br label [[POSTLOOP:%.*]] 1002; CHECK: for.body.preloop: 1003; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ] 1004; CHECK-NEXT: [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024 1005; CHECK-NEXT: [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]] 1006; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4 1007; CHECK-NEXT: [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]] 1008; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4 1009; CHECK-NEXT: [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP10]], [[TMP9]] 1010; CHECK-NEXT: [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]] 1011; CHECK-NEXT: br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]] 1012; CHECK: if.else.preloop: 1013; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4 1014; CHECK-NEXT: [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP11]], [[MUL_PRELOOP]] 1015; CHECK-NEXT: br label [[FOR_INC_PRELOOP]] 1016; CHECK: for.inc.preloop: 1017; CHECK-NEXT: [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ] 1018; CHECK-NEXT: store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4 1019; CHECK-NEXT: [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1 1020; CHECK-NEXT: [[CMP_PRELOOP:%.*]] = icmp eq i32 [[DEC_PRELOOP]], [[M]] 1021; CHECK-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]] 1022; CHECK-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true 1023; CHECK-NEXT: br i1 [[TMP13]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[FOR_BODY_PRELOOP]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 1024; CHECK: preloop.exit.selector: 1025; CHECK-NEXT: [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ] 1026; CHECK-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]] 1027; CHECK-NEXT: br i1 [[TMP14]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] 1028; CHECK: preloop.pseudo.exit: 1029; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 1030; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] 1031; CHECK-NEXT: br label [[MAINLOOP]] 1032; CHECK: postloop: 1033; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] 1034; CHECK: for.body.postloop: 1035; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ] 1036; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024 1037; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]] 1038; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 1039; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]] 1040; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 1041; CHECK-NEXT: [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP16]], [[TMP15]] 1042; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]] 1043; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]] 1044; CHECK: if.else.postloop: 1045; CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 1046; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP17]], [[MUL_POSTLOOP]] 1047; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] 1048; CHECK: for.inc.postloop: 1049; CHECK-NEXT: [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ] 1050; CHECK-NEXT: store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 1051; CHECK-NEXT: [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1 1052; CHECK-NEXT: [[CMP_POSTLOOP:%.*]] = icmp eq i32 [[DEC_POSTLOOP]], [[M]] 1053; CHECK-NEXT: br i1 [[CMP_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone [[META5]] 1054; 1055entry: 1056 %cmp14 = icmp slt i32 %M, 1024 1057 br i1 %cmp14, label %for.body, label %for.cond.cleanup 1058 1059for.cond.cleanup: ; preds = %for.inc, %entry 1060 ret void 1061 1062for.body: ; preds = %entry, %for.inc 1063 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 1064 %cmp1 = icmp slt i32 %iv, 1024 1065 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv 1066 %0 = load i32, ptr %arrayidx, align 4 1067 %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv 1068 %1 = load i32, ptr %arrayidx2, align 4 1069 %mul = mul nsw i32 %1, %0 1070 %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv 1071 br i1 %cmp1, label %for.inc, label %if.else 1072 1073if.else: ; preds = %for.body 1074 %2 = load i32, ptr %arrayidx3, align 4 1075 %add = add nsw i32 %2, %mul 1076 br label %for.inc 1077 1078for.inc: ; preds = %for.body, %if.else 1079 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 1080 store i32 %storemerge, ptr %arrayidx3, align 4 1081 %dec = add nsw i32 %iv, -1 1082 %cmp = icmp eq i32 %dec, %M 1083 br i1 %cmp, label %for.cond.cleanup, label %for.body 1084} 1085 1086;; Negative test 1087define void @test_dec_bound_with_smaller_start_than_bound(i64 %0) { 1088; CHECK-LABEL: define void @test_dec_bound_with_smaller_start_than_bound( 1089; CHECK-SAME: i64 [[TMP0:%.*]]) { 1090; CHECK-NEXT: entry: 1091; CHECK-NEXT: br label [[FOR_BODY:%.*]] 1092; CHECK: for.body: 1093; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 1094; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[IV]], [[TMP0]] 1095; CHECK-NEXT: br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_DEC]] 1096; CHECK: if.else: 1097; CHECK-NEXT: br label [[FOR_DEC]] 1098; CHECK: for.dec: 1099; CHECK-NEXT: [[DEC]] = sub nuw nsw i64 [[IV]], 1 1100; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i64 [[DEC]], 1 1101; CHECK-NEXT: br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]] 1102; CHECK: exit: 1103; CHECK-NEXT: ret void 1104; 1105entry: 1106 br label %for.body 1107 1108for.body: ; preds = %for.dec, %entry 1109 %iv = phi i64 [ %dec, %for.dec ], [ 0, %entry ] 1110 %1 = icmp slt i64 %iv, %0 1111 br i1 %1, label %if.else, label %for.dec 1112 1113if.else: ; preds = %for.body 1114 br label %for.dec 1115 1116for.dec: ; preds = %if.else, %for.body 1117 %dec = sub nuw nsw i64 %iv, 1 1118 %2 = icmp slt i64 %dec, 1 1119 br i1 %2, label %exit, label %for.body 1120 1121exit: ; preds = %for.dec 1122 ret void 1123} 1124 1125;; Negative test 1126define void @test_inc_bound_with_bigger_start_than_bound(i32 %0) { 1127; CHECK-LABEL: define void @test_inc_bound_with_bigger_start_than_bound( 1128; CHECK-SAME: i32 [[TMP0:%.*]]) { 1129; CHECK-NEXT: entry: 1130; CHECK-NEXT: br label [[FOR_BODY:%.*]] 1131; CHECK: for.body: 1132; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 200, [[ENTRY:%.*]] ] 1133; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[IV]], [[TMP0]] 1134; CHECK-NEXT: br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_INC]] 1135; CHECK: if.else: 1136; CHECK-NEXT: br label [[FOR_INC]] 1137; CHECK: for.inc: 1138; CHECK-NEXT: [[INC]] = add nsw i32 [[IV]], 1 1139; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INC]], 100 1140; CHECK-NEXT: br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]] 1141; CHECK: exit: 1142; CHECK-NEXT: ret void 1143; 1144entry: 1145 br label %for.body 1146 1147for.body: ; preds = %for.inc, %entry 1148 %iv = phi i32 [ %inc, %for.inc ], [ 200, %entry ] 1149 %1 = icmp slt i32 %iv, %0 1150 br i1 %1, label %if.else, label %for.inc 1151 1152if.else: ; preds = %for.body 1153 br label %for.inc 1154 1155for.inc: ; preds = %if.else, %for.body 1156 %inc = add nsw i32 %iv, 1 1157 %2 = icmp sgt i32 %inc, 100 1158 br i1 %2, label %exit, label %for.body 1159 1160exit: ; preds = %for.inc 1161 ret void 1162} 1163