[llvm-commits] [llvm] r128545 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp unittests/ADT/APFloatTest.cpp
Benjamin Kramer
benny.kra at googlemail.com
Wed Mar 30 08:42:27 PDT 2011
Author: d0k
Date: Wed Mar 30 10:42:27 2011
New Revision: 128545
URL: http://llvm.org/viewvc/llvm-project?rev=128545&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/ADT/APFloat.h
llvm/trunk/lib/Support/APFloat.cpp
llvm/trunk/unittests/ADT/APFloatTest.cpp
Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=128545&r1=128544&r2=128545&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Mar 30 10:42:27 2011
@@ -353,6 +353,10 @@
unsigned FormatPrecision = 0,
unsigned FormatMaxPadding = 3) const;
+ /// getExactInverse - If this value has an exact multiplicative inverse,
+ /// store it in inv and return true.
+ bool getExactInverse(APFloat *inv) const;
+
private:
/* Trivial queries. */
Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=128545&r1=128544&r2=128545&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Wed Mar 30 10:42:27 2011
@@ -3562,3 +3562,29 @@
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;
+}
Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=128545&r1=128544&r2=128545&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APFloatTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APFloatTest.cpp Wed Mar 30 10:42:27 2011
@@ -576,4 +576,27 @@
#endif
#endif
+TEST(APFloatTest, exactInverse) {
+ APFloat inv(0.0f);
+
+ // Trivial operation.
+ EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
+ EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
+ EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
+ EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
+
+ // FLT_MIN
+ EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
+ EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
+
+ // Large float
+ EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv));
+ EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f)));
+
+ // Zero
+ EXPECT_FALSE(APFloat(0.0).getExactInverse(0));
+ // Denormalized float
+ EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0));
+}
+
}
More information about the llvm-commits
mailing list