[llvm] r269211 - [SCEV] Be more aggressive around proving no-wrap

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 10:41:26 PDT 2016


Author: sanjoy
Date: Wed May 11 12:41:26 2016
New Revision: 269211

URL: http://llvm.org/viewvc/llvm-project?rev=269211&view=rev
Log:
[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.

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=269211&r1=269210&r2=269211&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed May 11 12:41:26 2016
@@ -1742,11 +1742,23 @@ const SCEV *ScalarEvolution::getSignExte
                 getZeroExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
           }
         }
+      }
+
+      // 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 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 (!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::getSignExte
               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

Added: 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=269211&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll Wed May 11 12:41:26 2016
@@ -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
+}




More information about the llvm-commits mailing list