Skip to content

Commit 0b293e8

Browse files
authored
[APInt] Remove multiplicativeInverse with explicit modulus (#87644)
All callers have been changed to use the new simpler overload with an implicit modulus of 2^BitWidth. The old form was never used or tested with non-power-of-two modulus anyway.
1 parent ed41249 commit 0b293e8

File tree

3 files changed

+4
-67
lines changed

3 files changed

+4
-67
lines changed

llvm/include/llvm/ADT/APInt.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,9 +1740,6 @@ class [[nodiscard]] APInt {
17401740
return *this;
17411741
}
17421742

1743-
/// \returns the multiplicative inverse for a given modulo.
1744-
APInt multiplicativeInverse(const APInt &modulo) const;
1745-
17461743
/// \returns the multiplicative inverse of an odd APInt modulo 2^BitWidth.
17471744
APInt multiplicativeInverse() const;
17481745

llvm/lib/Support/APInt.cpp

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,55 +1240,6 @@ APInt APInt::sqrt() const {
12401240
return x_old + 1;
12411241
}
12421242

1243-
/// Computes the multiplicative inverse of this APInt for a given modulo. The
1244-
/// iterative extended Euclidean algorithm is used to solve for this value,
1245-
/// however we simplify it to speed up calculating only the inverse, and take
1246-
/// advantage of div+rem calculations. We also use some tricks to avoid copying
1247-
/// (potentially large) APInts around.
1248-
/// WARNING: a value of '0' may be returned,
1249-
/// signifying that no multiplicative inverse exists!
1250-
APInt APInt::multiplicativeInverse(const APInt& modulo) const {
1251-
assert(ult(modulo) && "This APInt must be smaller than the modulo");
1252-
1253-
// Using the properties listed at the following web page (accessed 06/21/08):
1254-
// http://www.numbertheory.org/php/euclid.html
1255-
// (especially the properties numbered 3, 4 and 9) it can be proved that
1256-
// BitWidth bits suffice for all the computations in the algorithm implemented
1257-
// below. More precisely, this number of bits suffice if the multiplicative
1258-
// inverse exists, but may not suffice for the general extended Euclidean
1259-
// algorithm.
1260-
1261-
APInt r[2] = { modulo, *this };
1262-
APInt t[2] = { APInt(BitWidth, 0), APInt(BitWidth, 1) };
1263-
APInt q(BitWidth, 0);
1264-
1265-
unsigned i;
1266-
for (i = 0; r[i^1] != 0; i ^= 1) {
1267-
// An overview of the math without the confusing bit-flipping:
1268-
// q = r[i-2] / r[i-1]
1269-
// r[i] = r[i-2] % r[i-1]
1270-
// t[i] = t[i-2] - t[i-1] * q
1271-
udivrem(r[i], r[i^1], q, r[i]);
1272-
t[i] -= t[i^1] * q;
1273-
}
1274-
1275-
// If this APInt and the modulo are not coprime, there is no multiplicative
1276-
// inverse, so return 0. We check this by looking at the next-to-last
1277-
// remainder, which is the gcd(*this,modulo) as calculated by the Euclidean
1278-
// algorithm.
1279-
if (r[i] != 1)
1280-
return APInt(BitWidth, 0);
1281-
1282-
// The next-to-last t is the multiplicative inverse. However, we are
1283-
// interested in a positive inverse. Calculate a positive one from a negative
1284-
// one if necessary. A simple addition of the modulo suffices because
1285-
// abs(t[i]) is known to be less than *this/2 (see the link above).
1286-
if (t[i].isNegative())
1287-
t[i] += modulo;
1288-
1289-
return std::move(t[i]);
1290-
}
1291-
12921243
/// \returns the multiplicative inverse of an odd APInt modulo 2^BitWidth.
12931244
APInt APInt::multiplicativeInverse() const {
12941245
assert((*this)[0] &&

llvm/unittests/ADT/APIntTest.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,22 +3249,11 @@ TEST(APIntTest, SolveQuadraticEquationWrap) {
32493249
}
32503250

32513251
TEST(APIntTest, MultiplicativeInverseExaustive) {
3252-
for (unsigned BitWidth = 1; BitWidth <= 16; ++BitWidth) {
3253-
for (unsigned Value = 0; Value < (1u << BitWidth); ++Value) {
3252+
for (unsigned BitWidth = 1; BitWidth <= 8; ++BitWidth) {
3253+
for (unsigned Value = 1; Value < (1u << BitWidth); Value += 2) {
3254+
// Multiplicative inverse exists for all odd numbers.
32543255
APInt V = APInt(BitWidth, Value);
3255-
APInt MulInv =
3256-
V.zext(BitWidth + 1)
3257-
.multiplicativeInverse(APInt::getSignedMinValue(BitWidth + 1))
3258-
.trunc(BitWidth);
3259-
APInt One = V * MulInv;
3260-
if (V[0]) {
3261-
// Multiplicative inverse exists for all odd numbers.
3262-
EXPECT_TRUE(One.isOne());
3263-
EXPECT_TRUE((V * V.multiplicativeInverse()).isOne());
3264-
} else {
3265-
// Multiplicative inverse does not exist for even numbers (and 0).
3266-
EXPECT_TRUE(MulInv.isZero());
3267-
}
3256+
EXPECT_EQ(V * V.multiplicativeInverse(), 1);
32683257
}
32693258
}
32703259
}

0 commit comments

Comments
 (0)