llvm.org GIT mirror
[SCEV] Properly solve quadratic equations Differential Revision: https://reviews.llvm.org/D48283 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338758 91177308-0d34-0410-b5e6-96231b3b80d8 Krzysztof Parzyszek 2 years ago
7 changed file(s) with 1097 addition(s) and 117 deletion(s).
 30 30 31 31 template class SmallVectorImpl; 32 32 template class ArrayRef; 33 template class Optional; 33 34 34 35 class APInt; 35 36 2165 2166 /// Return A sign-divided by B, rounded by the given rounding mode. 2166 2167 APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM); 2167 2168 2169 /// Let q(n) = An^2 + Bn + C, and BW = bit width of the value range 2170 /// (e.g. 32 for i32). 2171 /// This function finds the smallest number n, such that 2172 /// (a) n >= 0 and q(n) = 0, or 2173 /// (b) n >= 1 and q(n-1) and q(n), when evaluated in the set of all 2174 /// integers, belong to two different intervals [Rk, Rk+R), 2175 /// where R = 2^BW, and k is an integer. 2176 /// The idea here is to find when q(n) "overflows" 2^BW, while at the 2177 /// same time "allowing" subtraction. In unsigned modulo arithmetic a 2178 /// subtraction (treated as addition of negated numbers) would always 2179 /// count as an overflow, but here we want to allow values to decrease 2180 /// and increase as long as they are within the same interval. 2181 /// Specifically, adding of two negative numbers should not cause an 2182 /// overflow (as long as the magnitude does not exceed the bith width). 2183 /// On the other hand, given a positive number, adding a negative 2184 /// number to it can give a negative result, which would cause the 2185 /// value to go from [-2^BW, 0) to [0, 2^BW). In that sense, zero is 2186 /// treated as a special case of an overflow. 2187 /// 2188 /// This function returns None if after finding k that minimizes the 2189 /// positive solution to q(n) = kR, both solutions are contained between 2190 /// two consecutive integers. 2191 /// 2192 /// There are cases where q(n) > T, and q(n+1) < T (assuming evaluation 2193 /// in arithmetic modulo 2^BW, and treating the values as signed) by the 2194 /// virtue of *signed* overflow. This function will *not* find such an n, 2195 /// however it may find a value of n satisfying the inequalities due to 2196 /// an *unsigned* overflow (if the values are treated as unsigned). 2197 /// To find a solution for a signed overflow, treat it as a problem of 2198 /// finding an unsigned overflow with a range with of BW-1. 2199 /// 2200 /// The returned value may have a different bit width from the input 2201 /// coefficients. 2202 Optional SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, 2203 unsigned RangeWidth); 2168 2204 } // End of APIntOps namespace 2169 2205 2170 2206 // See friend declaration above. This additional declaration is required in