From fb706e086c70de9dd24852f1ef1d0f411bd501a1 Mon Sep 17 00:00:00 2001 From: Siva Chandra Reddy Date: Wed, 14 Apr 2021 06:04:11 +0000 Subject: [PATCH] [libc][NFC] Make conversion from FPBits to the float point type explicit. This will help us catch errors like the ones fixed by the commit 31ed45d9cfd5da2bf4f1d7ddba54122df6fc91fa --- libc/test/src/math/FDimTest.h | 14 +++++++------- libc/test/src/math/FmaTest.h | 28 +++++++++++++++------------- libc/test/src/math/HypotTest.h | 14 +++++++------- libc/test/src/math/ILogbTest.h | 15 ++++++++------- libc/test/src/math/LdExpTest.h | 10 +++++----- libc/test/src/math/NextAfterTest.h | 10 +++++----- libc/test/src/math/RIntTest.h | 14 +++++++------- libc/test/src/math/RemQuoTest.h | 14 +++++++------- libc/test/src/math/RoundToIntegerTest.h | 18 +++++++++--------- libc/test/src/math/SqrtTest.h | 4 ++-- libc/test/src/math/frexp_test.cpp | 2 +- libc/test/src/math/frexpf_test.cpp | 2 +- libc/test/src/math/frexpl_test.cpp | 2 +- libc/utils/FPUtil/FPBits.h | 4 ++-- libc/utils/FPUtil/Hypot.h | 6 +++--- libc/utils/FPUtil/ManipulationFunctions.h | 15 ++++++++------- libc/utils/FPUtil/NearestIntegerOperations.h | 2 +- libc/utils/FPUtil/NormalFloat.h | 14 +++++++------- libc/utils/FPUtil/TestHelpers.h | 10 +++++----- 19 files changed, 101 insertions(+), 97 deletions(-) diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h index d632b23..1a53440 100644 --- a/libc/test/src/math/FDimTest.h +++ b/libc/test/src/math/FDimTest.h @@ -57,7 +57,7 @@ public: constexpr UIntType step = UIntType(-1) / count; for (UIntType i = 0, v = 0, w = UIntType(-1); i <= count; ++i, v += step, w -= step) { - T x = FPBits(v), y = FPBits(w); + T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) continue; if (isnan(y) || isinf(y)) @@ -74,9 +74,9 @@ public: private: // constexpr does not work on FPBits yet, so we cannot have these constants as // static. - const T nan = __llvm_libc::fputil::FPBits::buildNaN(1); - const T inf = __llvm_libc::fputil::FPBits::inf(); - const T negInf = __llvm_libc::fputil::FPBits::negInf(); - const T zero = __llvm_libc::fputil::FPBits::zero(); - const T negZero = __llvm_libc::fputil::FPBits::negZero(); -}; \ No newline at end of file + const T nan = T(__llvm_libc::fputil::FPBits::buildNaN(1)); + const T inf = T(__llvm_libc::fputil::FPBits::inf()); + const T negInf = T(__llvm_libc::fputil::FPBits::negInf()); + const T zero = T(__llvm_libc::fputil::FPBits::zero()); + const T negZero = T(__llvm_libc::fputil::FPBits::negZero()); +}; diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h index 9f90c86..eb31bf8 100644 --- a/libc/test/src/math/FmaTest.h +++ b/libc/test/src/math/FmaTest.h @@ -23,11 +23,11 @@ private: using Func = T (*)(T, T, T); using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; - const T nan = __llvm_libc::fputil::FPBits::buildNaN(1); - const T inf = __llvm_libc::fputil::FPBits::inf(); - const T negInf = __llvm_libc::fputil::FPBits::negInf(); - const T zero = __llvm_libc::fputil::FPBits::zero(); - const T negZero = __llvm_libc::fputil::FPBits::negZero(); + const T nan = T(__llvm_libc::fputil::FPBits::buildNaN(1)); + const T inf = T(__llvm_libc::fputil::FPBits::inf()); + const T negInf = T(__llvm_libc::fputil::FPBits::negInf()); + const T zero = T(__llvm_libc::fputil::FPBits::zero()); + const T negZero = T(__llvm_libc::fputil::FPBits::negZero()); UIntType getRandomBitPattern() { UIntType bits{0}; @@ -50,16 +50,16 @@ public: EXPECT_FP_EQ(func(inf, negInf, nan), nan); // Test underflow rounding up. - EXPECT_FP_EQ(func(T(0.5), FPBits(FPBits::minSubnormal), - FPBits(FPBits::minSubnormal)), - FPBits(UIntType(2))); + EXPECT_FP_EQ(func(T(0.5), T(FPBits(FPBits::minSubnormal)), + T(FPBits(FPBits::minSubnormal))), + T(FPBits(UIntType(2)))); // Test underflow rounding down. - FPBits v(FPBits::minNormal + UIntType(1)); + T v = T(FPBits(FPBits::minNormal + UIntType(1))); EXPECT_FP_EQ( - func(T(1) / T(FPBits::minNormal << 1), v, FPBits(FPBits::minNormal)), + func(T(1) / T(FPBits::minNormal << 1), v, T(FPBits(FPBits::minNormal))), v); // Test overflow. - FPBits z(FPBits::maxNormal); + T z = T(FPBits(FPBits::maxNormal)); EXPECT_FP_EQ(func(T(1.75), z, -z), T(0.75) * z); } @@ -70,7 +70,8 @@ public: for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal; v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal; v += step, w -= step) { - T x = FPBits(getRandomBitPattern()), y = FPBits(v), z = FPBits(w); + T x = T(FPBits(getRandomBitPattern())), y = T(FPBits(v)), + z = T(FPBits(w)); T result = func(x, y, z); mpfr::TernaryInput input{x, y, z}; ASSERT_MPFR_MATCH(mpfr::Operation::Fma, input, result, 0.5); @@ -83,7 +84,8 @@ public: for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal; v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) { - T x = FPBits(v), y = FPBits(w), z = FPBits(getRandomBitPattern()); + T x = T(FPBits(v)), y = T(FPBits(w)), + z = T(FPBits(getRandomBitPattern())); T result = func(x, y, z); mpfr::TernaryInput input{x, y, z}; ASSERT_MPFR_MATCH(mpfr::Operation::Fma, input, result, 0.5); diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h index 34b1ff6..697d604 100644 --- a/libc/test/src/math/HypotTest.h +++ b/libc/test/src/math/HypotTest.h @@ -25,11 +25,11 @@ private: using Func = T (*)(T, T); using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; - const T nan = __llvm_libc::fputil::FPBits::buildNaN(1); - const T inf = __llvm_libc::fputil::FPBits::inf(); - const T negInf = __llvm_libc::fputil::FPBits::negInf(); - const T zero = __llvm_libc::fputil::FPBits::zero(); - const T negZero = __llvm_libc::fputil::FPBits::negZero(); + const T nan = T(__llvm_libc::fputil::FPBits::buildNaN(1)); + const T inf = T(__llvm_libc::fputil::FPBits::inf()); + const T negInf = T(__llvm_libc::fputil::FPBits::negInf()); + const T zero = T(__llvm_libc::fputil::FPBits::zero()); + const T negZero = T(__llvm_libc::fputil::FPBits::negZero()); public: void testSpecialNumbers(Func func) { @@ -52,7 +52,7 @@ public: for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal; v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal; v += step, w -= step) { - T x = FPBits(v), y = FPBits(w); + T x = T(FPBits(v)), y = T(FPBits(w)); T result = func(x, y); mpfr::BinaryInput input{x, y}; ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5); @@ -65,7 +65,7 @@ public: for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal; v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) { - T x = FPBits(v), y = FPBits(w); + T x = T(FPBits(v)), y = T(FPBits(w)); T result = func(x, y); mpfr::BinaryInput input{x, y}; ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5); diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h index 724cc95..bf79960 100644 --- a/libc/test/src/math/ILogbTest.h +++ b/libc/test/src/math/ILogbTest.h @@ -22,13 +22,14 @@ public: template void testSpecialNumbers(typename ILogbFunc::Func func) { - EXPECT_EQ(FP_ILOGB0, func(__llvm_libc::fputil::FPBits::zero())); - EXPECT_EQ(FP_ILOGB0, func(__llvm_libc::fputil::FPBits::negZero())); + EXPECT_EQ(FP_ILOGB0, func(T(__llvm_libc::fputil::FPBits::zero()))); + EXPECT_EQ(FP_ILOGB0, func(T(__llvm_libc::fputil::FPBits::negZero()))); - EXPECT_EQ(FP_ILOGBNAN, func(__llvm_libc::fputil::FPBits::buildNaN(1))); + EXPECT_EQ(FP_ILOGBNAN, + func(T(__llvm_libc::fputil::FPBits::buildNaN(1)))); - EXPECT_EQ(INT_MAX, func(__llvm_libc::fputil::FPBits::inf())); - EXPECT_EQ(INT_MAX, func(__llvm_libc::fputil::FPBits::negInf())); + EXPECT_EQ(INT_MAX, func(T(__llvm_libc::fputil::FPBits::inf()))); + EXPECT_EQ(INT_MAX, func(T(__llvm_libc::fputil::FPBits::negInf()))); } template void testPowersOfTwo(typename ILogbFunc::Func func) { @@ -78,7 +79,7 @@ public: (FPBits::maxSubnormal - FPBits::minSubnormal) / count; for (UIntType v = FPBits::minSubnormal; v <= FPBits::maxSubnormal; v += step) { - T x = FPBits(v); + T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; @@ -94,7 +95,7 @@ public: constexpr UIntType count = 1000001; constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count; for (UIntType v = FPBits::minNormal; v <= FPBits::maxNormal; v += step) { - T x = FPBits(v); + T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h index a2c1b54..046ec04 100644 --- a/libc/test/src/math/LdExpTest.h +++ b/libc/test/src/math/LdExpTest.h @@ -28,11 +28,11 @@ class LdExpTestTemplate : public __llvm_libc::testing::Test { // A normalized mantissa to be used with tests. static constexpr UIntType mantissa = NormalFloat::one + 0x1234; - const T zero = __llvm_libc::fputil::FPBits::zero(); - const T negZero = __llvm_libc::fputil::FPBits::negZero(); - const T inf = __llvm_libc::fputil::FPBits::inf(); - const T negInf = __llvm_libc::fputil::FPBits::negInf(); - const T nan = __llvm_libc::fputil::FPBits::buildNaN(1); + const T zero = T(__llvm_libc::fputil::FPBits::zero()); + const T negZero = T(__llvm_libc::fputil::FPBits::negZero()); + const T inf = T(__llvm_libc::fputil::FPBits::inf()); + const T negInf = T(__llvm_libc::fputil::FPBits::negInf()); + const T nan = T(__llvm_libc::fputil::FPBits::buildNaN(1)); public: typedef T (*LdExpFunc)(T, int); diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h index 8ba3f30..9c53ab7 100644 --- a/libc/test/src/math/NextAfterTest.h +++ b/libc/test/src/math/NextAfterTest.h @@ -29,11 +29,11 @@ class NextAfterTestTemplate : public __llvm_libc::testing::Test { static constexpr int bitWidthOfType = sizeof(T) * 8; #endif - const T zero = FPBits::zero(); - const T negZero = FPBits::negZero(); - const T inf = FPBits::inf(); - const T negInf = FPBits::negInf(); - const T nan = FPBits::buildNaN(1); + const T zero = T(FPBits::zero()); + const T negZero = T(FPBits::negZero()); + const T inf = T(FPBits::inf()); + const T negInf = T(FPBits::negInf()); + const T nan = T(FPBits::buildNaN(1)); const UIntType minSubnormal = FPBits::minSubnormal; const UIntType maxSubnormal = FPBits::maxSubnormal; const UIntType minNormal = FPBits::minNormal; diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h index 18331ec..edcc279 100644 --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -33,11 +33,11 @@ private: using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; - const T zero = FPBits::zero(); - const T negZero = FPBits::negZero(); - const T inf = FPBits::inf(); - const T negInf = FPBits::negInf(); - const T nan = FPBits::buildNaN(1); + const T zero = T(FPBits::zero()); + const T negZero = T(FPBits::negZero()); + const T inf = T(FPBits::inf()); + const T negInf = T(FPBits::negInf()); + const T nan = T(FPBits::buildNaN(1)); static inline mpfr::RoundingMode toMPFRRoundingMode(int mode) { switch (mode) { @@ -98,7 +98,7 @@ public: (FPBits::maxSubnormal - FPBits::minSubnormal) / count; for (UIntType i = FPBits::minSubnormal; i <= FPBits::maxSubnormal; i += step) { - T x = FPBits(i); + T x = T(FPBits(i)); for (int mode : roundingModes) { __llvm_libc::fputil::setRound(mode); mpfr::RoundingMode mpfrMode = toMPFRRoundingMode(mode); @@ -111,7 +111,7 @@ public: constexpr UIntType count = 1000001; constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count; for (UIntType i = FPBits::minNormal; i <= FPBits::maxNormal; i += step) { - T x = FPBits(i); + T x = T(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be // zero making the numbers NaN. We will skip them. if (isnan(x)) { diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h index f643079..7b442ff 100644 --- a/libc/test/src/math/RemQuoTest.h +++ b/libc/test/src/math/RemQuoTest.h @@ -23,11 +23,11 @@ class RemQuoTestTemplate : public __llvm_libc::testing::Test { using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; - const T zero = __llvm_libc::fputil::FPBits::zero(); - const T negZero = __llvm_libc::fputil::FPBits::negZero(); - const T inf = __llvm_libc::fputil::FPBits::inf(); - const T negInf = __llvm_libc::fputil::FPBits::negInf(); - const T nan = __llvm_libc::fputil::FPBits::buildNaN(1); + const T zero = T(__llvm_libc::fputil::FPBits::zero()); + const T negZero = T(__llvm_libc::fputil::FPBits::negZero()); + const T inf = T(__llvm_libc::fputil::FPBits::inf()); + const T negInf = T(__llvm_libc::fputil::FPBits::negInf()); + const T nan = T(__llvm_libc::fputil::FPBits::buildNaN(1)); public: typedef T (*RemQuoFunc)(T, T, int *); @@ -101,7 +101,7 @@ public: for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal; v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal; v += step, w -= step) { - T x = FPBits(v), y = FPBits(w); + T x = T(FPBits(v)), y = T(FPBits(w)); mpfr::BinaryOutput result; mpfr::BinaryInput input{x, y}; result.f = func(x, y, &result.i); @@ -115,7 +115,7 @@ public: for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal; v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) { - T x = FPBits(v), y = FPBits(w); + T x = T(FPBits(v)), y = T(FPBits(w)); mpfr::BinaryOutput result; mpfr::BinaryInput input{x, y}; result.f = func(x, y, &result.i); diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index 0b83b9a..c3d0351 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -35,11 +35,11 @@ private: using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; - const F zero = __llvm_libc::fputil::FPBits::zero(); - const F negZero = __llvm_libc::fputil::FPBits::negZero(); - const F inf = __llvm_libc::fputil::FPBits::inf(); - const F negInf = __llvm_libc::fputil::FPBits::negInf(); - const F nan = __llvm_libc::fputil::FPBits::buildNaN(1); + const F zero = F(__llvm_libc::fputil::FPBits::zero()); + const F negZero = F(__llvm_libc::fputil::FPBits::negZero()); + const F inf = F(__llvm_libc::fputil::FPBits::inf()); + const F negInf = F(__llvm_libc::fputil::FPBits::negInf()); + const F nan = F(__llvm_libc::fputil::FPBits::buildNaN(1)); static constexpr I IntegerMin = I(1) << (sizeof(I) * 8 - 1); static constexpr I IntegerMax = -(IntegerMin + 1); @@ -139,7 +139,7 @@ public: bits.encoding.sign = 1; bits.encoding.mantissa = 0; - F x = bits; + F x = F(bits); long mpfrResult; bool erangeflag = mpfr::RoundToLong(x, mpfrResult); ASSERT_FALSE(erangeflag); @@ -204,7 +204,7 @@ public: bits.encoding.mantissa = UIntType(0x1) << (__llvm_libc::fputil::MantissaWidth::value - 1); - F x = bits; + F x = F(bits); if (TestModes) { for (int m : roundingModes) { __llvm_libc::fputil::setRound(m); @@ -228,7 +228,7 @@ public: (FPBits::maxSubnormal - FPBits::minSubnormal) / count; for (UIntType i = FPBits::minSubnormal; i <= FPBits::maxSubnormal; i += step) { - F x = FPBits(i); + F x = F(FPBits(i)); if (x == F(0.0)) continue; // All subnormal numbers should round to zero. @@ -270,7 +270,7 @@ public: constexpr UIntType count = 1000001; constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count; for (UIntType i = FPBits::minNormal; i <= FPBits::maxNormal; i += step) { - F x = FPBits(i); + F x = F(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be // zero making the numbers NaN. We will skip them. if (isnan(x)) { diff --git a/libc/test/src/math/SqrtTest.h b/libc/test/src/math/SqrtTest.h index 56916a5..56a16bb 100644 --- a/libc/test/src/math/SqrtTest.h +++ b/libc/test/src/math/SqrtTest.h @@ -41,8 +41,8 @@ public: FPBits denormal(T(0.0)); denormal.encoding.mantissa = mant; - ASSERT_MPFR_MATCH(mpfr::Operation::Sqrt, T(denormal), - func(denormal), T(0.5)); + ASSERT_MPFR_MATCH(mpfr::Operation::Sqrt, T(denormal), func(T(denormal)), + T(0.5)); } constexpr UIntType count = 1'000'001; diff --git a/libc/test/src/math/frexp_test.cpp b/libc/test/src/math/frexp_test.cpp index d9fcae4..2d8ae1c 100644 --- a/libc/test/src/math/frexp_test.cpp +++ b/libc/test/src/math/frexp_test.cpp @@ -136,7 +136,7 @@ TEST(LlvmLibcFrexpTest, InDoubleRange) { constexpr UIntType count = 1000001; constexpr UIntType step = UIntType(-1) / count; for (UIntType i = 0, v = 0; i <= count; ++i, v += step) { - double x = FPBits(v); + double x = double(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; diff --git a/libc/test/src/math/frexpf_test.cpp b/libc/test/src/math/frexpf_test.cpp index 8d2fe30..a3a3da4 100644 --- a/libc/test/src/math/frexpf_test.cpp +++ b/libc/test/src/math/frexpf_test.cpp @@ -143,7 +143,7 @@ TEST(LlvmLibcFrexpfTest, InFloatRange) { constexpr UIntType count = 1000001; constexpr UIntType step = UIntType(-1) / count; for (UIntType i = 0, v = 0; i <= count; ++i, v += step) { - float x = FPBits(v); + float x = float(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; diff --git a/libc/test/src/math/frexpl_test.cpp b/libc/test/src/math/frexpl_test.cpp index ee18961..6036178 100644 --- a/libc/test/src/math/frexpl_test.cpp +++ b/libc/test/src/math/frexpl_test.cpp @@ -93,7 +93,7 @@ TEST(LlvmLibcFrexplTest, LongDoubleRange) { constexpr UIntType count = 10000000; constexpr UIntType step = UIntType(-1) / count; for (UIntType i = 0, v = 0; i <= count; ++i, v += step) { - long double x = FPBits(v); + long double x = static_cast(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0l) continue; diff --git a/libc/utils/FPUtil/FPBits.h b/libc/utils/FPUtil/FPBits.h index b2c1e57..bc69829c 100644 --- a/libc/utils/FPUtil/FPBits.h +++ b/libc/utils/FPUtil/FPBits.h @@ -102,7 +102,7 @@ template union FPBits { FPBits() : integer(0) {} - operator T() { return val; } + explicit operator T() { return val; } UIntType uintval() const { return integer; } @@ -143,7 +143,7 @@ template union FPBits { static T buildNaN(UIntType v) { FPBits bits = inf(); bits.encoding.mantissa = v; - return bits; + return T(bits); } }; diff --git a/libc/utils/FPUtil/Hypot.h b/libc/utils/FPUtil/Hypot.h index 3585304..adbd9f5 100644 --- a/libc/utils/FPUtil/Hypot.h +++ b/libc/utils/FPUtil/Hypot.h @@ -125,7 +125,7 @@ static inline T hypot(T x, T y) { FPBits_t x_bits(x), y_bits(y); if (x_bits.isInf() || y_bits.isInf()) { - return FPBits_t::inf(); + return T(FPBits_t::inf()); } if (x_bits.isNaN()) { return x; @@ -208,7 +208,7 @@ static inline T hypot(T x, T y) { sum >>= 2; ++out_exp; if (out_exp >= FPBits_t::maxExponent) { - return FPBits_t::inf(); + return T(FPBits_t::inf()); } } else { // For denormal result, we simply move the leading bit of the result to @@ -254,7 +254,7 @@ static inline T hypot(T x, T y) { Y -= one >> 1; ++out_exp; if (out_exp >= FPBits_t::maxExponent) { - return FPBits_t::inf(); + return T(FPBits_t::inf()); } } diff --git a/libc/utils/FPUtil/ManipulationFunctions.h b/libc/utils/FPUtil/ManipulationFunctions.h index f0e5c8f..9bd54ec 100644 --- a/libc/utils/FPUtil/ManipulationFunctions.h +++ b/libc/utils/FPUtil/ManipulationFunctions.h @@ -47,13 +47,14 @@ static inline T modf(T x, T &iptr) { return x; } else if (bits.isInf()) { iptr = x; - return bits.encoding.sign ? FPBits::negZero() : FPBits::zero(); + return bits.encoding.sign ? T(FPBits::negZero()) : T(FPBits::zero()); } else { iptr = trunc(x); if (x == iptr) { // If x is already an integer value, then return zero with the right // sign. - return bits.encoding.sign ? FPBits::negZero() : FPBits::zero(); + return bits.encoding.sign ? T(FPBits::negZero()) + : T(FPBits::zero()); } else { return x - iptr; } @@ -65,7 +66,7 @@ template xbits(x); xbits.encoding.sign = FPBits(y).encoding.sign; - return xbits; + return T(xbits); } template ::negInf(); + return T(FPBits::negInf()); } else if (bits.isNaN()) { return x; } else if (bits.isInf()) { // Return positive infinity. - return FPBits::inf(); + return T(FPBits::inf()); } NormalFloat normal(bits); @@ -131,11 +132,11 @@ static inline T ldexp(T x, int exp) { // calculating the limit. int expLimit = FPBits::maxExponent + MantissaWidth::value + 1; if (exp > expLimit) - return bits.encoding.sign ? FPBits::negInf() : FPBits::inf(); + return bits.encoding.sign ? T(FPBits::negInf()) : T(FPBits::inf()); // Similarly on the negative side we return zero early if |exp| is too small. if (exp < -expLimit) - return bits.encoding.sign ? FPBits::negZero() : FPBits::zero(); + return bits.encoding.sign ? T(FPBits::negZero()) : T(FPBits::zero()); // For all other values, NormalFloat to T conversion handles it the right way. NormalFloat normal(bits); diff --git a/libc/utils/FPUtil/NearestIntegerOperations.h b/libc/utils/FPUtil/NearestIntegerOperations.h index 7bb79be..5ea4b41 100644 --- a/libc/utils/FPUtil/NearestIntegerOperations.h +++ b/libc/utils/FPUtil/NearestIntegerOperations.h @@ -51,7 +51,7 @@ static inline T trunc(T x) { int trimSize = MantissaWidth::value - exponent; bits.encoding.mantissa = (bits.encoding.mantissa >> trimSize) << trimSize; - return bits; + return T(bits); } template struct NormalFloat { // Max exponent is of the form 0xFF...E. That is why -2 and not -1. constexpr int maxExponentValue = (1 << ExponentWidth::value) - 2; if (biasedExponent > maxExponentValue) { - return sign ? FPBits::negInf() : FPBits::inf(); + return sign ? T(FPBits::negInf()) : T(FPBits::inf()); } FPBits result(T(0.0)); @@ -126,15 +126,15 @@ template struct NormalFloat { // the overflow into the exponent. if (newMantissa == one) result.encoding.exponent = 1; - return result; + return T(result); } else { - return result; + return T(result); } } result.encoding.exponent = exponent + FPBits::exponentBias; result.encoding.mantissa = mantissa; - return result; + return T(result); } private: @@ -245,16 +245,16 @@ template <> inline NormalFloat::operator long double() const { } else { result.encoding.implicitBit = 0; } - return result; + return static_cast(result); } else { - return result; + return static_cast(result); } } result.encoding.exponent = biasedExponent; result.encoding.mantissa = mantissa; result.encoding.implicitBit = 1; - return result; + return static_cast(result); } #endif diff --git a/libc/utils/FPUtil/TestHelpers.h b/libc/utils/FPUtil/TestHelpers.h index 6ad6d3f..263eace 100644 --- a/libc/utils/FPUtil/TestHelpers.h +++ b/libc/utils/FPUtil/TestHelpers.h @@ -68,11 +68,11 @@ FPMatcher getMatcher(T expectedValue) { #define DECLARE_SPECIAL_CONSTANTS(T) \ using FPBits = __llvm_libc::fputil::FPBits; \ using UIntType = typename FPBits::UIntType; \ - const T zero = FPBits::zero(); \ - const T negZero = FPBits::negZero(); \ - const T aNaN = FPBits::buildNaN(1); \ - const T inf = FPBits::inf(); \ - const T negInf = FPBits::negInf(); + const T zero = T(FPBits::zero()); \ + const T negZero = T(FPBits::negZero()); \ + const T aNaN = T(FPBits::buildNaN(1)); \ + const T inf = T(FPBits::inf()); \ + const T negInf = T(FPBits::negInf()); #define EXPECT_FP_EQ(expected, actual) \ EXPECT_THAT( \ -- 2.7.4