Compiler projects using 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 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 ], [ %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)