mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00: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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141441 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -3455,7 +3455,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
|
|||||||
// <= semantics->precision + e * 137 / 59
|
// <= semantics->precision + e * 137 / 59
|
||||||
// (log_2(5) ~ 2.321928 < 2.322034 ~ 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.
|
// Multiply significand by 5^e.
|
||||||
// N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
|
// 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();
|
clearAllBits();
|
||||||
unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
|
unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
|
||||||
memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
|
memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
|
||||||
|
clearUnusedBits();
|
||||||
|
|
||||||
// delete dest array and return
|
// delete dest array and return
|
||||||
delete[] dest;
|
delete[] dest;
|
||||||
@@ -471,7 +472,7 @@ APInt APInt::operator*(const APInt& RHS) const {
|
|||||||
return APInt(BitWidth, VAL * RHS.VAL);
|
return APInt(BitWidth, VAL * RHS.VAL);
|
||||||
APInt Result(*this);
|
APInt Result(*this);
|
||||||
Result *= RHS;
|
Result *= RHS;
|
||||||
return Result.clearUnusedBits();
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt APInt::operator+(const APInt& RHS) const {
|
APInt APInt::operator+(const APInt& RHS) const {
|
||||||
|
@@ -441,4 +441,13 @@ TEST(APIntTest, StringDeath) {
|
|||||||
#endif
|
#endif
|
||||||
#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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user