[llvm] r269790 - [SCEV] Be more aggressive in proving NUW
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Tue May 17 10:51:14 PDT 2016
Author: sanjoy
Date: Tue May 17 12:51:14 2016
New Revision: 269790
URL: http://llvm.org/viewvc/llvm-project?rev=269790&view=rev
Log:
[SCEV] Be more aggressive in proving NUW
... for AddRec's in loops for which SCEV is unable to compute a max
tripcount. This is the NUW variant of r269211 and fixes PR27691.
(Note: PR27691 is not a correct or stability bug, it was created to
track a pending task).
Modified:
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=269790&r1=269789&r2=269790&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue May 17 12:51:14 2016
@@ -1521,11 +1521,22 @@ const SCEV *ScalarEvolution::getZeroExte
getSignExtendExpr(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.
if (isKnownPositive(Step)) {
const SCEV *N = getConstant(APInt::getMinValue(BitWidth) -
getUnsignedRange(Step).getUnsignedMax());
@@ -1533,7 +1544,8 @@ const SCEV *ScalarEvolution::getZeroExte
(isLoopEntryGuardedByCond(L, ICmpInst::ICMP_ULT, Start, N) &&
isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT,
AR->getPostIncExpr(*this), N))) {
- // Cache knowledge of AR NUW, which is propagated to this AddRec.
+ // Cache knowledge of AR NUW, which is propagated to this
+ // AddRec.
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNUW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
@@ -1547,8 +1559,9 @@ const SCEV *ScalarEvolution::getZeroExte
(isLoopEntryGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) &&
isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT,
AR->getPostIncExpr(*this), N))) {
- // Cache knowledge of AR NW, which is propagated to this AddRec.
- // Negative step causes unsigned wrap, but it still can't self-wrap.
+ // Cache knowledge of AR NW, which is propagated to this
+ // AddRec. Negative step causes unsigned wrap, but it
+ // still can't self-wrap.
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
Modified: llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll?rev=269790&r1=269789&r2=269790&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll Tue May 17 12:51:14 2016
@@ -62,3 +62,63 @@ loop:
leave:
ret void
}
+
+define void @u_0(i32 %n, i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_0
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+ %iv.zext = zext i32 %iv to i64
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,1}<nuw><%loop>
+ %cmp = icmp ult 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 @u_1(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_1
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 3
+ %iv.zext = zext i32 %iv to i64
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,3}<nuw><%loop>
+ %cmp = icmp ult 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 @u_2(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_2
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 30000, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, -2
+ %iv.zext = zext i32 %iv to i64
+ %cmp = icmp ugt i32 %iv.inc, -10000
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {30000,+,-2}<nw><%loop>
+ call void @llvm.assume(i1 %cmp)
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
More information about the llvm-commits
mailing list