[llvm] 05e4c01 - [Test] Regenerate test checks using auto-updater

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 12 23:33:32 PDT 2023


Author: Max Kazantsev
Date: 2023-04-13T13:33:14+07:00
New Revision: 05e4c0142dd4279e54dd8c3db6325367971677d1

URL: https://github.com/llvm/llvm-project/commit/05e4c0142dd4279e54dd8c3db6325367971677d1
DIFF: https://github.com/llvm/llvm-project/commit/05e4c0142dd4279e54dd8c3db6325367971677d1.diff

LOG: [Test] Regenerate test checks using auto-updater

Added: 
    

Modified: 
    llvm/test/Transforms/IRCE/wide_indvar.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/IRCE/wide_indvar.ll b/llvm/test/Transforms/IRCE/wide_indvar.ll
index ce8bf11ab9a7d..6fdcce574d349 100644
--- a/llvm/test/Transforms/IRCE/wide_indvar.ll
+++ b/llvm/test/Transforms/IRCE/wide_indvar.ll
@@ -1,14 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s
 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s
 
 ; Check that we can remove trivially non-failing range check.
 define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_no_postloop(
-; CHECK-NOT:   preloop
-; CHECK-NOT:   postloop
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i64 [[IV]], 100
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+;
 
 entry:
   br label %loop
@@ -33,15 +46,56 @@ check_failed:
 
 ; This range check fails on the last iteration, so it needs a postloop.
 define i32 @test_increasing_slt_slt_wide_simple_postloop() {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_postloop(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_postloop() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp slt i64 %wide.narrow.iv, 99
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i64 [[IV]], 99
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 100
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], 99
+; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], 100
+; CHECK-NEXT:    br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit2:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], 99
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP0:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   br label %loop
@@ -66,15 +120,63 @@ check_failed:
 
 ; General case. If both %N and %M are non-negative, we do not need a preloop.
 define i32 @test_increasing_slt_slt_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_non-negative(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_non-negative
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6:![0-9]+]]
+; CHECK-NEXT:    [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7:![0-9]+]]
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 [[TMP0]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp slt i64 %wide.narrow.iv, %exit.mainloop.at
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = sext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit2:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP8:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -103,15 +205,71 @@ check_failed:
 ; we make a non-negativity runtime check against M and do not go to main loop if
 ; M was negative.
 define i32 @test_increasing_slt_slt_wide_general(ptr %n_ptr, ptr %m_ptr) {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_general(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[M]], [[SMAX]]
+; CHECK-NEXT:    [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
+; CHECK-NEXT:    [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
+; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 0)
+; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp slt i64
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT5:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP6]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA4:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = sext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA4]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit5:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP9:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -138,15 +296,101 @@ check_failed:
 
 ; General case with preloop.
 define i32 @test_increasing_slt_slt_wide_general_preloop(ptr %n_ptr, ptr %m_ptr) {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_general_preloop(
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general_preloop
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
+; CHECK-NEXT:    [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
+; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = sub i64 -1, [[SMAX]]
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 1)
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[M]], [[SMAX1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i64 [[SMAX]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 -1)
+; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i64 -1, [[EXIT_PRELOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preloop.preheader:
+; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]
+; CHECK:       mainloop:
+; CHECK-NEXT:    [[TMP6:%.*]] = icmp slt i64 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP6]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp slt i64
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       preloop
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT8:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP7]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA7:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N4:%.*]] = sext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP8:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N4]]
+; CHECK-NEXT:    br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END5:%.*]] = phi i64 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; 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:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit6:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed.loopexit8:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       loop.preloop:
+; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP:%.*]], [[BACKEDGE_PRELOOP:%.*]] ], [ 0, [[LOOP_PRELOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC_PRELOOP:%.*]] = icmp slt i64 [[IV_PRELOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_PRELOOP]], label [[BACKEDGE_PRELOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.preloop:
+; CHECK-NEXT:    [[IV_NEXT_PRELOOP]] = add i64 [[IV_PRELOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_PRELOOP:%.*]] = trunc i64 [[IV_PRELOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_PRELOOP:%.*]] = icmp slt i32 [[NARROW_IV_PRELOOP]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_PRELOOP:%.*]] = sext i32 [[NARROW_IV_PRELOOP]] to i64
+; CHECK-NEXT:    [[TMP9:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP]], [[EXIT_PRELOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP9]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR]], !llvm.loop [[LOOP10:![0-9]+]], !irce.loop.clone !5
+; CHECK:       preloop.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_PRELOOP_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
+; CHECK-NEXT:    [[NARROW_IV_PRELOOP_LCSSA]] = phi i32 [ [[NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_PRELOOP_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = sext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP10]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]
+; CHECK:       preloop.pseudo.exit:
+; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END]] = phi i64 [ -1, [[ENTRY]] ], [ [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[MAINLOOP]]
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT6:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP11:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -173,17 +417,110 @@ check_failed:
 
 ; Same as above, multiple checks.
 define i32 @test_increasing_slt_slt_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {
-; CHECK-LABEL: @test_increasing_slt_slt_wide_multiple_checks(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_multiple_checks
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4
+; CHECK-NEXT:    [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4
+; CHECK-NEXT:    [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4
+; CHECK-NEXT:    [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[M2]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[M2]], [[SMAX]]
+; CHECK-NEXT:    [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)
+; CHECK-NEXT:    [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
+; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[M1]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP4]], i64 0)
+; CHECK-NEXT:    [[TMP5:%.*]] = sub i64 [[M1]], [[SMAX2]]
+; CHECK-NEXT:    [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)
+; CHECK-NEXT:    [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)
+; CHECK-NEXT:    [[TMP6:%.*]] = add nsw i64 [[SMAX4]], 1
+; CHECK-NEXT:    [[TMP7:%.*]] = mul i64 [[TMP5]], [[TMP6]]
+; CHECK-NEXT:    [[SMIN5:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP7]])
+; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[M3]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX6:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP8]], i64 0)
+; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 [[M3]], [[SMAX6]]
+; CHECK-NEXT:    [[SMIN7:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)
+; CHECK-NEXT:    [[SMAX8:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN7]], i64 -1)
+; CHECK-NEXT:    [[TMP10:%.*]] = add nsw i64 [[SMAX8]], 1
+; CHECK-NEXT:    [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
+; CHECK-NEXT:    [[SMIN9:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN5]], i64 [[TMP11]])
+; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[M4]], -9223372036854775807
+; CHECK-NEXT:    [[SMAX10:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP12]], i64 0)
+; CHECK-NEXT:    [[TMP13:%.*]] = sub i64 [[M4]], [[SMAX10]]
+; CHECK-NEXT:    [[SMIN11:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)
+; CHECK-NEXT:    [[SMAX12:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN11]], i64 -1)
+; CHECK-NEXT:    [[TMP14:%.*]] = add nsw i64 [[SMAX12]], 1
+; CHECK-NEXT:    [[TMP15:%.*]] = mul i64 [[TMP13]], [[TMP14]]
+; CHECK-NEXT:    [[SMIN13:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN9]], i64 [[TMP15]])
+; CHECK-NEXT:    [[TMP16:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[SMIN14:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN13]], i64 [[TMP16]])
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN14]], i64 0)
+; CHECK-NEXT:    [[TMP17:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP17]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       %c1 = and i1 true, true
-; CHECK:       %c2 = and i1 %c1, true
-; CHECK:       %rc = and i1 %c2, true
-; CHECK:       br i1 %rc, label %backedge, label %check_failed.loopexit
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp slt i64
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC1:%.*]] = icmp slt i64 [[IV]], [[M1]]
+; CHECK-NEXT:    [[RC2:%.*]] = icmp slt i64 [[IV]], [[M2]]
+; CHECK-NEXT:    [[RC3:%.*]] = icmp slt i64 [[IV]], [[M3]]
+; CHECK-NEXT:    [[RC4:%.*]] = icmp slt i64 [[IV]], [[M4]]
+; CHECK-NEXT:    [[C1:%.*]] = and i1 true, true
+; CHECK-NEXT:    [[C2:%.*]] = and i1 [[C1]], true
+; CHECK-NEXT:    [[RC:%.*]] = and i1 [[C2]], true
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT17:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP18:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP18]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA16:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = sext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP19:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP19]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA16]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit17:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC1_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M1]]
+; CHECK-NEXT:    [[RC2_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M2]]
+; CHECK-NEXT:    [[RC3_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M3]]
+; CHECK-NEXT:    [[RC4_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M4]]
+; CHECK-NEXT:    [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]
+; CHECK-NEXT:    [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP12:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -219,10 +556,24 @@ check_failed:
 
 ; Wide IV against narrow range check. We don't currently support it.
 define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {
-
-; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_negtest_narrow_rc(
-; CHECK-NOT:   i1 true
-; CHECK-NOT:   main
+; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i32 [[NARROW_IV]], 101
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp slt i64 [[IV]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA1]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+;
 
 entry:
   br label %loop
@@ -247,12 +598,24 @@ check_failed:
 
 ; Check that we can remove trivially non-failing range check.
 define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {
-
-; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_no_postloop(
-; CHECK-NOT:   preloop
-; CHECK-NOT:   postloop
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp ult i64 [[IV]], 100
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+;
 
 entry:
   br label %loop
@@ -277,15 +640,56 @@ check_failed:
 
 ; This range check fails on the last iteration, so it needs a postloop.
 define i32 @test_increasing_ult_ult_wide_simple_postloop() {
-
-; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_postloop(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_postloop() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp ult i64 %wide.narrow.iv, 99
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp ult i64 [[IV]], 99
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], 99
+; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], 100
+; CHECK-NEXT:    br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit2:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], 99
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP13:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   br label %loop
@@ -310,15 +714,63 @@ check_failed:
 
 ; General case. If both %N and %M are non-negative, we do not need a preloop.
 define i32 @test_increasing_ult_ult_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
-
-; CHECK-LABEL: @test_increasing_ult_ult_wide_non-negative(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_non-negative
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7]]
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[M]], i64 [[TMP0]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp ult i64 %wide.narrow.iv, %exit.mainloop.at
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit2:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP14:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -347,15 +799,68 @@ check_failed:
 ; we make a non-negativity runtime check against M and do not go to main loop if
 ; M was negative.
 define i32 @test_increasing_ult_ult_wide_general(ptr %n_ptr, ptr %m_ptr) {
-
-; CHECK-LABEL: @test_increasing_ult_ult_wide_general(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_general
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
+; CHECK-NEXT:    [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
+; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[M]], [[SMIN]]
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
+; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP3]])
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP4]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       br i1 true, label %backedge, label %check_failed
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp ult i64
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]
+; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit2:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP15:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -382,17 +887,101 @@ check_failed:
 
 ; Same as above, multiple checks.
 define i32 @test_increasing_ult_ult_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {
-; CHECK-LABEL: @test_increasing_ult_ult_wide_multiple_checks(
-; CHECK-NOT:   preloop
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_multiple_checks
+; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
+; CHECK-NEXT:    [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4
+; CHECK-NEXT:    [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4
+; CHECK-NEXT:    [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4
+; CHECK-NEXT:    [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4
+; CHECK-NEXT:    [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)
+; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[M2]], [[SMIN]]
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
+; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[SMIN1:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)
+; CHECK-NEXT:    [[TMP3:%.*]] = sub i64 [[M1]], [[SMIN1]]
+; CHECK-NEXT:    [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN1]], i64 -1)
+; CHECK-NEXT:    [[TMP4:%.*]] = add nsw i64 [[SMAX2]], 1
+; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP3]], [[TMP4]]
+; CHECK-NEXT:    [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP5]])
+; CHECK-NEXT:    [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)
+; CHECK-NEXT:    [[TMP6:%.*]] = sub i64 [[M3]], [[SMIN3]]
+; CHECK-NEXT:    [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)
+; CHECK-NEXT:    [[TMP7:%.*]] = add nsw i64 [[SMAX4]], 1
+; CHECK-NEXT:    [[TMP8:%.*]] = mul i64 [[TMP6]], [[TMP7]]
+; CHECK-NEXT:    [[UMIN5:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN]], i64 [[TMP8]])
+; CHECK-NEXT:    [[SMIN6:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)
+; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 [[M4]], [[SMIN6]]
+; CHECK-NEXT:    [[SMAX7:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN6]], i64 -1)
+; CHECK-NEXT:    [[TMP10:%.*]] = add nsw i64 [[SMAX7]], 1
+; CHECK-NEXT:    [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
+; CHECK-NEXT:    [[UMIN8:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN5]], i64 [[TMP11]])
+; CHECK-NEXT:    [[TMP12:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN8]], i64 [[TMP12]])
+; CHECK-NEXT:    [[TMP13:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP13]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK:       %c1 = and i1 true, true
-; CHECK:       %c2 = and i1 %c1, true
-; CHECK:       %rc = and i1 %c2, true
-; CHECK:       br i1 %rc, label %backedge, label %check_failed.loopexit
-; CHECK:       backedge
-; CHECK:       [[COND:%[^ ]+]] = icmp ult i64
-; CHECK:       br i1 [[COND]], label %loop, label %main.exit.selector
-; CHECK:       postloop
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT:    [[RC1:%.*]] = icmp ult i64 [[IV]], [[M1]]
+; CHECK-NEXT:    [[RC2:%.*]] = icmp ult i64 [[IV]], [[M2]]
+; CHECK-NEXT:    [[RC3:%.*]] = icmp ult i64 [[IV]], [[M3]]
+; CHECK-NEXT:    [[RC4:%.*]] = icmp ult i64 [[IV]], [[M4]]
+; CHECK-NEXT:    [[C1:%.*]] = and i1 true, true
+; CHECK-NEXT:    [[C2:%.*]] = and i1 [[C1]], true
+; CHECK-NEXT:    [[RC:%.*]] = and i1 [[C2]], true
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT11:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
+; CHECK-NEXT:    [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
+; CHECK-NEXT:    br i1 [[TMP14]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
+; CHECK:       main.exit.selector:
+; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[NARROW_IV_LCSSA10:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    [[WIDE_N:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT:    [[TMP15:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
+; CHECK-NEXT:    br i1 [[TMP15]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
+; CHECK:       main.pseudo.exit:
+; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
+; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA10]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA]]
+; CHECK:       check_failed.loopexit:
+; CHECK-NEXT:    br label [[CHECK_FAILED:%.*]]
+; CHECK:       check_failed.loopexit11:
+; CHECK-NEXT:    br label [[CHECK_FAILED]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+; CHECK:       postloop:
+; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]
+; CHECK:       loop.postloop:
+; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
+; CHECK-NEXT:    [[RC1_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M1]]
+; CHECK-NEXT:    [[RC2_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M2]]
+; CHECK-NEXT:    [[RC3_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M3]]
+; CHECK-NEXT:    [[RC4_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M4]]
+; CHECK-NEXT:    [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]
+; CHECK-NEXT:    [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]
+; CHECK-NEXT:    [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]
+; CHECK-NEXT:    br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
+; CHECK:       backedge.postloop:
+; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
+; CHECK-NEXT:    [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
+; CHECK-NEXT:    [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
+; CHECK-NEXT:    br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP16:![0-9]+]], !irce.loop.clone !5
+;
 
 entry:
   %N = load i32, ptr %n_ptr, !range !2
@@ -428,10 +1017,24 @@ check_failed:
 
 ; Wide IV against narrow range check. We don't currently support it.
 define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {
-
-; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_negtest_narrow_rc(
-; CHECK-NOT:   i1 true
-; CHECK-NOT:   main
+; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
+; CHECK-NEXT:    [[RC:%.*]] = icmp ult i32 [[NARROW_IV]], 101
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
+; CHECK:       backedge:
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    [[LATCH_COND:%.*]] = icmp ult i64 [[IV]], 100
+; CHECK-NEXT:    br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
+; CHECK-NEXT:    ret i32 [[NARROW_IV_LCSSA1]]
+; CHECK:       check_failed:
+; CHECK-NEXT:    ret i32 -1
+;
 
 entry:
   br label %loop


        


More information about the llvm-commits mailing list