1117 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s3; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s4 5; Check that we can remove trivially non-failing range check.6define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {7; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {8; CHECK-NEXT: entry:9; CHECK-NEXT: br label [[LOOP:%.*]]10; CHECK: loop:11; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]12; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], 10013; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]14; CHECK: backedge:15; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 116; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i3217; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 10018; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]19; CHECK: exit:20; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]21; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]22; CHECK: check_failed:23; CHECK-NEXT: ret i32 -124;25 26entry:27 br label %loop28 29loop:30 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]31 %rc = icmp slt i64 %iv, 10032 br i1 %rc, label %backedge, label %check_failed33 34backedge:35 %iv.next = add i64 %iv, 136 %narrow.iv = trunc i64 %iv.next to i3237 %latch.cond = icmp slt i32 %narrow.iv, 10038 br i1 %latch.cond, label %loop, label %exit39 40exit:41 ret i32 %narrow.iv42 43check_failed:44 ret i32 -145}46 47; This range check fails on the last iteration, so it needs a postloop.48define i32 @test_increasing_slt_slt_wide_simple_postloop() {49; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_postloop() {50; CHECK-NEXT: entry:51; CHECK-NEXT: br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]52; CHECK: loop.preheader:53; CHECK-NEXT: br label [[LOOP:%.*]]54; CHECK: loop:55; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]56; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], 9957; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]58; CHECK: backedge:59; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 160; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i3261; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 10062; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i6463; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], 9964; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]65; CHECK: main.exit.selector:66; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]67; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]68; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]69; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], 10070; CHECK-NEXT: br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]71; CHECK: main.pseudo.exit:72; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]73; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]74; CHECK-NEXT: br label [[POSTLOOP:%.*]]75; CHECK: exit.loopexit:76; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]77; CHECK-NEXT: br label [[EXIT]]78; CHECK: exit:79; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]80; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]81; CHECK: check_failed.loopexit:82; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]83; CHECK: check_failed.loopexit2:84; CHECK-NEXT: br label [[CHECK_FAILED]]85; CHECK: check_failed:86; CHECK-NEXT: ret i32 -187; CHECK: postloop:88; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]89; CHECK: loop.postloop:90; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]91; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], 9992; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]93; CHECK: backedge.postloop:94; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 195; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i3296; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], 10097; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]]98;99 100entry:101 br label %loop102 103loop:104 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]105 %rc = icmp slt i64 %iv, 99106 br i1 %rc, label %backedge, label %check_failed107 108backedge:109 %iv.next = add i64 %iv, 1110 %narrow.iv = trunc i64 %iv.next to i32111 %latch.cond = icmp slt i32 %narrow.iv, 100112 br i1 %latch.cond, label %loop, label %exit113 114exit:115 ret i32 %narrow.iv116 117check_failed:118 ret i32 -1119}120 121; General case. If both %N and %M are non-negative, we do not need a preloop.122define i32 @test_increasing_slt_slt_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {123; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_non-negative124; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {125; CHECK-NEXT: entry:126; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6:![0-9]+]]127; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7:![0-9]+]]128; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64129; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 [[TMP0]])130; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]131; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]132; CHECK: loop.preheader:133; CHECK-NEXT: br label [[LOOP:%.*]]134; CHECK: loop:135; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]136; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]137; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]138; CHECK: backedge:139; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1140; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32141; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]142; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64143; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]144; CHECK-NEXT: br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]145; CHECK: main.exit.selector:146; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]147; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]148; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]149; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64150; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]151; CHECK-NEXT: br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]152; CHECK: main.pseudo.exit:153; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]154; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]155; CHECK-NEXT: br label [[POSTLOOP:%.*]]156; CHECK: exit.loopexit:157; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]158; CHECK-NEXT: br label [[EXIT]]159; CHECK: exit:160; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]161; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]162; CHECK: check_failed.loopexit:163; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]164; CHECK: check_failed.loopexit2:165; CHECK-NEXT: br label [[CHECK_FAILED]]166; CHECK: check_failed:167; CHECK-NEXT: ret i32 -1168; CHECK: postloop:169; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]170; CHECK: loop.postloop:171; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]172; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]173; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]174; CHECK: backedge.postloop:175; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1176; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32177; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]178; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META5]]179;180 181entry:182 %N = load i32, ptr %n_ptr, !range !2183 %M = load i64, ptr %m_ptr, !range !1184 br label %loop185 186loop:187 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]188 %rc = icmp slt i64 %iv, %M189 br i1 %rc, label %backedge, label %check_failed190 191backedge:192 %iv.next = add i64 %iv, 1193 %narrow.iv = trunc i64 %iv.next to i32194 %latch.cond = icmp slt i32 %narrow.iv, %N195 br i1 %latch.cond, label %loop, label %exit196 197exit:198 ret i32 %narrow.iv199 200check_failed:201 ret i32 -1202}203 204; General case. Even though %M may be negative, we do not need a preloop because205; we make a non-negativity runtime check against M and do not go to main loop if206; M was negative.207define i32 @test_increasing_slt_slt_wide_general(ptr %n_ptr, ptr %m_ptr) {208; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general209; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {210; CHECK-NEXT: entry:211; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]212; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4213; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807214; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)215; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M]], [[SMAX]]216; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)217; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)218; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1219; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]220; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64221; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])222; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 0)223; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]224; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]225; CHECK: loop.preheader:226; CHECK-NEXT: br label [[LOOP:%.*]]227; CHECK: loop:228; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]229; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]230; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT5:%.*]]231; CHECK: backedge:232; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1233; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32234; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]235; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64236; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]237; CHECK-NEXT: br i1 [[TMP6]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]238; CHECK: main.exit.selector:239; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]240; CHECK-NEXT: [[NARROW_IV_LCSSA4:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]241; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]242; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64243; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]244; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]245; CHECK: main.pseudo.exit:246; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]247; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]248; CHECK-NEXT: br label [[POSTLOOP:%.*]]249; CHECK: exit.loopexit:250; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]251; CHECK-NEXT: br label [[EXIT]]252; CHECK: exit:253; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA4]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]254; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]255; CHECK: check_failed.loopexit:256; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]257; CHECK: check_failed.loopexit5:258; CHECK-NEXT: br label [[CHECK_FAILED]]259; CHECK: check_failed:260; CHECK-NEXT: ret i32 -1261; CHECK: postloop:262; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]263; CHECK: loop.postloop:264; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]265; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]266; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]267; CHECK: backedge.postloop:268; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1269; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32270; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]271; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META5]]272;273 274entry:275 %N = load i32, ptr %n_ptr, !range !2276 %M = load i64, ptr %m_ptr277 br label %loop278 279loop:280 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]281 %rc = icmp slt i64 %iv, %M282 br i1 %rc, label %backedge, label %check_failed283 284backedge:285 %iv.next = add i64 %iv, 1286 %narrow.iv = trunc i64 %iv.next to i32287 %latch.cond = icmp slt i32 %narrow.iv, %N288 br i1 %latch.cond, label %loop, label %exit289 290exit:291 ret i32 %narrow.iv292 293check_failed:294 ret i32 -1295}296 297; General case with preloop.298define i32 @test_increasing_slt_slt_wide_general_preloop(ptr %n_ptr, ptr %m_ptr) {299; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general_preloop300; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {301; CHECK-NEXT: entry:302; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]303; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4304; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)305; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)306; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = sub i64 -1, [[SMAX]]307; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807308; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 1)309; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M]], [[SMAX1]]310; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX]], 1311; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]312; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64313; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])314; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 -1)315; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 -1, [[EXIT_PRELOOP_AT]]316; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]317; CHECK: loop.preloop.preheader:318; CHECK-NEXT: br label [[LOOP_PRELOOP:%.*]]319; CHECK: mainloop:320; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i64 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]321; CHECK-NEXT: br i1 [[TMP6]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]322; CHECK: loop.preheader:323; CHECK-NEXT: br label [[LOOP:%.*]]324; CHECK: loop:325; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[LOOP_PREHEADER]] ]326; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]327; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT8:%.*]]328; CHECK: backedge:329; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1330; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32331; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]332; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64333; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]334; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]335; CHECK: main.exit.selector:336; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]337; CHECK-NEXT: [[NARROW_IV_LCSSA7:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]338; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]339; CHECK-NEXT: [[WIDE_N4:%.*]] = sext i32 [[N]] to i64340; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N4]]341; CHECK-NEXT: br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]342; CHECK: main.pseudo.exit:343; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]344; CHECK-NEXT: [[INDVAR_END5:%.*]] = phi i64 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]345; CHECK-NEXT: br label [[POSTLOOP:%.*]]346; CHECK: exit.loopexit:347; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]348; CHECK-NEXT: br label [[EXIT]]349; CHECK: exit:350; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA7]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_PRELOOP_LCSSA:%.*]], [[PRELOOP_EXIT_SELECTOR:%.*]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]351; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]352; CHECK: check_failed.loopexit:353; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]354; CHECK: check_failed.loopexit6:355; CHECK-NEXT: br label [[CHECK_FAILED]]356; CHECK: check_failed.loopexit8:357; CHECK-NEXT: br label [[CHECK_FAILED]]358; CHECK: check_failed:359; CHECK-NEXT: ret i32 -1360; CHECK: loop.preloop:361; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP:%.*]], [[BACKEDGE_PRELOOP:%.*]] ], [ 0, [[LOOP_PRELOOP_PREHEADER]] ]362; CHECK-NEXT: [[RC_PRELOOP:%.*]] = icmp slt i64 [[IV_PRELOOP]], [[M]]363; CHECK-NEXT: br i1 [[RC_PRELOOP]], label [[BACKEDGE_PRELOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]364; CHECK: backedge.preloop:365; CHECK-NEXT: [[IV_NEXT_PRELOOP]] = add i64 [[IV_PRELOOP]], 1366; CHECK-NEXT: [[NARROW_IV_PRELOOP:%.*]] = trunc i64 [[IV_PRELOOP]] to i32367; CHECK-NEXT: [[LATCH_COND_PRELOOP:%.*]] = icmp slt i32 [[NARROW_IV_PRELOOP]], [[N]]368; CHECK-NEXT: [[WIDE_NARROW_IV_PRELOOP:%.*]] = sext i32 [[NARROW_IV_PRELOOP]] to i64369; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP]], [[EXIT_PRELOOP_AT]]370; CHECK-NEXT: br i1 [[TMP9]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META5]]371; CHECK: preloop.exit.selector:372; CHECK-NEXT: [[IV_NEXT_PRELOOP_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP]], [[BACKEDGE_PRELOOP]] ]373; CHECK-NEXT: [[NARROW_IV_PRELOOP_LCSSA]] = phi i32 [ [[NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]374; CHECK-NEXT: [[WIDE_NARROW_IV_PRELOOP_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]375; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64376; CHECK-NEXT: [[TMP10:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[WIDE_N]]377; CHECK-NEXT: br i1 [[TMP10]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]378; CHECK: preloop.pseudo.exit:379; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]380; CHECK-NEXT: [[INDVAR_END]] = phi i64 [ -1, [[ENTRY]] ], [ [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]381; CHECK-NEXT: br label [[MAINLOOP]]382; CHECK: postloop:383; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]384; CHECK: loop.postloop:385; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]386; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]387; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT6:%.*]]388; CHECK: backedge.postloop:389; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1390; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_POSTLOOP]] to i32391; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]392; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META5]]393;394 395entry:396 %N = load i32, ptr %n_ptr, !range !2397 %M = load i64, ptr %m_ptr398 br label %loop399 400loop:401 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]402 %rc = icmp slt i64 %iv, %M403 br i1 %rc, label %backedge, label %check_failed404 405backedge:406 %iv.next = add i64 %iv, 1407 %narrow.iv = trunc i64 %iv to i32408 %latch.cond = icmp slt i32 %narrow.iv, %N409 br i1 %latch.cond, label %loop, label %exit410 411exit:412 ret i32 %narrow.iv413 414check_failed:415 ret i32 -1416}417 418; Same as above, multiple checks.419define i32 @test_increasing_slt_slt_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {420; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_multiple_checks421; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {422; CHECK-NEXT: entry:423; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]424; CHECK-NEXT: [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4425; CHECK-NEXT: [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4426; CHECK-NEXT: [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4427; CHECK-NEXT: [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4428; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M2]], -9223372036854775807429; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)430; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M2]], [[SMAX]]431; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)432; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)433; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1434; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]435; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[M1]], -9223372036854775807436; CHECK-NEXT: [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP4]], i64 0)437; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[M1]], [[SMAX2]]438; CHECK-NEXT: [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)439; CHECK-NEXT: [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)440; CHECK-NEXT: [[TMP6:%.*]] = add nsw i64 [[SMAX4]], 1441; CHECK-NEXT: [[TMP7:%.*]] = mul i64 [[TMP5]], [[TMP6]]442; CHECK-NEXT: [[SMIN5:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP7]])443; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[M3]], -9223372036854775807444; CHECK-NEXT: [[SMAX6:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP8]], i64 0)445; CHECK-NEXT: [[TMP9:%.*]] = sub i64 [[M3]], [[SMAX6]]446; CHECK-NEXT: [[SMIN7:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)447; CHECK-NEXT: [[SMAX8:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN7]], i64 -1)448; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[SMAX8]], 1449; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]450; CHECK-NEXT: [[SMIN9:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN5]], i64 [[TMP11]])451; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[M4]], -9223372036854775807452; CHECK-NEXT: [[SMAX10:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP12]], i64 0)453; CHECK-NEXT: [[TMP13:%.*]] = sub i64 [[M4]], [[SMAX10]]454; CHECK-NEXT: [[SMIN11:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)455; CHECK-NEXT: [[SMAX12:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN11]], i64 -1)456; CHECK-NEXT: [[TMP14:%.*]] = add nsw i64 [[SMAX12]], 1457; CHECK-NEXT: [[TMP15:%.*]] = mul i64 [[TMP13]], [[TMP14]]458; CHECK-NEXT: [[SMIN13:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN9]], i64 [[TMP15]])459; CHECK-NEXT: [[TMP16:%.*]] = zext nneg i32 [[N]] to i64460; CHECK-NEXT: [[SMIN14:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN13]], i64 [[TMP16]])461; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN14]], i64 0)462; CHECK-NEXT: [[TMP17:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]463; CHECK-NEXT: br i1 [[TMP17]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]464; CHECK: loop.preheader:465; CHECK-NEXT: br label [[LOOP:%.*]]466; CHECK: loop:467; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]468; CHECK-NEXT: [[RC1:%.*]] = icmp slt i64 [[IV]], [[M1]]469; CHECK-NEXT: [[RC2:%.*]] = icmp slt i64 [[IV]], [[M2]]470; CHECK-NEXT: [[RC3:%.*]] = icmp slt i64 [[IV]], [[M3]]471; CHECK-NEXT: [[RC4:%.*]] = icmp slt i64 [[IV]], [[M4]]472; CHECK-NEXT: [[C1:%.*]] = and i1 true, true473; CHECK-NEXT: [[C2:%.*]] = and i1 [[C1]], true474; CHECK-NEXT: [[RC:%.*]] = and i1 [[C2]], true475; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT17:%.*]]476; CHECK: backedge:477; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1478; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32479; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]480; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64481; CHECK-NEXT: [[TMP18:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]482; CHECK-NEXT: br i1 [[TMP18]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]483; CHECK: main.exit.selector:484; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]485; CHECK-NEXT: [[NARROW_IV_LCSSA16:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]486; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]487; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64488; CHECK-NEXT: [[TMP19:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]489; CHECK-NEXT: br i1 [[TMP19]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]490; CHECK: main.pseudo.exit:491; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]492; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]493; CHECK-NEXT: br label [[POSTLOOP:%.*]]494; CHECK: exit.loopexit:495; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]496; CHECK-NEXT: br label [[EXIT]]497; CHECK: exit:498; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA16]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]499; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]500; CHECK: check_failed.loopexit:501; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]502; CHECK: check_failed.loopexit17:503; CHECK-NEXT: br label [[CHECK_FAILED]]504; CHECK: check_failed:505; CHECK-NEXT: ret i32 -1506; CHECK: postloop:507; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]508; CHECK: loop.postloop:509; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]510; CHECK-NEXT: [[RC1_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M1]]511; CHECK-NEXT: [[RC2_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M2]]512; CHECK-NEXT: [[RC3_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M3]]513; CHECK-NEXT: [[RC4_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M4]]514; CHECK-NEXT: [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]515; CHECK-NEXT: [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]516; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]517; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]518; CHECK: backedge.postloop:519; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1520; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32521; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]522; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META5]]523;524 525entry:526 %N = load i32, ptr %n_ptr, !range !2527 %M1 = load i64, ptr %m1_ptr528 %M2 = load i64, ptr %m2_ptr529 %M3 = load i64, ptr %m3_ptr530 %M4 = load i64, ptr %m4_ptr531 br label %loop532 533loop:534 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]535 %rc1 = icmp slt i64 %iv, %M1536 %rc2 = icmp slt i64 %iv, %M2537 %rc3 = icmp slt i64 %iv, %M3538 %rc4 = icmp slt i64 %iv, %M4539 %c1 = and i1 %rc1, %rc2540 %c2 = and i1 %c1, %rc3541 %rc = and i1 %c2, %rc4542 br i1 %rc, label %backedge, label %check_failed543 544backedge:545 %iv.next = add i64 %iv, 1546 %narrow.iv = trunc i64 %iv.next to i32547 %latch.cond = icmp slt i32 %narrow.iv, %N548 br i1 %latch.cond, label %loop, label %exit549 550exit:551 ret i32 %narrow.iv552 553check_failed:554 ret i32 -1555}556 557; Wide IV against narrow range check. We don't currently support it.558define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {559; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {560; CHECK-NEXT: entry:561; CHECK-NEXT: br label [[LOOP:%.*]]562; CHECK: loop:563; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]564; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32565; CHECK-NEXT: [[RC:%.*]] = icmp slt i32 [[NARROW_IV]], 101566; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]567; CHECK: backedge:568; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1569; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i64 [[IV]], 100570; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]571; CHECK: exit:572; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]573; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA1]]574; CHECK: check_failed:575; CHECK-NEXT: ret i32 -1576;577 578entry:579 br label %loop580 581loop:582 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]583 %narrow.iv = trunc i64 %iv to i32584 %rc = icmp slt i32 %narrow.iv, 101585 br i1 %rc, label %backedge, label %check_failed586 587backedge:588 %iv.next = add i64 %iv, 1589 %latch.cond = icmp slt i64 %iv, 100590 br i1 %latch.cond, label %loop, label %exit591 592exit:593 ret i32 %narrow.iv594 595check_failed:596 ret i32 -1597}598 599; Check that we can remove trivially non-failing range check.600define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {601; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {602; CHECK-NEXT: entry:603; CHECK-NEXT: br label [[LOOP:%.*]]604; CHECK: loop:605; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]606; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], 100607; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]608; CHECK: backedge:609; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1610; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32611; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100612; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]613; CHECK: exit:614; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]615; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]616; CHECK: check_failed:617; CHECK-NEXT: ret i32 -1618;619 620entry:621 br label %loop622 623loop:624 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]625 %rc = icmp ult i64 %iv, 100626 br i1 %rc, label %backedge, label %check_failed627 628backedge:629 %iv.next = add i64 %iv, 1630 %narrow.iv = trunc i64 %iv.next to i32631 %latch.cond = icmp ult i32 %narrow.iv, 100632 br i1 %latch.cond, label %loop, label %exit633 634exit:635 ret i32 %narrow.iv636 637check_failed:638 ret i32 -1639}640 641; This range check fails on the last iteration, so it needs a postloop.642define i32 @test_increasing_ult_ult_wide_simple_postloop() {643; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_postloop() {644; CHECK-NEXT: entry:645; CHECK-NEXT: br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]646; CHECK: loop.preheader:647; CHECK-NEXT: br label [[LOOP:%.*]]648; CHECK: loop:649; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]650; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], 99651; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]652; CHECK: backedge:653; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1654; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32655; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100656; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64657; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], 99658; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]659; CHECK: main.exit.selector:660; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]661; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]662; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]663; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], 100664; CHECK-NEXT: br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]665; CHECK: main.pseudo.exit:666; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]667; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]668; CHECK-NEXT: br label [[POSTLOOP:%.*]]669; CHECK: exit.loopexit:670; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]671; CHECK-NEXT: br label [[EXIT]]672; CHECK: exit:673; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]674; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]675; CHECK: check_failed.loopexit:676; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]677; CHECK: check_failed.loopexit2:678; CHECK-NEXT: br label [[CHECK_FAILED]]679; CHECK: check_failed:680; CHECK-NEXT: ret i32 -1681; CHECK: postloop:682; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]683; CHECK: loop.postloop:684; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]685; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], 99686; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]687; CHECK: backedge.postloop:688; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1689; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32690; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], 100691; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP13:![0-9]+]], !loop_constrainer.loop.clone [[META5]]692;693 694entry:695 br label %loop696 697loop:698 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]699 %rc = icmp ult i64 %iv, 99700 br i1 %rc, label %backedge, label %check_failed701 702backedge:703 %iv.next = add i64 %iv, 1704 %narrow.iv = trunc i64 %iv.next to i32705 %latch.cond = icmp ult i32 %narrow.iv, 100706 br i1 %latch.cond, label %loop, label %exit707 708exit:709 ret i32 %narrow.iv710 711check_failed:712 ret i32 -1713}714 715; General case. If both %N and %M are non-negative, we do not need a preloop.716define i32 @test_increasing_ult_ult_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {717; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_non-negative718; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {719; CHECK-NEXT: entry:720; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]721; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7]]722; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64723; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[M]], i64 [[TMP0]])724; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]725; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]726; CHECK: loop.preheader:727; CHECK-NEXT: br label [[LOOP:%.*]]728; CHECK: loop:729; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]730; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]731; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]732; CHECK: backedge:733; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1734; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32735; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]736; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64737; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]738; CHECK-NEXT: br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]739; CHECK: main.exit.selector:740; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]741; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]742; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]743; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64744; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]745; CHECK-NEXT: br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]746; CHECK: main.pseudo.exit:747; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]748; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]749; CHECK-NEXT: br label [[POSTLOOP:%.*]]750; CHECK: exit.loopexit:751; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]752; CHECK-NEXT: br label [[EXIT]]753; CHECK: exit:754; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]755; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]756; CHECK: check_failed.loopexit:757; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]758; CHECK: check_failed.loopexit2:759; CHECK-NEXT: br label [[CHECK_FAILED]]760; CHECK: check_failed:761; CHECK-NEXT: ret i32 -1762; CHECK: postloop:763; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]764; CHECK: loop.postloop:765; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]766; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]767; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]768; CHECK: backedge.postloop:769; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1770; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32771; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]772; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone [[META5]]773;774 775entry:776 %N = load i32, ptr %n_ptr, !range !2777 %M = load i64, ptr %m_ptr, !range !1778 br label %loop779 780loop:781 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]782 %rc = icmp ult i64 %iv, %M783 br i1 %rc, label %backedge, label %check_failed784 785backedge:786 %iv.next = add i64 %iv, 1787 %narrow.iv = trunc i64 %iv.next to i32788 %latch.cond = icmp ult i32 %narrow.iv, %N789 br i1 %latch.cond, label %loop, label %exit790 791exit:792 ret i32 %narrow.iv793 794check_failed:795 ret i32 -1796}797 798; General case. Even though %M may be negative, we do not need a preloop because799; we make a non-negativity runtime check against M and do not go to main loop if800; M was negative.801define i32 @test_increasing_ult_ult_wide_general(ptr %n_ptr, ptr %m_ptr) {802; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_general803; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {804; CHECK-NEXT: entry:805; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]806; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4807; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)808; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[M]], [[SMIN]]809; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)810; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1811; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]812; CHECK-NEXT: [[TMP3:%.*]] = zext nneg i32 [[N]] to i64813; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP3]])814; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]815; CHECK-NEXT: br i1 [[TMP4]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]816; CHECK: loop.preheader:817; CHECK-NEXT: br label [[LOOP:%.*]]818; CHECK: loop:819; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]820; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]821; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]822; CHECK: backedge:823; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1824; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32825; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]826; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64827; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]828; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]829; CHECK: main.exit.selector:830; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]831; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]832; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]833; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64834; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]835; CHECK-NEXT: br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]836; CHECK: main.pseudo.exit:837; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]838; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]839; CHECK-NEXT: br label [[POSTLOOP:%.*]]840; CHECK: exit.loopexit:841; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]842; CHECK-NEXT: br label [[EXIT]]843; CHECK: exit:844; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]845; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]846; CHECK: check_failed.loopexit:847; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]848; CHECK: check_failed.loopexit2:849; CHECK-NEXT: br label [[CHECK_FAILED]]850; CHECK: check_failed:851; CHECK-NEXT: ret i32 -1852; CHECK: postloop:853; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]854; CHECK: loop.postloop:855; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]856; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]857; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]858; CHECK: backedge.postloop:859; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1860; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32861; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]862; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone [[META5]]863;864 865entry:866 %N = load i32, ptr %n_ptr, !range !2867 %M = load i64, ptr %m_ptr868 br label %loop869 870loop:871 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]872 %rc = icmp ult i64 %iv, %M873 br i1 %rc, label %backedge, label %check_failed874 875backedge:876 %iv.next = add i64 %iv, 1877 %narrow.iv = trunc i64 %iv.next to i32878 %latch.cond = icmp ult i32 %narrow.iv, %N879 br i1 %latch.cond, label %loop, label %exit880 881exit:882 ret i32 %narrow.iv883 884check_failed:885 ret i32 -1886}887 888; Same as above, multiple checks.889define i32 @test_increasing_ult_ult_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {890; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_multiple_checks891; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {892; CHECK-NEXT: entry:893; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]894; CHECK-NEXT: [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4895; CHECK-NEXT: [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4896; CHECK-NEXT: [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4897; CHECK-NEXT: [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4898; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)899; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[M2]], [[SMIN]]900; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)901; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1902; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]903; CHECK-NEXT: [[SMIN1:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)904; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[M1]], [[SMIN1]]905; CHECK-NEXT: [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN1]], i64 -1)906; CHECK-NEXT: [[TMP4:%.*]] = add nsw i64 [[SMAX2]], 1907; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP3]], [[TMP4]]908; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP5]])909; CHECK-NEXT: [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)910; CHECK-NEXT: [[TMP6:%.*]] = sub i64 [[M3]], [[SMIN3]]911; CHECK-NEXT: [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)912; CHECK-NEXT: [[TMP7:%.*]] = add nsw i64 [[SMAX4]], 1913; CHECK-NEXT: [[TMP8:%.*]] = mul i64 [[TMP6]], [[TMP7]]914; CHECK-NEXT: [[UMIN5:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN]], i64 [[TMP8]])915; CHECK-NEXT: [[SMIN6:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)916; CHECK-NEXT: [[TMP9:%.*]] = sub i64 [[M4]], [[SMIN6]]917; CHECK-NEXT: [[SMAX7:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN6]], i64 -1)918; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[SMAX7]], 1919; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]920; CHECK-NEXT: [[UMIN8:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN5]], i64 [[TMP11]])921; CHECK-NEXT: [[TMP12:%.*]] = zext nneg i32 [[N]] to i64922; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN8]], i64 [[TMP12]])923; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]924; CHECK-NEXT: br i1 [[TMP13]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]925; CHECK: loop.preheader:926; CHECK-NEXT: br label [[LOOP:%.*]]927; CHECK: loop:928; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]929; CHECK-NEXT: [[RC1:%.*]] = icmp ult i64 [[IV]], [[M1]]930; CHECK-NEXT: [[RC2:%.*]] = icmp ult i64 [[IV]], [[M2]]931; CHECK-NEXT: [[RC3:%.*]] = icmp ult i64 [[IV]], [[M3]]932; CHECK-NEXT: [[RC4:%.*]] = icmp ult i64 [[IV]], [[M4]]933; CHECK-NEXT: [[C1:%.*]] = and i1 true, true934; CHECK-NEXT: [[C2:%.*]] = and i1 [[C1]], true935; CHECK-NEXT: [[RC:%.*]] = and i1 [[C2]], true936; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT11:%.*]]937; CHECK: backedge:938; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1939; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32940; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]941; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64942; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]943; CHECK-NEXT: br i1 [[TMP14]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]944; CHECK: main.exit.selector:945; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]946; CHECK-NEXT: [[NARROW_IV_LCSSA10:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]947; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]948; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64949; CHECK-NEXT: [[TMP15:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]950; CHECK-NEXT: br i1 [[TMP15]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]951; CHECK: main.pseudo.exit:952; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]953; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]954; CHECK-NEXT: br label [[POSTLOOP:%.*]]955; CHECK: exit.loopexit:956; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]957; CHECK-NEXT: br label [[EXIT]]958; CHECK: exit:959; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA10]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]960; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]961; CHECK: check_failed.loopexit:962; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]963; CHECK: check_failed.loopexit11:964; CHECK-NEXT: br label [[CHECK_FAILED]]965; CHECK: check_failed:966; CHECK-NEXT: ret i32 -1967; CHECK: postloop:968; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]969; CHECK: loop.postloop:970; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]971; CHECK-NEXT: [[RC1_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M1]]972; CHECK-NEXT: [[RC2_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M2]]973; CHECK-NEXT: [[RC3_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M3]]974; CHECK-NEXT: [[RC4_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M4]]975; CHECK-NEXT: [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]976; CHECK-NEXT: [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]977; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]978; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]979; CHECK: backedge.postloop:980; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1981; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32982; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]983; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone [[META5]]984;985 986entry:987 %N = load i32, ptr %n_ptr, !range !2988 %M1 = load i64, ptr %m1_ptr989 %M2 = load i64, ptr %m2_ptr990 %M3 = load i64, ptr %m3_ptr991 %M4 = load i64, ptr %m4_ptr992 br label %loop993 994loop:995 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]996 %rc1 = icmp ult i64 %iv, %M1997 %rc2 = icmp ult i64 %iv, %M2998 %rc3 = icmp ult i64 %iv, %M3999 %rc4 = icmp ult i64 %iv, %M41000 %c1 = and i1 %rc1, %rc21001 %c2 = and i1 %c1, %rc31002 %rc = and i1 %c2, %rc41003 br i1 %rc, label %backedge, label %check_failed1004 1005backedge:1006 %iv.next = add i64 %iv, 11007 %narrow.iv = trunc i64 %iv.next to i321008 %latch.cond = icmp ult i32 %narrow.iv, %N1009 br i1 %latch.cond, label %loop, label %exit1010 1011exit:1012 ret i32 %narrow.iv1013 1014check_failed:1015 ret i32 -11016}1017 1018; Wide IV against narrow range check. We don't currently support it.1019define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {1020; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {1021; CHECK-NEXT: entry:1022; CHECK-NEXT: br label [[LOOP:%.*]]1023; CHECK: loop:1024; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]1025; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i321026; CHECK-NEXT: [[RC:%.*]] = icmp ult i32 [[NARROW_IV]], 1011027; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]1028; CHECK: backedge:1029; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11030; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i64 [[IV]], 1001031; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]1032; CHECK: exit:1033; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]1034; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA1]]1035; CHECK: check_failed:1036; CHECK-NEXT: ret i32 -11037;1038 1039entry:1040 br label %loop1041 1042loop:1043 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]1044 %narrow.iv = trunc i64 %iv to i321045 %rc = icmp ult i32 %narrow.iv, 1011046 br i1 %rc, label %backedge, label %check_failed1047 1048backedge:1049 %iv.next = add i64 %iv, 11050 %latch.cond = icmp ult i64 %iv, 1001051 br i1 %latch.cond, label %loop, label %exit1052 1053exit:1054 ret i32 %narrow.iv1055 1056check_failed:1057 ret i32 -11058}1059 1060; Check that fake wide exit doesn't inhibit the transform.1061define i16 @test_fake_wide_exit(i64 %x) {1062; CHECK-LABEL: define i16 @test_fake_wide_exit1063; CHECK-SAME: (i64 [[X:%.*]]) {1064; CHECK-NEXT: entry:1065; CHECK-NEXT: br label [[LOOP:%.*]]1066; CHECK: loop:1067; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]1068; CHECK-NEXT: [[IV_WIDE:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_WIDE_NEXT:%.*]], [[BACKEDGE]] ]1069; CHECK-NEXT: [[RC:%.*]] = icmp slt i32 [[IV]], 1001070; CHECK-NEXT: br i1 true, label [[CHECKED:%.*]], label [[CHECK_FAILED:%.*]]1071; CHECK: checked:1072; CHECK-NEXT: [[RC_WIDE:%.*]] = icmp ult i64 [[IV_WIDE]], [[X]]1073; CHECK-NEXT: br i1 [[RC_WIDE]], label [[BACKEDGE]], label [[CHECK_FAILED]]1074; CHECK: backedge:1075; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11076; CHECK-NEXT: [[IV_WIDE_NEXT]] = add i64 [[IV_WIDE]], 11077; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i32 [[IV_NEXT]] to i161078; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i16 [[NARROW_IV]], 1001079; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]1080; CHECK: exit:1081; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i16 [ [[NARROW_IV]], [[BACKEDGE]] ]1082; CHECK-NEXT: ret i16 [[NARROW_IV_LCSSA]]1083; CHECK: check_failed:1084; CHECK-NEXT: ret i16 -11085;1086entry:1087 br label %loop1088 1089loop:1090 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]1091 %iv.wide = phi i64 [ 0, %entry ], [ %iv.wide.next, %backedge ]1092 %rc = icmp slt i32 %iv, 1001093 br i1 %rc, label %checked, label %check_failed1094 1095checked:1096 %rc.wide = icmp ult i64 %iv.wide, %x1097 br i1 %rc.wide, label %backedge, label %check_failed1098 1099backedge:1100 %iv.next = add i32 %iv, 11101 %iv.wide.next = add i64 %iv.wide, 11102 %narrow.iv = trunc i32 %iv.next to i161103 %latch.cond = icmp slt i16 %narrow.iv, 1001104 br i1 %latch.cond, label %loop, label %exit1105 1106exit:1107 ret i16 %narrow.iv1108 1109check_failed:1110 ret i16 -11111}1112 1113 1114!0 = !{i32 0, i32 2147483647}1115!1 = !{i64 0, i64 9223372036854775807}1116!2 = !{i32 1, i32 2147483647}1117