1. Fix three serious bugs in the comparison code.

2. Change RoundDoubleToAPInt to take a bit width parameter. Use that
   parameter to limit the bit width of the result.

llvm-svn: 34673
This commit is contained in:
Reid Spencer 2007-02-27 18:23:40 +00:00
parent c561bd2f18
commit 54abdcf30b
1 changed files with 22 additions and 18 deletions

View File

@ -540,7 +540,8 @@ bool APInt::ult(const APInt& RHS) const {
return pVal[0] < RHS.pVal[0]; return pVal[0] < RHS.pVal[0];
// Otherwise, compare all words // Otherwise, compare all words
for (int i = whichWord(n1 - 1); i >= 0; --i) { uint32_t topWord = whichWord(std::max(n1,n2)-1);
for (int i = topWord; i >= 0; --i) {
if (pVal[i] > RHS.pVal[i]) if (pVal[i] > RHS.pVal[i])
return false; return false;
if (pVal[i] < RHS.pVal[i]) if (pVal[i] < RHS.pVal[i])
@ -558,30 +559,28 @@ bool APInt::slt(const APInt& RHS) const {
} }
APInt lhs(*this); APInt lhs(*this);
APInt rhs(*this); APInt rhs(RHS);
bool lhsNegative = false; bool lhsNeg = isNegative();
bool rhsNegative = false; bool rhsNeg = rhs.isNegative();
if (lhs[BitWidth-1]) { if (lhsNeg) {
// Sign bit is set so make a note of it and perform two's complement // Sign bit is set so perform two's complement to make it positive
lhsNegative = true;
lhs.flip(); lhs.flip();
lhs++; lhs++;
} }
if (rhs[BitWidth-1]) { if (rhsNeg) {
// Sign bit is set so make a note of it and perform two's complement // Sign bit is set so perform two's complement to make it positive
rhsNegative = true;
rhs.flip(); rhs.flip();
rhs++; rhs++;
} }
// Now we have unsigned values to compare so do the comparison if necessary // Now we have unsigned values to compare so do the comparison if necessary
// based on the negativeness of the values. // based on the negativeness of the values.
if (lhsNegative) if (lhsNeg)
if (rhsNegative) if (rhsNeg)
return !lhs.ult(rhs); return lhs.ugt(rhs);
else else
return true; return true;
else if (rhsNegative) else if (rhsNeg)
return false; return false;
else else
return lhs.ult(rhs); return lhs.ult(rhs);
@ -797,7 +796,7 @@ APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1,
return A; return A;
} }
APInt llvm::APIntOps::RoundDoubleToAPInt(double Double) { APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, uint32_t width) {
union { union {
double D; double D;
uint64_t I; uint64_t I;
@ -819,11 +818,16 @@ APInt llvm::APIntOps::RoundDoubleToAPInt(double Double) {
// If the exponent doesn't shift all bits out of the mantissa // If the exponent doesn't shift all bits out of the mantissa
if (exp < 52) if (exp < 52)
return isNeg ? -APInt(64u, mantissa >> (52 - exp)) : return isNeg ? -APInt(width, mantissa >> (52 - exp)) :
APInt(64u, mantissa >> (52 - exp)); APInt(width, mantissa >> (52 - exp));
// If the client didn't provide enough bits for us to shift the mantissa into
// then the result is undefined, just return 0
if (width <= exp - 52)
return APInt(width, 0);
// Otherwise, we have to shift the mantissa bits up to the right location // Otherwise, we have to shift the mantissa bits up to the right location
APInt Tmp(exp+1, mantissa); APInt Tmp(width, mantissa);
Tmp = Tmp.shl(exp - 52); Tmp = Tmp.shl(exp - 52);
return isNeg ? -Tmp : Tmp; return isNeg ? -Tmp : Tmp;
} }