[PATCH] D48283: [SCEV] Properly solve quadratic equations

Krzysztof Parzyszek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 26 10:30:13 PDT 2018


kparzysz marked 2 inline comments as done.
kparzysz added inline comments.


================
Comment at: lib/Analysis/ScalarEvolution.cpp:8715
+    Optional<APInt> Min = MinOptional(SO, UO);
+    if (Min.hasValue() && LeavesRange(*Min))
+      return { Min, true };
----------------
efriedma wrote:
> Min.hasValue() is always true here.
So is Max.hasValue().


================
Comment at: lib/Analysis/ScalarEvolution.cpp:8719
+    if (Max.hasValue() && LeavesRange(*Max))
+      return { Max, true };
+
----------------
efriedma wrote:
> How do you ensure the correct solution isn't some value between Min and Max?
> 
> Similarly, in the case where SolveForBoundary returns None, how can you be sure the correct solution isn't some value between the Max for this boundary and the Min of the other boundary?
> How do you ensure the correct solution isn't some value between Min and Max?

Assuming that Min and Max are different values, one of them is when the first signed overflow happens, the other is when the first unsigned overflow happens. Crossing the range boundary is only possible via an overflow (treating 0 as a special case of it, modeling overflow as crossing //k*2^W// for some //k//).

The interesting case here is when Min was eliminated as an invalid solution, but Max was not. The argument is that if there was another overflow between Min and Max, it would also have been eliminated if it was considered.

For a given boundary, it is possible to have two overflows of the same type (signed/unsigned) without having the other type in between: this can happen when the vertex of the parabola is between the iterations corresponding to the overflows.  This is only possible when the two overflows cross //k*2^W// for the same //k//.  In such case, if the second one left the range (and was the first one to do so), the first overflow would have to enter the range, which would mean that either we had left the range before or that we started outside of it.  Both of these cases are contradictions.

> Similarly, in the case where SolveForBoundary returns None, how can you be sure the correct solution isn't some value between the Max for this boundary and the Min of the other boundary?

Assume that we had such Max_A and Min_B corresponding to range boundaries A and B and such that Max_A < Min_B.  If there was a solution between Max_A and Min_B, it would have to be caused by an overflow corresponding to either A or B. It cannot correspond to B, since Min_B is the first occurrence of such an overflow. If it corresponded to A, it would have to be either a signed or an unsigned overflow that is larger than both eliminated overflows for A. But between the eliminated overflows and this overflow, the values would cover the entire value space, thus crossing the other boundary, which is a contradiction.


Repository:
  rL LLVM

https://reviews.llvm.org/D48283





More information about the llvm-commits mailing list