mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
b55d0a6618
In this method, we invoke `SimplifyICmpOperands` which takes the `Cond` predicate by reference and may change it along with `LHS` and `RHS` SCEVs. But then we invoke `computeShiftCompareExitLimit` with Values from which the SCEVs have been derived, these Values have not been modified while `Cond` could be. One of possible outcomes of this is that we may falsely prove that an infinite loop ends within some finite number of iterations. In this patch, we save the original `Cond` and pass it along with original operands. This logic may be removed in future once `computeShiftCompareExitLimit` works with SCEVs instead of value operands. Reviewed By: sanjoy Differential Revision: https://reviews.llvm.org/D40953 llvm-svn: 320142
184 lines
4.2 KiB
LLVM
184 lines
4.2 KiB
LLVM
; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
|
|
|
|
define void @test0(i32 %init) {
|
|
; CHECK-LABEL: Classifying expressions for: @test0
|
|
; CHECK: Loop %loop: max backedge-taken count is 32
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = lshr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test1(i32 %init) {
|
|
; CHECK-LABEL: Classifying expressions for: @test1
|
|
; CHECK: Loop %loop: max backedge-taken count is 32
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = shl i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test2(i32 %init) {
|
|
; CHECK-LABEL: Determining loop execution counts for: @test2
|
|
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
|
|
|
|
; Unpredictable because %iv could "stabilize" to either -1 or 0,
|
|
; depending on %init.
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test3(i32* %init.ptr) {
|
|
; CHECK-LABEL: Determining loop execution counts for: @test3
|
|
; CHECK: Loop %loop: max backedge-taken count is 32
|
|
entry:
|
|
%init = load i32, i32* %init.ptr, !range !0
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test4(i32* %init.ptr) {
|
|
; CHECK-LABEL: Classifying expressions for: @test4
|
|
; CHECK-LABEL: Loop %loop: max backedge-taken count is 32
|
|
entry:
|
|
%init = load i32, i32* %init.ptr, !range !1
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, -1
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test5(i32* %init.ptr) {
|
|
; CHECK-LABEL: Determining loop execution counts for: @test5
|
|
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
|
|
|
|
; %iv will "stabilize" to -1, so this is an infinite loop
|
|
entry:
|
|
%init = load i32, i32* %init.ptr, !range !1
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test6(i32 %init, i32 %shift.amt) {
|
|
; CHECK-LABEL: Determining loop execution counts for: @test6
|
|
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
|
|
|
|
; Potentially infinite loop, since %shift.amt could be 0
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = lshr i32 %iv, %shift.amt
|
|
%exit.cond = icmp eq i32 %iv, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test7(i32 %init) {
|
|
; CHECK-LABEL: Classifying expressions for: @test7
|
|
; CHECK: Loop %loop: max backedge-taken count is 32
|
|
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = lshr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv.shift, 0
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test8(i32 %init) {
|
|
; CHECK-LABEL: Classifying expressions for: @test8
|
|
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
|
|
|
|
; In this test case, %iv.test stabilizes to 127, not -1, so the loop
|
|
; is infinite.
|
|
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ %init, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%iv.test = lshr i32 %iv, 1
|
|
%exit.cond = icmp eq i32 %iv.test, -1
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
|
|
leave:
|
|
ret void
|
|
}
|
|
|
|
define void @test9() {
|
|
; CHECK-LABEL: Determining loop execution counts for: @test9
|
|
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
|
|
|
|
; This is an infinite loop, make sure that it recognized as such.
|
|
|
|
entry:
|
|
br label %loop
|
|
|
|
leave:
|
|
ret void
|
|
|
|
loop:
|
|
%iv = phi i32 [ -20, %entry ], [ %iv.shift, %loop ]
|
|
%iv.shift = ashr i32 %iv, 1
|
|
%exit.cond = icmp sgt i32 %iv, -1
|
|
br i1 %exit.cond, label %leave, label %loop
|
|
}
|
|
|
|
!0 = !{i32 0, i32 50000}
|
|
!1 = !{i32 -5000, i32 -1}
|