[PATCH] D65845: [SCEV] evaluateAtIteration may produce incorrect result if accuracy of evalutation point is not enough.

Evgeniy via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 27 01:28:08 PDT 2019


ebrevnov updated this revision to Diff 222096.
ebrevnov added a comment.
Herald added a subscriber: hiraditya.

Use alternative approach to ensure enough precision of 'It'


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65845/new/

https://reviews.llvm.org/D65845

Files:
  llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
  llvm/lib/Analysis/ScalarEvolution.cpp
  llvm/lib/Analysis/ScalarEvolutionExpander.cpp


Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -1627,7 +1627,9 @@
     NewS = Ext;
 
   const SCEV *V = cast<SCEVAddRecExpr>(NewS)->evaluateAtIteration(IH, SE);
-  //cerr << "Evaluated: " << *this << "\n     to: " << *V << "\n";
+  assert(!isa<SCEVCouldNotCompute>(V) &&
+         "Expansion of AddRec failed. Can't evaluate SCEV at iteration.");
+  // cerr << "Evaluated: " << *this << "\n     to: " << *V << "\n";
 
   // Truncate the result down to the original type, if needed.
   const SCEV *T = SE.getTruncateOrNoop(V, Ty);
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1205,6 +1205,15 @@
   IntegerType *CalculationTy = IntegerType::get(SE.getContext(),
                                                       CalculationBits);
   const SCEV *Dividend = SE.getTruncateOrZeroExtend(It, CalculationTy);
+
+  // 'It' should have at least 'CalculationBits' precision for the calculation
+  // to be correct. Check that by verifying that downconversion of upconverted
+  // value is not changed. In other words check that X == trunc(zext(X)).
+  if (SE.getTypeSizeInBits(It->getType()) < CalculationBits &&
+      It != SE.getTruncateExpr(Dividend, It->getType()))
+    // Return SCEVCouldNotCompute if 'It' doesn't have enough precision.
+    return SE.getCouldNotCompute();
+
   for (unsigned i = 1; i != K; ++i) {
     const SCEV *S = SE.getMinusSCEV(It, SE.getConstant(It->getType(), i));
     Dividend = SE.getMulExpr(Dividend,
@@ -8320,7 +8329,9 @@
       if (BackedgeTakenCount == getCouldNotCompute()) return AddRec;
 
       // Then, evaluate the AddRec.
-      return AddRec->evaluateAtIteration(BackedgeTakenCount, *this);
+      const SCEV *ValAtIter =
+          AddRec->evaluateAtIteration(BackedgeTakenCount, *this);
+      if (!isa<SCEVCouldNotCompute>(ValAtIter)) return ValAtIter;
     }
 
     return AddRec;
Index: llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
===================================================================
--- llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -343,6 +343,10 @@
 
     /// Return the value of this chain of recurrences at the specified
     /// iteration number.
+    ///
+    /// Note that SCEVCouldNotCompute is returned if evaluation attempt failed.
+    /// For example, if precision of \p It is less than required to perform
+    /// evaluation an instance of SCEVCouldNotCompute is returned.
     const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
 
     /// Return the number of iterations of this loop that produce


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65845.222096.patch
Type: text/x-patch
Size: 2919 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190927/ac0ef1af/attachment.bin>


More information about the llvm-commits mailing list