mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
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.
llvm-svn: 141441
This commit is contained in:
parent
8b0cf65af7
commit
433785c651
@ -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)
|
||||
|
@ -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;
|
||||
@ -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 {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user