diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-12-14 09:41:56 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-12-14 09:41:56 +0000 |
commit | 7f03920dad606b3ea5ae34f91de383adcdc32c10 (patch) | |
tree | 72e8660bb0dc31018fa88e78cee89872bffb7bd2 /llvm/lib/Support/APInt.cpp | |
parent | 4e87936d2f28a2703350159c4dcd0a6f8b7a3597 (diff) | |
download | llvm-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.cpp | 12 |
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); |