]> granicus.if.org Git - llvm/commitdiff
[SCEV] Simplify SolveLinEquationWithOverflow a bit.
authorEli Friedman <efriedma@codeaurora.org>
Thu, 12 Jan 2017 20:21:00 +0000 (20:21 +0000)
committerEli Friedman <efriedma@codeaurora.org>
Thu, 12 Jan 2017 20:21:00 +0000 (20:21 +0000)
Cleanup in preparation for generalizing it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291808 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ScalarEvolution.cpp

index 791042c61fb7af01aaf5766a6dc51b3be4923d8c..b3905cc01e84b3f9b6a092f1e1bf3fa2d00bc753 100644 (file)
@@ -7032,20 +7032,21 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const APInt &B,
   // 3. Compute I: the multiplicative inverse of (A / D) in arithmetic
   // modulo (N / D).
   //
-  // (N / D) may need BW+1 bits in its representation.  Hence, we'll use this
-  // bit width during computations.
+  // If D == 1, (N / D) == N == 2^BW, so we need one extra bit to represent
+  // (N / D) in general. The inverse itself always fits into BW bits, though,
+  // so we immediately truncate it.
   APInt AD = A.lshr(Mult2).zext(BW + 1);  // AD = A / D
   APInt Mod(BW + 1, 0);
   Mod.setBit(BW - Mult2);  // Mod = N / D
-  APInt I = AD.multiplicativeInverse(Mod);
+  APInt I = AD.multiplicativeInverse(Mod).trunc(BW);
 
   // 4. Compute the minimum unsigned root of the equation:
   // I * (B / D) mod (N / D)
-  APInt Result = (I * B.lshr(Mult2).zext(BW + 1)).urem(Mod);
+  // To simplify the computation, we factor out the divide by D:
+  // (I * B mod N) / D
+  APInt Result = (I * B).lshr(Mult2);
 
-  // The result is guaranteed to be less than 2^BW so we may truncate it to BW
-  // bits.
-  return SE.getConstant(Result.trunc(BW));
+  return SE.getConstant(Result);
 }
 
 /// Find the roots of the quadratic equation for the given quadratic chrec