; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
; RUN: opt -disable-output "-passes=print<scalar-evolution>" -scalar-evolution-classify-expressions=0 < %s 2>&1 | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @f_0() {
;
; CHECK-LABEL: 'f_0'
; CHECK-NEXT:  Determining loop execution counts for: @f_0
; CHECK-NEXT:  Loop %for.body: backedge-taken count is i32 5
; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 5
; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is i32 5
; CHECK-NEXT:  Loop %for.body: Trip multiple is 6
;
entry:
  br label %for.body

for.body:
  %i.05 = phi i32 [ 32, %entry ], [ %div4, %for.body ]
  tail call void @dummy()
  %div4 = lshr i32 %i.05, 1
  %cmp = icmp eq i32 %div4, 0
  br i1 %cmp, label %for.cond.cleanup, label %for.body

for.cond.cleanup:
  ret void
}

; Do not compute exhaustive trip count based on FP libcalls, as their exact
; return value may not be specified.
define i64 @test_fp_libcall() {
; CHECK-LABEL: 'test_fp_libcall'
; CHECK-NEXT:  Determining loop execution counts for: @test_fp_libcall
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %fv.next = call double @llvm.sin.f64(double %fv)
  %iv.next = add i64 %iv, 1
  %fcmp = fcmp une double %fv, 0x3FC6BA15EE8460B0
  br i1 %fcmp, label %loop, label %exit

exit:
  ret i64 %iv
}

; Do not compute exhaustive trip count based on FP constant folding resulting
; in NaN values, as we don't specify which NaN exactly is returned.
define i64 @test_nan_sign() {
; CHECK-LABEL: 'test_nan_sign'
; CHECK-NEXT:  Determining loop execution counts for: @test_nan_sign
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ -1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %a = fsub double %fv, 0x7F86C16C16C16C16
  %b = fadd double %a, %a
  %fv.next = fsub double %b, %a
  %iv.next = add i64 %iv, 1
  %fv.bc = bitcast double %fv to i64
  %icmp = icmp slt i64 %fv.bc, 0
  br i1 %icmp, label %loop, label %exit

exit:
  ret i64 %iv
}

; Do not compute exhaustive trip count based on FP constant folding if the
; involved operation has nsz or one of the algebraic FMF flags (reassoc, arcp,
; contract) set. The examples in the following are dummies and don't illustrate
; real cases where FMF transforms could cause issues.

define i64 @test_fp_nsz() {
; CHECK-LABEL: 'test_fp_nsz'
; CHECK-NEXT:  Determining loop execution counts for: @test_fp_nsz
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %fv.next = fadd nsz double %fv, 1.0
  %iv.next = add i64 %iv, 1
  %fcmp = fcmp une double %fv, 100.0
  br i1 %fcmp, label %loop, label %exit

exit:
  ret i64 %iv
}

define i64 @test_fp_reassoc() {
; CHECK-LABEL: 'test_fp_reassoc'
; CHECK-NEXT:  Determining loop execution counts for: @test_fp_reassoc
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %fv.next = fadd reassoc double %fv, 1.0
  %iv.next = add i64 %iv, 1
  %fcmp = fcmp une double %fv, 100.0
  br i1 %fcmp, label %loop, label %exit

exit:
  ret i64 %iv
}

define i64 @test_fp_arcp() {
; CHECK-LABEL: 'test_fp_arcp'
; CHECK-NEXT:  Determining loop execution counts for: @test_fp_arcp
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %fv.next = fadd arcp double %fv, 1.0
  %iv.next = add i64 %iv, 1
  %fcmp = fcmp une double %fv, 100.0
  br i1 %fcmp, label %loop, label %exit

exit:
  ret i64 %iv
}

define i64 @test_fp_contract() {
; CHECK-LABEL: 'test_fp_contract'
; CHECK-NEXT:  Determining loop execution counts for: @test_fp_contract
; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
;
entry:
  br label %loop

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
  call void @use(double %fv)
  %fv.next = fadd contract double %fv, 1.0
  %iv.next = add i64 %iv, 1
  %fcmp = fcmp une double %fv, 100.0
  br i1 %fcmp, label %loop, label %exit

exit:
  ret i64 %iv
}

declare void @dummy()
declare void @use(double %i)
declare double @llvm.sin.f64(double)
