APInt: udivrem should use machine instructions for single-word APInts
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 14 Dec 2014 09:41:56 +0000 (09:41 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 14 Dec 2014 09:41:56 +0000 (09:41 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224217 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/APInt.cpp

index c20eeb269484e7afe2f2eef807258ba097f061ae..0ddc2ab8af30279e9951e0a27b7fd0eeda93869b 100644 (file)
@@ -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);