mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-07 19:19:26 +00:00
[SCEV] Be more aggressive around proving no-wrap
... for AddRec's in loops for which SCEV is unable to compute a max tripcount. This is not a problem for "normal" loops[0] that don't have guards or assumes, but helps in cases where we have guards or assumes in the loop that can be used to constrain incoming values over the backedge. This partially fixes PR27691 (we still don't handle the NUW case). [0]: for "normal" loops, in the cases where we'd be able to prove no-wrap via isKnownPredicate, we'd also be able to compute a max tripcount. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269211 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5c4ef289a9
commit
836f35c484
@ -1742,11 +1742,23 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
|
||||
getZeroExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the backedge is guarded by a comparison with the pre-inc value
|
||||
// the addrec is safe. Also, if the entry is guarded by a comparison
|
||||
// with the start value and the backedge is guarded by a comparison
|
||||
// with the post-inc value, the addrec is safe.
|
||||
// Normally, in the cases we can prove no-overflow via a
|
||||
// backedge guarding condition, we can also compute a backedge
|
||||
// taken count for the loop. The exceptions are assumptions and
|
||||
// guards present in the loop -- SCEV is not great at exploiting
|
||||
// these to compute max backedge taken counts, but can still use
|
||||
// these to prove lack of overflow. Use this fact to avoid
|
||||
// doing extra work that may not pay off.
|
||||
|
||||
if (!isa<SCEVCouldNotCompute>(MaxBECount) || HasGuards ||
|
||||
!AC.assumptions().empty()) {
|
||||
// If the backedge is guarded by a comparison with the pre-inc
|
||||
// value the addrec is safe. Also, if the entry is guarded by
|
||||
// a comparison with the start value and the backedge is
|
||||
// guarded by a comparison with the post-inc value, the addrec
|
||||
// is safe.
|
||||
ICmpInst::Predicate Pred;
|
||||
const SCEV *OverflowLimit =
|
||||
getSignedOverflowLimitForStep(Step, &Pred, this);
|
||||
@ -1762,6 +1774,7 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
|
||||
getSignExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
|
||||
}
|
||||
}
|
||||
|
||||
// If Start and Step are constants, check if we can apply this
|
||||
// transformation:
|
||||
// sext{C1,+,C2} --> C1 + sext{0,+,C2} if C1 < C2
|
||||
|
64
test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
Normal file
64
test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
Normal file
@ -0,0 +1,64 @@
|
||||
; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
define void @s_0(i32 %n, i1* %cond) {
|
||||
; CHECK-LABEL: Classifying expressions for: @s_0
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
%iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
|
||||
%iv.inc = add i32 %iv, 1
|
||||
%iv.sext = sext i32 %iv to i64
|
||||
; CHECK: %iv.sext = sext i32 %iv to i64
|
||||
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
|
||||
%cmp = icmp slt i32 %iv, %n
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
%c = load volatile i1, i1* %cond
|
||||
br i1 %c, label %loop, label %leave
|
||||
|
||||
leave:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @s_1(i1* %cond) {
|
||||
; CHECK-LABEL: Classifying expressions for: @s_1
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
%iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
|
||||
%iv.inc = add i32 %iv, 3
|
||||
%iv.sext = sext i32 %iv to i64
|
||||
; CHECK: %iv.sext = sext i32 %iv to i64
|
||||
; CHECK-NEXT: --> {0,+,3}<nuw><nsw><%loop>
|
||||
%cmp = icmp slt i32 %iv, 10000
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
%c = load volatile i1, i1* %cond
|
||||
br i1 %c, label %loop, label %leave
|
||||
|
||||
leave:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @s_2(i1* %cond) {
|
||||
; CHECK-LABEL: Classifying expressions for: @s_2
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
%iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
|
||||
%iv.inc = add i32 %iv, 3
|
||||
%iv.sext = sext i32 %iv to i64
|
||||
%cmp = icmp slt i32 %iv, 10000
|
||||
; CHECK: %iv.sext = sext i32 %iv to i64
|
||||
; CHECK-NEXT: --> {0,+,3}<nuw><nsw><%loop>
|
||||
call void @llvm.assume(i1 %cmp)
|
||||
%c = load volatile i1, i1* %cond
|
||||
br i1 %c, label %loop, label %leave
|
||||
|
||||
leave:
|
||||
ret void
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user