aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorJay Foad <jay.foad@amd.com>2024-04-04 16:11:06 +0100
committerGitHub <noreply@github.com>2024-04-04 16:11:06 +0100
commit1b761205f2686516cebadbcbc37f798197d9c482 (patch)
tree2aa2a932303b99777e2d369c021ea612b4b43acc /llvm/lib/Support/APInt.cpp
parent51f1cb5355d296ccb7756944d0545d9c96066b78 (diff)
downloadllvm-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.cpp13
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