diff options
author | Jay Foad <jay.foad@amd.com> | 2024-04-04 16:11:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-04 16:11:06 +0100 |
commit | 1b761205f2686516cebadbcbc37f798197d9c482 (patch) | |
tree | 2aa2a932303b99777e2d369c021ea612b4b43acc /llvm/lib/Support/APInt.cpp | |
parent | 51f1cb5355d296ccb7756944d0545d9c96066b78 (diff) | |
download | llvm-1b761205f2686516cebadbcbc37f798197d9c482.zip llvm-1b761205f2686516cebadbcbc37f798197d9c482.tar.gz llvm-1b761205f2686516cebadbcbc37f798197d9c482.tar.bz2 |
[APInt] Add a simpler overload of multiplicativeInverse (#87610)
The current APInt::multiplicativeInverse takes a modulus which can be
any value, but all in-tree callers use a power of two. Moreover, most
callers want to use two to the power of the width of an existing APInt,
which is awkward because 2^N is not representable as an N-bit APInt.
Add a new overload of multiplicativeInverse which implicitly uses
2^BitWidth as the modulus.
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index c206097..f8f699f 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -1289,6 +1289,19 @@ APInt APInt::multiplicativeInverse(const APInt& modulo) const { return std::move(t[i]); } +/// \returns the multiplicative inverse of an odd APInt modulo 2^BitWidth. +APInt APInt::multiplicativeInverse() const { + assert((*this)[0] && + "multiplicative inverse is only defined for odd numbers!"); + + // Use Newton's method. + APInt Factor = *this; + APInt T; + while (!(T = *this * Factor).isOne()) + Factor *= 2 - T; + return Factor; +} + /// Implementation of Knuth's Algorithm D (Division of nonnegative integers) /// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The /// variables here have the same names as in the algorithm. Comments explain |