| ; 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) |