llvm-project/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll
Philip Reames 0d38f21e4a [SCEV] Extend type hint in analysis output to all backedge kinds
This extends the work from 7755c26 to all of the different backend
taken count kinds that we print for the scev analysis printer.  As
before, the goal is to cut down on confusion as i4 -1 is a very
different (unsigned) value from i32 -1.
2024-03-06 13:08:05 -08:00

678 lines
24 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
; RUN: opt < %s -disable-output "-passes=print<scalar-evolution>" -scalar-evolution-classify-expressions=0 2>&1 | FileCheck %s
; A collection of tests which exercise SCEV's ability to compute trip counts
; for negative steps.
; Unsigned Comparisons
; --------------------
; Case where we wrap the induction variable (without generating poison), and
; thus can't currently compute a trip count.
define void @ult_wrap() {
; CHECK-LABEL: 'ult_wrap'
; CHECK-NEXT: Determining loop execution counts for: @ult_wrap
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 254
%cmp = icmp ult i8 %add, 255
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; This IV cycles between 0, and 128, never causing the loop to exit
; (This is well defined.)
define void @ult_infinite() {
; CHECK-LABEL: 'ult_infinite'
; CHECK-NEXT: Determining loop execution counts for: @ult_infinite
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 128
%cmp = icmp ult i8 %add, 255
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Same as ult_infinite, except that the loop is ill defined due to the
; must progress attribute
define void @ult_infinite_ub() mustprogress {
; CHECK-LABEL: 'ult_infinite_ub'
; CHECK-NEXT: Determining loop execution counts for: @ult_infinite_ub
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: Trip multiple is 2
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 128
%cmp = icmp ult i8 %add, 255
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Backedge is not taken
define void @ult_129_not_taken() {
; CHECK-LABEL: 'ult_129_not_taken'
; CHECK-NEXT: Determining loop execution counts for: @ult_129_not_taken
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 129
%cmp = icmp ult i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @ult_129_unknown_start(i8 %start) mustprogress {
; CHECK-LABEL: 'ult_129_unknown_start'
; CHECK-NEXT: Determining loop execution counts for: @ult_129_unknown_start
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ %start, %entry ]
%add = add nuw i8 %i.05, 129
%cmp = icmp ult i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; A case with a non-constant stride where the backedge is not taken
define void @ult_not_taken(i8 %step) {
; CHECK-LABEL: 'ult_not_taken'
; CHECK-NEXT: Determining loop execution counts for: @ult_not_taken
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, %step
%cmp = icmp ult i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; IV does wrap, and thus causes us to branch on poison. This loop is
; ill defined.
define void @ult_ub1() {
; CHECK-LABEL: 'ult_ub1'
; CHECK-NEXT: Determining loop execution counts for: @ult_ub1
; CHECK-NEXT: Loop %for.body: backedge-taken count is i32 2
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 2
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i32 2
; CHECK-NEXT: Loop %for.body: Trip multiple is 3
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 2, %entry ]
%add = add nuw i8 %i.05, 255
%cmp = icmp ult i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; This loop is ill defined because we violate the nsw flag on the first
; iteration.
define void @ult_ub2() {
; CHECK-LABEL: 'ult_ub2'
; CHECK-NEXT: Determining loop execution counts for: @ult_ub2
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nsw nuw i8 %i.05, 129
%cmp = icmp ult i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Large stride, poison produced for %add on second iteration, but not
; branched on.
define void @ult_129_preinc() {
; CHECK-LABEL: 'ult_129_preinc'
; CHECK-NEXT: Determining loop execution counts for: @ult_129_preinc
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: Trip multiple is 2
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nuw i8 %i.05, 129
%cmp = icmp ult i8 %i.05, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @ult_preinc(i8 %step) {
; CHECK-LABEL: 'ult_preinc'
; CHECK-NEXT: Determining loop execution counts for: @ult_preinc
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: Trip multiple is 2
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nuw i8 %i.05, 129
%cmp = icmp ult i8 %i.05, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @ult_129_varying_rhs(ptr %n_p) {
; CHECK-LABEL: 'ult_129_varying_rhs'
; CHECK-NEXT: Determining loop execution counts for: @ult_129_varying_rhs
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nuw i8 %i.05, 129
%n = load i8, ptr %n_p
%cmp = icmp ult i8 %add, %n
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @ult_symbolic_varying_rhs(ptr %n_p, i8 %step) {
; CHECK-LABEL: 'ult_symbolic_varying_rhs'
; CHECK-NEXT: Determining loop execution counts for: @ult_symbolic_varying_rhs
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nuw i8 %i.05, %step
%n = load i8, ptr %n_p
%cmp = icmp ult i8 %add, %n
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Signed Comparisons
; ------------------
; Case where we wrap the induction variable (without generating poison), and
; thus can't currently compute a trip count.
define void @slt_wrap() {
; CHECK-LABEL: 'slt_wrap'
; CHECK-NEXT: Determining loop execution counts for: @slt_wrap
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 63
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 63
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 63
; CHECK-NEXT: Loop %for.body: Trip multiple is 64
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 255, %entry ]
%add = add i8 %i.05, 254
%cmp = icmp slt i8 %add, 127
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; This IV cycles between 0, and int_min (128), never causing the loop to exit
; (This is well defined.)
define void @slt_infinite() {
; CHECK-LABEL: 'slt_infinite'
; CHECK-NEXT: Determining loop execution counts for: @slt_infinite
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 128
%cmp = icmp slt i8 %add, 127
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Same as slt_infinite, except that the loop is ill defined due to the
; must progress attribute
define void @slt_infinite_ub() mustprogress {
; CHECK-LABEL: 'slt_infinite_ub'
; CHECK-NEXT: Determining loop execution counts for: @slt_infinite_ub
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add i8 %i.05, 128
%cmp = icmp slt i8 %add, 127
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Backedge is not taken
define void @slt_129_not_taken() {
; CHECK-LABEL: 'slt_129_not_taken'
; CHECK-NEXT: Determining loop execution counts for: @slt_129_not_taken
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 0
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add i8 %i.05, 129
%cmp = icmp slt i8 %add, 0
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; A case with a non-constant stride where the backedge is not taken
define void @slt_not_taken(i8 %step) {
; CHECK-LABEL: 'slt_not_taken'
; CHECK-NEXT: Determining loop execution counts for: @slt_not_taken
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add i8 %i.05, %step
%cmp = icmp slt i8 %add, 0
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @slt_129_unknown_start(i8 %start) mustprogress {
; CHECK-LABEL: 'slt_129_unknown_start'
; CHECK-NEXT: Determining loop execution counts for: @slt_129_unknown_start
; CHECK-NEXT: Loop %for.body: backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (0 smax (-127 + %start)<nsw>))))<nuw><nsw> + (-1 * %start) + (0 smax (-127 + %start)<nsw>)) /u -127) + (1 umin (127 + (-1 * %start) + (0 smax (-127 + %start)<nsw>))))
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 2
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (0 smax (-127 + %start)<nsw>))))<nuw><nsw> + (-1 * %start) + (0 smax (-127 + %start)<nsw>)) /u -127) + (1 umin (127 + (-1 * %start) + (0 smax (-127 + %start)<nsw>))))
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ %start, %entry ]
%add = add nsw i8 %i.05, 129
%cmp = icmp slt i8 %add, 0
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; IV does wrap, and thus causes us to branch on poison. This loop is
; ill defined.
define void @slt_ub1() {
; CHECK-LABEL: 'slt_ub1'
; CHECK-NEXT: Determining loop execution counts for: @slt_ub1
; CHECK-NEXT: Loop %for.body: backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 2, %entry ]
%add = add nuw i8 %i.05, 255
%cmp = icmp slt i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; This loop is ill defined because we violate the nsw flag on the first
; iteration.
define void @slt_ub2() {
; CHECK-LABEL: 'slt_ub2'
; CHECK-NEXT: Determining loop execution counts for: @slt_ub2
; CHECK-NEXT: Loop %for.body: backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i1 false
; CHECK-NEXT: Loop %for.body: Trip multiple is 1
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ 0, %entry ]
%add = add nsw nuw i8 %i.05, 129
%cmp = icmp slt i8 %add, 128
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
; Large stride, poison produced for %add on second iteration, but not
; branched on.
define void @slt_129_preinc() {
; CHECK-LABEL: 'slt_129_preinc'
; CHECK-NEXT: Determining loop execution counts for: @slt_129_preinc
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: Trip multiple is 2
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add nuw i8 %i.05, 129
%cmp = icmp slt i8 %i.05, 0
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @slt_preinc(i8 %step) {
; CHECK-LABEL: 'slt_preinc'
; CHECK-NEXT: Determining loop execution counts for: @slt_preinc
; CHECK-NEXT: Loop %for.body: backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i8 1
; CHECK-NEXT: Loop %for.body: Trip multiple is 2
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add nuw i8 %i.05, 129
%cmp = icmp slt i8 %i.05, 0
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @slt_129_varying_rhs(ptr %n_p) {
; CHECK-LABEL: 'slt_129_varying_rhs'
; CHECK-NEXT: Determining loop execution counts for: @slt_129_varying_rhs
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add nsw i8 %i.05, 129
%n = load i8, ptr %n_p
%cmp = icmp slt i8 %add, %n
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
define void @slt_symbolic_varying_rhs(ptr %n_p, i8 %step) {
; CHECK-LABEL: 'slt_symbolic_varying_rhs'
; CHECK-NEXT: Determining loop execution counts for: @slt_symbolic_varying_rhs
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
;
entry:
%assume = icmp ult i8 128, %step
call void @llvm.assume(i1 %assume)
br label %for.body
for.body: ; preds = %entry, %for.body
%i.05 = phi i8 [ %add, %for.body ], [ -128, %entry ]
%add = add nsw i8 %i.05, %step
%n = load i8, ptr %n_p
%cmp = icmp slt i8 %add, %n
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
ret void
}
declare void @llvm.assume(i1)
; Test case for PR57818.
define void @step_is_neg_addrec_slt_8(i64 %n) {
; CHECK-LABEL: 'step_is_neg_addrec_slt_8'
; CHECK-NEXT: Determining loop execution counts for: @step_is_neg_addrec_slt_8
; CHECK-NEXT: Loop %inner: backedge-taken count is (7 /u {0,+,-1}<%outer.header>)
; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i32 8
; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is (7 /u {0,+,-1}<%outer.header>)
; CHECK-NEXT: Loop %inner: Trip multiple is 1
; CHECK-NEXT: Loop %outer.header: backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: constant max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: symbolic max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: Trip multiple is 1
;
entry:
br label %outer.header
outer.header:
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
%ec.1 = icmp eq i64 %outer.iv, 100
br i1 %ec.1, label %inner.ph, label %exit
inner.ph:
%outer.trunc = trunc i64 %outer.iv to i32
br label %inner
inner:
%inner.iv = phi i32 [ 0, %inner.ph ], [ %inner.iv.next, %inner ]
%inner.iv.next = add nsw i32 %inner.iv, %outer.trunc
%inner.c = icmp slt i32 %inner.iv.next, 8
br i1 %inner.c, label %inner, label %outer.latch, !llvm.loop !0
outer.latch:
%outer.iv.next = add nsw i64 %outer.iv, -1
br label %outer.header
exit:
ret void
}
define void @step_is_neg_addrec_slt_var(i32 %n) {
; CHECK-LABEL: 'step_is_neg_addrec_slt_var'
; CHECK-NEXT: Determining loop execution counts for: @step_is_neg_addrec_slt_var
; CHECK-NEXT: Loop %inner: backedge-taken count is ({0,+,1}<nuw><nsw><%outer.header> + ({0,+,-1}<nsw><%outer.header> smax %n))
; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i32 2147483647
; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is ({0,+,1}<nuw><nsw><%outer.header> + ({0,+,-1}<nsw><%outer.header> smax %n))
; CHECK-NEXT: Loop %inner: Trip multiple is 1
; CHECK-NEXT: Loop %outer.header: backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: constant max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: symbolic max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: Trip multiple is 1
;
entry:
br label %outer.header
outer.header:
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
%ec.1 = icmp eq i64 %outer.iv, 100
br i1 %ec.1, label %inner.ph, label %exit
inner.ph:
%outer.trunc = trunc i64 %outer.iv to i32
br label %inner
inner:
%inner.iv = phi i32 [ 0, %inner.ph ], [ %inner.iv.next, %inner ]
%inner.iv.next = add nsw i32 %inner.iv, %outer.trunc
%inner.c = icmp slt i32 %inner.iv.next, %n
br i1 %inner.c, label %inner, label %outer.latch, !llvm.loop !0
outer.latch:
%outer.iv.next = add nsw i64 %outer.iv, -1
br label %outer.header
exit:
ret void
}
define void @step_is_neg_addrec_unknown_start(i32 %n) {
; CHECK-LABEL: 'step_is_neg_addrec_unknown_start'
; CHECK-NEXT: Determining loop execution counts for: @step_is_neg_addrec_unknown_start
; CHECK-NEXT: Loop %inner: backedge-taken count is ({(-1 * %n),+,1}<nw><%outer.header> + (8 smax {%n,+,-1}<nsw><%outer.header>))
; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i32 -2147483640
; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is ({(-1 * %n),+,1}<nw><%outer.header> + (8 smax {%n,+,-1}<nsw><%outer.header>))
; CHECK-NEXT: Loop %inner: Trip multiple is 1
; CHECK-NEXT: Loop %outer.header: backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: constant max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: symbolic max backedge-taken count is i64 0
; CHECK-NEXT: Loop %outer.header: Trip multiple is 1
;
entry:
br label %outer.header
outer.header:
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
%ec.1 = icmp eq i64 %outer.iv, 100
br i1 %ec.1, label %inner.ph, label %exit
inner.ph:
%outer.trunc = trunc i64 %outer.iv to i32
br label %inner
inner:
%inner.iv = phi i32 [ %n, %inner.ph ], [ %inner.iv.next, %inner ]
%inner.iv.next = add nsw i32 %inner.iv, %outer.trunc
%inner.c = icmp slt i32 %inner.iv.next, 8
br i1 %inner.c, label %inner, label %outer.latch, !llvm.loop !0
outer.latch:
%outer.iv.next = add nsw i64 %outer.iv, -1
br label %outer.header
exit:
ret void
}
!0 = distinct !{!0, !1}
!1 = !{!"llvm.loop.mustprogress"}