From e96d8395f457f3b8ac0266489f199b32db24c63e Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 12 May 2017 21:45:50 +0000 Subject: [PATCH] [APInt] Add early outs for a division by 1 to udiv/urem/udivrem We already counted the number of bits in the RHS so its pretty cheap to just check if the RHS is 1. Differential Revision: https://reviews.llvm.org/D33154 llvm-svn: 302953 --- lib/Support/APInt.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 25d39771a08..369ded7cf14 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -1565,14 +1565,18 @@ APInt APInt::udiv(const APInt& RHS) const { } // Get some facts about the LHS and RHS number of bits and words - unsigned rhsWords = getNumWords(RHS.getActiveBits()); - assert(rhsWords && "Divided by zero???"); unsigned lhsWords = getNumWords(getActiveBits()); + unsigned rhsBits = RHS.getActiveBits(); + unsigned rhsWords = getNumWords(rhsBits); + assert(rhsWords && "Divided by zero???"); // Deal with some degenerate cases if (!lhsWords) // 0 / X ===> 0 return APInt(BitWidth, 0); + if (rhsBits == 1) + // X / 1 ===> X + return *this; if (lhsWords < rhsWords || this->ult(RHS)) // X / Y ===> 0, iff X < Y return APInt(BitWidth, 0); @@ -1611,13 +1615,17 @@ APInt APInt::urem(const APInt& RHS) const { unsigned lhsWords = getNumWords(getActiveBits()); // Get some facts about the RHS - unsigned rhsWords = getNumWords(RHS.getActiveBits()); + unsigned rhsBits = RHS.getActiveBits(); + unsigned rhsWords = getNumWords(rhsBits); assert(rhsWords && "Performing remainder operation by zero ???"); // Check the degenerate cases if (lhsWords == 0) // 0 % Y ===> 0 return APInt(BitWidth, 0); + if (rhsBits == 1) + // X % 1 ===> 0 + return APInt(BitWidth, 0); if (lhsWords < rhsWords || this->ult(RHS)) // X % Y ===> X, iff X < Y return *this; @@ -1662,7 +1670,8 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS, // Get some size facts about the dividend and divisor unsigned lhsWords = getNumWords(LHS.getActiveBits()); - unsigned rhsWords = getNumWords(RHS.getActiveBits()); + unsigned rhsBits = RHS.getActiveBits(); + unsigned rhsWords = getNumWords(rhsBits); assert(rhsWords && "Performing divrem operation by zero ???"); // Check the degenerate cases @@ -1672,6 +1681,11 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS, return; } + if (rhsBits == 1) { + Quotient = LHS; // X / 1 ===> X + Remainder = 0; // X % 1 ===> 0 + } + if (lhsWords < rhsWords || LHS.ult(RHS)) { Remainder = LHS; // X % Y ===> X, iff X < Y Quotient = 0; // X / Y ===> 0, iff X < Y