Skip to content

Commit

Permalink
APFloat: Add getExactLog2Abs
Browse files Browse the repository at this point in the history
Like the recently added getExactLog2 except ignore the sign bit.

https://reviews.llvm.org/D158102
  • Loading branch information
arsenm committed Aug 23, 2023
1 parent 908ae84 commit 8a02fd3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
16 changes: 15 additions & 1 deletion llvm/include/llvm/ADT/APFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,17 @@ class IEEEFloat final : public APFloatBase {
/// return true.
bool getExactInverse(APFloat *inv) const;

// If this is an exact power of two, return the exponent while ignoring the
// sign bit. If it's not an exact power of 2, return INT_MIN
LLVM_READONLY
int getExactLog2Abs() const;

// If this is an exact power of two, return the exponent. If it's not an exact
// power of 2, return INT_MIN
LLVM_READONLY
int getExactLog2() const;
int getExactLog2() const {
return isNegative() ? INT_MIN : getExactLog2Abs();
}

/// Returns the exponent of the internal representation of the APFloat.
///
Expand Down Expand Up @@ -754,6 +761,8 @@ class DoubleAPFloat final : public APFloatBase {

LLVM_READONLY
int getExactLog2() const;
LLVM_READONLY
int getExactLog2Abs() const;

friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp, roundingMode);
friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
Expand Down Expand Up @@ -1324,6 +1333,11 @@ class APFloat : public APFloatBase {
APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
}

LLVM_READONLY
int getExactLog2Abs() const {
APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2Abs());
}

LLVM_READONLY
int getExactLog2() const {
APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2());
Expand Down
9 changes: 7 additions & 2 deletions llvm/lib/Support/APFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4292,8 +4292,8 @@ bool IEEEFloat::getExactInverse(APFloat *inv) const {
return true;
}

int IEEEFloat::getExactLog2() const {
if (!isFinite() || isZero() || isNegative())
int IEEEFloat::getExactLog2Abs() const {
if (!isFinite() || isZero())
return INT_MIN;

const integerPart *Parts = significandParts();
Expand Down Expand Up @@ -5121,6 +5121,11 @@ int DoubleAPFloat::getExactLog2() const {
return INT_MIN;
}

int DoubleAPFloat::getExactLog2Abs() const {
// TODO: Implement me
return INT_MIN;
}

DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp,
APFloat::roundingMode RM) {
assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
Expand Down
16 changes: 15 additions & 1 deletion llvm/unittests/ADT/APFloatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6597,6 +6597,7 @@ TEST(APFloatTest, getExactLog2) {
if (I == APFloat::S_PPCDoubleDouble) {
// Not implemented
EXPECT_EQ(INT_MIN, One.getExactLog2());
EXPECT_EQ(INT_MIN, One.getExactLog2Abs());
continue;
}

Expand All @@ -6607,10 +6608,16 @@ TEST(APFloatTest, getExactLog2) {
EXPECT_EQ(0, One.getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2Abs());
EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "-8.0").getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25").getExactLog2());
EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2());
EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25").getExactLog2());
EXPECT_EQ(-2, APFloat(Semantics, "-0.25").getExactLog2Abs());
EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());
EXPECT_EQ(3, APFloat(Semantics, "-8.0").getExactLog2Abs());

EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2());
EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2());
Expand All @@ -6619,6 +6626,13 @@ TEST(APFloatTest, getExactLog2) {
EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2());
EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2());

EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2Abs());
EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2Abs());

EXPECT_EQ(INT_MIN,
scalbn(One, MinExp - Precision - 1, APFloat::rmNearestTiesToEven)
.getExactLog2());
Expand Down

0 comments on commit 8a02fd3

Please sign in to comment.