forked from OSchip/llvm-project
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:
parent
c561bd2f18
commit
54abdcf30b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue