Skip to content

Commit

Permalink
Fix APInt::operator*= so that it computes the correct result for larg…
Browse files Browse the repository at this point in the history
…e 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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141441 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
eefriedman committed Oct 7, 2011
1 parent d2fdb4a commit 9eb6b4d
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/Support/APFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3455,7 +3455,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// <= 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)
Expand Down
3 changes: 2 additions & 1 deletion lib/Support/APInt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ APInt& APInt::operator*=(const APInt& RHS) {
clearAllBits();
unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
clearUnusedBits();

// delete dest array and return
delete[] dest;
Expand Down Expand Up @@ -471,7 +472,7 @@ APInt APInt::operator*(const APInt& RHS) const {
return APInt(BitWidth, VAL * RHS.VAL);
APInt Result(*this);
Result *= RHS;
return Result.clearUnusedBits();
return Result;
}

APInt APInt::operator+(const APInt& RHS) const {
Expand Down
9 changes: 9 additions & 0 deletions unittests/ADT/APIntTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,4 +441,13 @@ TEST(APIntTest, StringDeath) {
#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));
}

}

0 comments on commit 9eb6b4d

Please sign in to comment.