diff options
| -rw-r--r-- | llvm/include/llvm/ADT/APFloat.h | 11 | ||||
| -rw-r--r-- | llvm/lib/Support/APFloat.cpp | 18 | ||||
| -rw-r--r-- | llvm/unittests/ADT/APFloatTest.cpp | 18 | 
3 files changed, 35 insertions, 12 deletions
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h index a1376ad3b98..45daeca8e43 100644 --- a/llvm/include/llvm/ADT/APFloat.h +++ b/llvm/include/llvm/ADT/APFloat.h @@ -511,16 +511,7 @@ public:    ///   0   -> \c IEK_Zero    ///   Inf -> \c IEK_Inf    /// -  friend int ilogb(const APFloat &Arg) { -    if (Arg.isNaN()) -      return IEK_NaN; -    if (Arg.isZero()) -      return IEK_Zero; -    if (Arg.isInfinity()) -      return IEK_Inf; - -    return Arg.exponent; -  } +  friend int ilogb(const APFloat &Arg);    /// \brief Returns: X * 2^Exp for integral exponents.    friend APFloat scalbn(APFloat X, int Exp, roundingMode); diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 95953b6d071..814c72cc4d3 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -3945,6 +3945,24 @@ APFloat::makeZero(bool Negative) {    APInt::tcSet(significandParts(), 0, partCount());    } +int llvm::ilogb(const APFloat &Arg) { +  if (Arg.isNaN()) +    return APFloat::IEK_NaN; +  if (Arg.isZero()) +    return APFloat::IEK_Zero; +  if (Arg.isInfinity()) +    return APFloat::IEK_Inf; +  if (!Arg.isDenormal()) +    return Arg.exponent; + +  APFloat Normalized(Arg); +  int SignificandBits = Arg.getSemantics().precision - 1; + +  Normalized.exponent += SignificandBits; +  Normalized.normalize(APFloat::rmNearestTiesToEven, lfExactlyZero); +  return Normalized.exponent - SignificandBits; +} +  APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) {    auto MaxExp = X.getSemantics().maxExponent;    auto MinExp = X.getSemantics().minExponent; diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index 546973ca481..e78caf3b898 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -2821,6 +2821,19 @@ TEST(APFloatTest, abs) {  }  TEST(APFloatTest, ilogb) { +  EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble, false))); +  EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble, true))); +  EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble, "0x1.ffffffffffffep-1024"))); +  EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble, "0x1.ffffffffffffep-1023"))); +  EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble, "-0x1.ffffffffffffep-1023"))); +  EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble, "0x1p-51"))); +  EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble, "0x1.c60f120d9f87cp-1023"))); +  EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble, "0x0.ffffp-1"))); +  EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble, "0x1.fffep-1023"))); +  EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble, false))); +  EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble, true))); + +    EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+0")));    EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "-0x1p+0")));    EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+42"))); @@ -2841,8 +2854,9 @@ TEST(APFloatTest, ilogb) {    EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, false)));    EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, true))); -  EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false))); -  EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true))); + +  EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false))); +  EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true)));    EXPECT_EQ(-126,              ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, false)));    EXPECT_EQ(-126,  | 

