This change moves logic which we'd added specifically for less than tests so that it applies to equalities and greater than tests as well. The basic idea is that if we can show an IV cycles infinitely through the same series on self-wrap, and that the exit condition must be taken to prevent UB, we can conclude that it must be taken before self-wrap and thus infer said flag.
The motivation here is simple loops with unsigned induction variables w/non-one steps and inequality tests. A toy example would be:
for (unsigned i = 0; i != N; i += 2) { body; }
If body contains no side effects, and this is a mustprogress function, we can assume that this must be a finite loop and thus that the exit count is N/2.
Differential Revision: https://reviews.llvm.org/D103991
575 lines
20 KiB
LLVM
575 lines
20 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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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 1
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 1
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 0
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 0
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 0
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start)))))<nuw><nsw> + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start)))))
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start)))))<nuw><nsw> + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start)))))
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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 2
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 2
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 2
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 0
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 0
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 0
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 1
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 1
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 1
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 1
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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(i8* %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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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, i8* %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(i8* %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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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, i8* %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 63
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 63
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 63
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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 0
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 0
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 0
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 0
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 0
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 0
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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: Unpredictable backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated backedge-taken count.
|
|
;
|
|
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 false
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is false
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is false
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 false
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is false
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is false
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 1
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 1
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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 1
|
|
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 1
|
|
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 1
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: 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(i8* %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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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, i8* %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(i8* %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 max backedge-taken count.
|
|
; CHECK-NEXT: Loop %for.body: Unpredictable predicated 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, i8* %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)
|
|
|
|
|