[llvm] r337478 - [APInt] Keep the original bit width in quotient and remainder

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 19 11:07:56 PDT 2018


Author: kparzysz
Date: Thu Jul 19 11:07:56 2018
New Revision: 337478

URL: http://llvm.org/viewvc/llvm-project?rev=337478&view=rev
Log:
[APInt] Keep the original bit width in quotient and remainder

Some trivial cases in udivrem were handled by directly assigning 0 or 1
to APInt objects. This would set the bit width to 1, instead of the bit
width of the inputs. A potentially undesirable side effect of that is
that with the bit width of 1, 1 equals -1.

Differential Revision: https://reviews.llvm.org/D49554

Modified:
    llvm/trunk/lib/Support/APInt.cpp
    llvm/trunk/unittests/ADT/APIntTest.cpp

Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=337478&r1=337477&r2=337478&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Thu Jul 19 11:07:56 2018
@@ -1735,25 +1735,25 @@ void APInt::udivrem(const APInt &LHS, co
 
   // Check the degenerate cases
   if (lhsWords == 0) {
-    Quotient = 0;                // 0 / Y ===> 0
-    Remainder = 0;               // 0 % Y ===> 0
+    Quotient = APInt(BitWidth, 0);    // 0 / Y ===> 0
+    Remainder = APInt(BitWidth, 0);   // 0 % Y ===> 0
     return;
   }
 
   if (rhsBits == 1) {
-    Quotient = LHS;             // X / 1 ===> X
-    Remainder = 0;              // X % 1 ===> 0
+    Quotient = LHS;                   // X / 1 ===> X
+    Remainder = APInt(BitWidth, 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
+    Remainder = LHS;                  // X % Y ===> X, iff X < Y
+    Quotient = APInt(BitWidth, 0);    // X / Y ===> 0, iff X < Y
     return;
   }
 
   if (LHS == RHS) {
-    Quotient  = 1;              // X / X ===> 1
-    Remainder = 0;              // X % X ===> 0;
+    Quotient  = APInt(BitWidth, 1);   // X / X ===> 1
+    Remainder = APInt(BitWidth, 0);   // X % X ===> 0;
     return;
   }
 
@@ -1801,25 +1801,26 @@ void APInt::udivrem(const APInt &LHS, ui
 
   // Check the degenerate cases
   if (lhsWords == 0) {
-    Quotient = 0;                // 0 / Y ===> 0
-    Remainder = 0;               // 0 % Y ===> 0
+    Quotient = APInt(BitWidth, 0);    // 0 / Y ===> 0
+    Remainder = 0;                    // 0 % Y ===> 0
     return;
   }
 
   if (RHS == 1) {
-    Quotient = LHS;             // X / 1 ===> X
-    Remainder = 0;              // X % 1 ===> 0
+    Quotient = LHS;                   // X / 1 ===> X
+    Remainder = 0;                    // X % 1 ===> 0
+    return;
   }
 
   if (LHS.ult(RHS)) {
-    Remainder = LHS.getZExtValue(); // X % Y ===> X, iff X < Y
-    Quotient = 0;                   // X / Y ===> 0, iff X < Y
+    Remainder = LHS.getZExtValue();   // X % Y ===> X, iff X < Y
+    Quotient = APInt(BitWidth, 0);    // X / Y ===> 0, iff X < Y
     return;
   }
 
   if (LHS == RHS) {
-    Quotient  = 1;              // X / X ===> 1
-    Remainder = 0;              // X % X ===> 0;
+    Quotient  = APInt(BitWidth, 1);   // X / X ===> 1
+    Remainder = 0;                    // X % X ===> 0;
     return;
   }
 

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=337478&r1=337477&r2=337478&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Thu Jul 19 11:07:56 2018
@@ -1060,6 +1060,38 @@ TEST(APIntTest, divremuint) {
           APInt{1024, 1});
 }
 
+TEST(APIntTest, divrem_simple) {
+  // Test simple cases.
+  APInt A(65, 2), B(65, 2);
+  APInt Q, R;
+
+  // X / X
+  APInt::sdivrem(A, B, Q, R);
+  EXPECT_EQ(Q, APInt(65, 1));
+  EXPECT_EQ(R, APInt(65, 0));
+  APInt::udivrem(A, B, Q, R);
+  EXPECT_EQ(Q, APInt(65, 1));
+  EXPECT_EQ(R, APInt(65, 0));
+
+  // 0 / X
+  APInt O(65, 0);
+  APInt::sdivrem(O, B, Q, R);
+  EXPECT_EQ(Q, APInt(65, 0));
+  EXPECT_EQ(R, APInt(65, 0));
+  APInt::udivrem(O, B, Q, R);
+  EXPECT_EQ(Q, APInt(65, 0));
+  EXPECT_EQ(R, APInt(65, 0));
+
+  // X / 1
+  APInt I(65, 1);
+  APInt::sdivrem(A, I, Q, R);
+  EXPECT_EQ(Q, A);
+  EXPECT_EQ(R, APInt(65, 0));
+  APInt::udivrem(A, I, Q, R);
+  EXPECT_EQ(Q, A);
+  EXPECT_EQ(R, APInt(65, 0));
+}
+
 TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, 0), APInt(32,   "0", 2));
   EXPECT_EQ(APInt(32, 1), APInt(32,   "1", 2));




More information about the llvm-commits mailing list