[llvm-commits] [llvm] r141441 - in /llvm/trunk: lib/Support/APFloat.cpp lib/Support/APInt.cpp unittests/ADT/APIntTest.cpp

Eli Friedman eli.friedman at gmail.com
Fri Oct 7 16:40:49 PDT 2011


Author: efriedma
Date: Fri Oct  7 18:40:49 2011
New Revision: 141441

URL: http://llvm.org/viewvc/llvm-project?rev=141441&view=rev
Log:
Fix APInt::operator*= so that it computes the correct result for large integers where there is unsigned overflow.  Fix APFloat::toString so that it doesn't depend on the incorrect behavior in common cases (and computes the correct result in some rare cases).  Fixes PR11086.


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

Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=141441&r1=141440&r2=141441&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct  7 18:40:49 2011
@@ -3455,7 +3455,7 @@
     //                 <= semantics->precision + e * 137 / 59
     //   (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
 
-    unsigned precision = semantics->precision + 137 * texp / 59;
+    unsigned precision = semantics->precision + (137 * texp + 136) / 59;
 
     // Multiply significand by 5^e.
     //   N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)

Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=141441&r1=141440&r2=141441&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Fri Oct  7 18:40:49 2011
@@ -386,6 +386,7 @@
   clearAllBits();
   unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
   memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
+  clearUnusedBits();
 
   // delete dest array and return
   delete[] dest;
@@ -471,7 +472,7 @@
     return APInt(BitWidth, VAL * RHS.VAL);
   APInt Result(*this);
   Result *= RHS;
-  return Result.clearUnusedBits();
+  return Result;
 }
 
 APInt APInt::operator+(const APInt& RHS) const {

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=141441&r1=141440&r2=141441&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Fri Oct  7 18:40:49 2011
@@ -441,4 +441,13 @@
 #endif
 #endif
 
+TEST(APIntTest, mul_clear) {
+  APInt ValA(65, -1ULL);
+  APInt ValB(65, 4);
+  APInt ValC(65, 0);
+  ValC = ValA * ValB;
+  ValA *= ValB;
+  EXPECT_EQ(ValA.toString(10, false), ValC.toString(10, false));
+}
+
 }





More information about the llvm-commits mailing list