Add APFloat::getExactInverse.

The idea is, that if an ieee 754 float is divided by a power of two, we can
turn the division into a cheaper multiplication. This function sees if we can
get an exact multiplicative inverse for a divisor and returns it if possible.

This is the hard part of PR9587.

I tested many inputs against llvm-gcc's frotend implementation of this
optimization and didn't find any difference. However, floating point is the
land of weird edge cases, so any review would be appreciated.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128545 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2011-03-30 15:42:27 +00:00
parent d01f2633b9
commit 2746000f4f
3 changed files with 53 additions and 0 deletions
+26
View File
@@ -3562,3 +3562,29 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
for (; I != NDigits; ++I)
Str.push_back(buffer[NDigits-I-1]);
}
bool APFloat::getExactInverse(APFloat *inv) const {
// We can only guarantee the existance of an exact inverse for IEEE floats.
if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
semantics != &IEEEdouble && semantics != &IEEEquad)
return false;
// Special floats and denormals have no exact inverse.
if (category != fcNormal)
return false;
// Check that the number is a power of two by making sure that only the
// integer bit is set in the significand.
if (significandLSB() != semantics->precision - 1)
return false;
// Get the inverse.
APFloat reciprocal(*semantics, 1ULL);
if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
return false;
if (inv)
*inv = reciprocal;
return true;
}