aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-12-14 09:41:56 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-12-14 09:41:56 +0000
commit7f03920dad606b3ea5ae34f91de383adcdc32c10 (patch)
tree72e8660bb0dc31018fa88e78cee89872bffb7bd2 /llvm/lib/Support/APInt.cpp
parent4e87936d2f28a2703350159c4dcd0a6f8b7a3597 (diff)
downloadllvm-7f03920dad606b3ea5ae34f91de383adcdc32c10.zip
llvm-7f03920dad606b3ea5ae34f91de383adcdc32c10.tar.gz
llvm-7f03920dad606b3ea5ae34f91de383adcdc32c10.tar.bz2
APInt: udivrem should use machine instructions for single-word APInts
This mirrors the behavior of APInt::udiv and APInt::urem. Some architectures, like X86, have a single instruction which can compute both division and remainder. llvm-svn: 224217
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r--llvm/lib/Support/APInt.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index c20eeb2..0ddc2ab 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -1956,6 +1956,18 @@ APInt APInt::srem(const APInt &RHS) const {
void APInt::udivrem(const APInt &LHS, const APInt &RHS,
APInt &Quotient, APInt &Remainder) {
+ assert(LHS.BitWidth == RHS.BitWidth && "Bit widths must be the same");
+
+ // First, deal with the easy case
+ if (LHS.isSingleWord()) {
+ assert(RHS.VAL != 0 && "Divide by zero?");
+ uint64_t QuotVal = LHS.VAL / RHS.VAL;
+ uint64_t RemVal = LHS.VAL % RHS.VAL;
+ Quotient = APInt(LHS.BitWidth, QuotVal);
+ Remainder = APInt(LHS.BitWidth, RemVal);
+ return;
+ }
+
// Get some size facts about the dividend and divisor
unsigned lhsBits = LHS.getActiveBits();
unsigned lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);