llvm.org GIT mirror llvm / 2746000
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 Benjamin Kramer 9 years ago
3 changed file(s) with 54 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
351351 void toString(SmallVectorImpl &Str,
352352 unsigned FormatPrecision = 0,
353353 unsigned FormatMaxPadding = 3) const;
354
355 /// getExactInverse - If this value has an exact multiplicative inverse,
356 /// store it in inv and return true.
357 bool getExactInverse(APFloat *inv) const;
354358
355359 private:
356360
35613561 for (; I != NDigits; ++I)
35623562 Str.push_back(buffer[NDigits-I-1]);
35633563 }
3564
3565 bool APFloat::getExactInverse(APFloat *inv) const {
3566 // We can only guarantee the existance of an exact inverse for IEEE floats.
3567 if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
3568 semantics != &IEEEdouble && semantics != &IEEEquad)
3569 return false;
3570
3571 // Special floats and denormals have no exact inverse.
3572 if (category != fcNormal)
3573 return false;
3574
3575 // Check that the number is a power of two by making sure that only the
3576 // integer bit is set in the significand.
3577 if (significandLSB() != semantics->precision - 1)
3578 return false;
3579
3580 // Get the inverse.
3581 APFloat reciprocal(*semantics, 1ULL);
3582 if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
3583 return false;
3584
3585 if (inv)
3586 *inv = reciprocal;
3587
3588 return true;
3589 }
575575 #endif
576576 #endif
577577
578 }
578 TEST(APFloatTest, exactInverse) {
579 APFloat inv(0.0f);
580
581 // Trivial operation.
582 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
583 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
584 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
585 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
586
587 // FLT_MIN
588 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
589 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
590
591 // Large float
592 EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv));
593 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f)));
594
595 // Zero
596 EXPECT_FALSE(APFloat(0.0).getExactInverse(0));
597 // Denormalized float
598 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0));
599 }
600
601 }