llvm.org GIT mirror llvm / 300c6c5
First step to fix PR2088. Implement routine to compute the multiplicative inverse of a given number. Modify udivrem to allow input and output pairs of arguments to overlap. Patch is based on the work by Chandler Carruth. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52638 91177308-0d34-0410-b5e6-96231b3b80d8 Wojciech Matyjewicz 11 years ago
2 changed file(s) with 57 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
667667 return this->urem(RHS);
668668 }
669669
670 /// Sometimes it is convenient to divide two APInt values and obtain both
671 /// the quotient and remainder. This function does both operations in the
672 /// same computation making it a little more efficient.
670 /// Sometimes it is convenient to divide two APInt values and obtain both the
671 /// quotient and remainder. This function does both operations in the same
672 /// computation making it a little more efficient. The pair of input arguments
673 /// may overlap with the pair of output arguments. It is safe to call
674 /// udivrem(X, Y, X, Y), for example.
673675 /// @brief Dual division/remainder interface.
674676 static void udivrem(const APInt &LHS, const APInt &RHS,
675677 APInt &Quotient, APInt &Remainder);
11061108 return *this;
11071109 }
11081110
1111 /// @returns the multiplicative inverse for a given modulo.
1112 APInt multiplicativeInverse(const APInt& modulo) const;
1113
11091114 /// @}
11101115 /// @name Building-block Operations for APInt and APFloat
11111116 /// @{
13001305 }
13011306
13021307 /// GreatestCommonDivisor - This function returns the greatest common
1303 /// divisor of the two APInt values using Enclid's algorithm.
1308 /// divisor of the two APInt values using Euclid's algorithm.
13041309 /// @returns the greatest common divisor of Val1 and Val2
13051310 /// @brief Compute GCD of two APInt values.
13061311 APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2);
14231423 } else
14241424 assert(0 && "Error in APInt::sqrt computation");
14251425 return x_old + 1;
1426 }
1427
1428 /// Computes the multiplicative inverse of this APInt for a given modulo. The
1429 /// iterative extended Euclidean algorithm is used to solve for this value,
1430 /// however we simplify it to speed up calculating only the inverse, and take
1431 /// advantage of div+rem calculations. We also use some tricks to avoid copying
1432 /// (potentially large) APInts around.
1433 APInt APInt::multiplicativeInverse(const APInt& modulo) const {
1434 assert(ult(modulo) && "This APInt must be smaller than the modulo");
1435
1436 // Using the properties listed at the following web page (accessed 06/21/08):
1437 // http://www.numbertheory.org/php/euclid.html
1438 // (especially the properties numbered 3, 4 and 9) it can be proved that
1439 // BitWidth bits suffice for all the computations in the algorithm implemented
1440 // below. More precisely, this number of bits suffice if the multiplicative
1441 // inverse exists, but may not suffice for the general extended Euclidean
1442 // algorithm.
1443
1444 APInt r[2] = { modulo, *this };
1445 APInt t[2] = { APInt(BitWidth, 0), APInt(BitWidth, 1) };
1446 APInt q(BitWidth, 0);
1447
1448 unsigned i;
1449 for (i = 0; r[i^1] != 0; i ^= 1) {
1450 // An overview of the math without the confusing bit-flipping:
1451 // q = r[i-2] / r[i-1]
1452 // r[i] = r[i-2] % r[i-1]
1453 // t[i] = t[i-2] - t[i-1] * q
1454 udivrem(r[i], r[i^1], q, r[i]);
1455 t[i] -= t[i^1] * q;
1456 }
1457
1458 // If this APInt and the modulo are not coprime, there is no multiplicative
1459 // inverse, so return 0. We check this by looking at the next-to-last
1460 // remainder, which is the gcd(*this,modulo) as calculated by the Euclidean
1461 // algorithm.
1462 if (r[i] != 1)
1463 return APInt(BitWidth, 0);
1464
1465 // The next-to-last t is the multiplicative inverse. However, we are
1466 // interested in a positive inverse. Calcuate a positive one from a negative
1467 // one if necessary. A simple addition of the modulo suffices because
1468 // abs(t[i]) is known to less than *this/2 (see the link above).
1469 return t[i].isNegative() ? t[i] + modulo : t[i];
14261470 }
14271471
14281472 /// Implementation of Knuth's Algorithm D (Division of nonnegative integers)
18811925
18821926 if (lhsWords == 1 && rhsWords == 1) {
18831927 // There is only one word to consider so use the native versions.
1884 if (LHS.isSingleWord()) {
1885 Quotient = APInt(LHS.getBitWidth(), LHS.VAL / RHS.VAL);
1886 Remainder = APInt(LHS.getBitWidth(), LHS.VAL % RHS.VAL);
1887 } else {
1888 Quotient = APInt(LHS.getBitWidth(), LHS.pVal[0] / RHS.pVal[0]);
1889 Remainder = APInt(LHS.getBitWidth(), LHS.pVal[0] % RHS.pVal[0]);
1890 }
1928 uint64_t lhsValue = LHS.isSingleWord() ? LHS.VAL : LHS.pVal[0];
1929 uint64_t rhsValue = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
1930 Quotient = APInt(LHS.getBitWidth(), lhsValue / rhsValue);
1931 Remainder = APInt(LHS.getBitWidth(), lhsValue % rhsValue);
18911932 return;
18921933 }
18931934