aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2011-03-30 15:42:27 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2011-03-30 15:42:27 +0000
commit2746000f4fa54e6ad00cf96910ea5772803624ed (patch)
treebd6513967e2f459833124c1834762d983bf7b3b0 /lib/Support
parentd01f2633b9aab6281c936da04226b46a0dde7ba9 (diff)
downloadexternal_llvm-2746000f4fa54e6ad00cf96910ea5772803624ed.zip
external_llvm-2746000f4fa54e6ad00cf96910ea5772803624ed.tar.gz
external_llvm-2746000f4fa54e6ad00cf96910ea5772803624ed.tar.bz2
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
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 93806fa..abe5575 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -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;
+}