[flang-commits] [flang] [llvm] [Flang] Introduce common::numeric_limits (PR #228108)
via flang-commits
flang-commits at lists.llvm.org
Fri Oct 2 00:49:48 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Michael Kruse (Meinersbur)
<details>
<summary>Changes</summary>
On platforms that do not have a native (u)int128_t, the class `Int128<IS_SIGNED>` is meant to provide it own implementation. The C++ specification allows programs to provide its own specializations of `std::numeric_limits<T>` for such user-defined types ([[namespace.std]](http://www.eel.is/c++draft//namespace.std#<!-- -->2)). However, there the combination of clang-cl using the MSVC STD poses one problem: While Clang has a int128_t native type, MSVC's STL implementation does not provide a `std::numeric_limits<T>` specialization for it (because Miscrosoft's cl.exe doesn't have 1 128 bit integer type).
A previous solution in #<!-- -->216958 was to provide our own specialization of `std::numeric_limits<__int128>` when this combination was detected. However, `__int128` is not a user-defined type and by the wording of the specification, not permitted to be provided a specialization for. A future version of the MSVC might support int128_t and provide `std::numeric_limits` overloads which would crash with our implemented. See https://github.com/llvm/llvm-project/pull/216958#discussion_r4135150943
This PR introduces its own class `Fortran::common::numeric_limits` which knows about Flang's custom `Int128`. Any Flang code handling native integers should preferable use this version to be prepared to handle `INTEGER(16)` types.
This PR replaces all uses of `std::numeric_limits` that are template-dependent with `common::numeric_limits`. I did not replace uses that have a fixed templated type such as `std::numeric_limits<int>`.
---
Patch is 26.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/228108.diff
16 Files Affected:
- (modified) flang-rt/include/flang-rt/runtime/numeric-templates.h (+7-16)
- (modified) flang-rt/lib/quadmath/math-entries.h (+2-2)
- (modified) flang-rt/lib/runtime/command.cpp (+1-1)
- (modified) flang-rt/lib/runtime/complex-powi.cpp (+2-2)
- (modified) flang-rt/lib/runtime/namelist.cpp (+1-1)
- (modified) flang-rt/lib/runtime/numeric.cpp (+4-4)
- (modified) flang-rt/lib/runtime/time-intrinsic.cpp (+2-2)
- (modified) flang-rt/lib/runtime/tools.cpp (+1-1)
- (modified) flang-rt/lib/runtime/transformational.cpp (+1-1)
- (modified) flang-rt/unittests/Runtime/ExternalIOTest.cpp (+7-4)
- (modified) flang-rt/unittests/Runtime/Numeric.cpp (+47-49)
- (modified) flang-rt/unittests/Runtime/Transformational.cpp (+4-3)
- (modified) flang/include/flang/Common/erfc-scaled.h (+3-3)
- (modified) flang/include/flang/Common/uint128.h (+82)
- (modified) flang/lib/Decimal/big-radix-floating-point.h (+2-2)
- (modified) flang/lib/Evaluate/constant.cpp (+1-1)
``````````diff
diff --git a/flang-rt/include/flang-rt/runtime/numeric-templates.h b/flang-rt/include/flang-rt/runtime/numeric-templates.h
index e41c7f079e921..7733a32c98f59 100644
--- a/flang-rt/include/flang-rt/runtime/numeric-templates.h
+++ b/flang-rt/include/flang-rt/runtime/numeric-templates.h
@@ -35,17 +35,8 @@ template <TypeCategory CAT, int KIND, bool IS_MAXVAL, typename Enable = void>
struct MaxOrMinIdentity {
using Type = CppTypeFor<CAT, KIND>;
static constexpr RT_API_ATTRS Type Value() {
- return IS_MAXVAL ? std::numeric_limits<Type>::lowest()
- : std::numeric_limits<Type>::max();
- }
-};
-
-// std::numeric_limits<> may not know int128_t
-template <bool IS_MAXVAL>
-struct MaxOrMinIdentity<TypeCategory::Integer, 16, IS_MAXVAL> {
- using Type = CppTypeFor<TypeCategory::Integer, 16>;
- static constexpr RT_API_ATTRS Type Value() {
- return IS_MAXVAL ? Type{1} << 127 : ~Type{0} >> 1;
+ return IS_MAXVAL ? common::numeric_limits<Type>::lowest()
+ : common::numeric_limits<Type>::max();
}
};
@@ -90,7 +81,7 @@ struct MaxOrMinIdentity<TypeCategory::Real, 16, IS_MAXVAL,
// Minimum finite representable value.
// For floating-point types, returns minimum positive normalized value.
template <int PREC, typename T> struct MinValue {
- static RT_API_ATTRS T get() { return std::numeric_limits<T>::min(); }
+ static RT_API_ATTRS T get() { return common::numeric_limits<T>::min(); }
};
template <typename T> struct MinValue<11, T> {
// TINY(0._2)
@@ -160,7 +151,7 @@ template <typename T> struct LDEXPTy {
template <typename T> struct MAXTy {
static constexpr RT_API_ATTRS T compute() {
- return std::numeric_limits<T>::max();
+ return common::numeric_limits<T>::max();
}
};
@@ -178,7 +169,7 @@ template <int PREC, typename T> struct MINTy {
template <typename T> struct QNANTy {
static constexpr RT_API_ATTRS T compute() {
- return std::numeric_limits<T>::quiet_NaN();
+ return common::numeric_limits<T>::quiet_NaN();
}
};
@@ -224,8 +215,8 @@ template <typename T> inline RT_API_ATTRS T SetExponent(T x, std::int64_t p) {
int expo{ILOGBTy<T>::compute(x) + 1};
auto ip{static_cast<int>(p - expo)};
if (ip != p - expo) {
- ip = p < 0 ? std::numeric_limits<int>::min()
- : std::numeric_limits<int>::max();
+ ip = p < 0 ? common::numeric_limits<int>::min()
+ : common::numeric_limits<int>::max();
}
return LDEXPTy<T>::compute(x, ip); // x*2**(p-e)
}
diff --git a/flang-rt/lib/quadmath/math-entries.h b/flang-rt/lib/quadmath/math-entries.h
index 91ad80c8197f4..75cfa7f2041fe 100644
--- a/flang-rt/lib/quadmath/math-entries.h
+++ b/flang-rt/lib/quadmath/math-entries.h
@@ -220,9 +220,9 @@ DEFINE_SIMPLE_ALIAS(Yn, ynl)
// Use numeric_limits to produce infinity of the right type.
#define F128_RT_INFINITY \
- (std::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::infinity())
+ (common::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::infinity())
#define F128_RT_QNAN \
- (std::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::quiet_NaN())
+ (common::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::quiet_NaN())
#elif HAS_LIBMF128
// We can use __float128 versions of libm functions.
// __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined
diff --git a/flang-rt/lib/runtime/command.cpp b/flang-rt/lib/runtime/command.cpp
index f0f4e8bf64e99..66e1fc787dfa0 100644
--- a/flang-rt/lib/runtime/command.cpp
+++ b/flang-rt/lib/runtime/command.cpp
@@ -87,7 +87,7 @@ template <int KIND> struct FitsInIntegerKind {
if constexpr (KIND >= 8) {
return true;
} else {
- return value <= std::numeric_limits<Fortran::runtime::CppTypeFor<
+ return value <= common::numeric_limits<Fortran::runtime::CppTypeFor<
Fortran::common::TypeCategory::Integer, KIND>>::max();
}
}
diff --git a/flang-rt/lib/runtime/complex-powi.cpp b/flang-rt/lib/runtime/complex-powi.cpp
index a561d114591cf..61b6f4b265978 100644
--- a/flang-rt/lib/runtime/complex-powi.cpp
+++ b/flang-rt/lib/runtime/complex-powi.cpp
@@ -24,10 +24,10 @@ template <typename C, typename I> C tgpowi(C base, I exp) {
}
bool invertResult{exp < 0};
- bool isMin{exp == std::numeric_limits<I>::min()};
+ bool isMin{exp == common::numeric_limits<I>::min()};
if (isMin) {
- exp = std::numeric_limits<I>::max();
+ exp = common::numeric_limits<I>::max();
}
if (exp < 0) {
diff --git a/flang-rt/lib/runtime/namelist.cpp b/flang-rt/lib/runtime/namelist.cpp
index 231b1705a4a2f..2f248208b88b5 100644
--- a/flang-rt/lib/runtime/namelist.cpp
+++ b/flang-rt/lib/runtime/namelist.cpp
@@ -138,7 +138,7 @@ static RT_API_ATTRS common::optional<SubscriptValue> GetSubscriptValue(
bool overflow{false};
while (ch && *ch >= '0' && *ch <= '9') {
SubscriptValue was{value.value_or(0)};
- overflow |= was >= std::numeric_limits<SubscriptValue>::max() / 10;
+ overflow |= was >= common::numeric_limits<SubscriptValue>::max() / 10;
value = 10 * was + *ch - '0';
io.HandleRelativePosition(byteCount);
ch = io.GetCurrentChar(byteCount);
diff --git a/flang-rt/lib/runtime/numeric.cpp b/flang-rt/lib/runtime/numeric.cpp
index 78f148dbc5d8c..835897680d6f1 100644
--- a/flang-rt/lib/runtime/numeric.cpp
+++ b/flang-rt/lib/runtime/numeric.cpp
@@ -190,9 +190,9 @@ inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(
template <int PREC, typename T>
inline RT_API_ATTRS T Nearest(T x, bool positive) {
if (positive) {
- return std::nextafter(x, std::numeric_limits<T>::infinity());
+ return std::nextafter(x, common::numeric_limits<T>::infinity());
} else {
- return std::nextafter(x, -std::numeric_limits<T>::infinity());
+ return std::nextafter(x, -common::numeric_limits<T>::infinity());
}
}
@@ -202,9 +202,9 @@ RT_API_ATTRS BTy FPowI(BTy base, ETy exp) {
if (exp == ETy{0})
return BTy{1};
bool isNegativePower{exp < ETy{0}};
- bool isMinPower{exp == std::numeric_limits<ETy>::min()};
+ bool isMinPower{exp == common::numeric_limits<ETy>::min()};
if (isMinPower) {
- exp = std::numeric_limits<ETy>::max();
+ exp = common::numeric_limits<ETy>::max();
} else if (isNegativePower) {
exp = -exp;
}
diff --git a/flang-rt/lib/runtime/time-intrinsic.cpp b/flang-rt/lib/runtime/time-intrinsic.cpp
index 89e199a1bc79d..d78f5990d5ce7 100644
--- a/flang-rt/lib/runtime/time-intrinsic.cpp
+++ b/flang-rt/lib/runtime/time-intrinsic.cpp
@@ -270,7 +270,7 @@ template <int KIND> struct StoreNegativeHugeAt {
const Fortran::runtime::Descriptor &result, std::size_t at) const {
*result.ZeroBasedIndexedElement<Fortran::runtime::CppTypeFor<
Fortran::common::TypeCategory::Integer, KIND>>(at) =
- -std::numeric_limits<Fortran::runtime::CppTypeFor<
+ -common::numeric_limits<Fortran::runtime::CppTypeFor<
Fortran::common::TypeCategory::Integer, KIND>>::max();
}
};
@@ -383,7 +383,7 @@ GetGmtOffset(const TM &tm, fallback_implementation) {
// tm.tm_gmtoff is not available, there may be platform dependent alternatives
// (such as using timezone from <time.h> when available), but so far just
// return -HUGE to report that this information is not available.
- const auto negHuge{-std::numeric_limits<Fortran::runtime::CppTypeFor<
+ const auto negHuge{-common::numeric_limits<Fortran::runtime::CppTypeFor<
Fortran::common::TypeCategory::Integer, KIND>>::max()};
#if defined _AIX
bool err{false};
diff --git a/flang-rt/lib/runtime/tools.cpp b/flang-rt/lib/runtime/tools.cpp
index 8ef7106f6a7c5..45a56fd7d71e7 100644
--- a/flang-rt/lib/runtime/tools.cpp
+++ b/flang-rt/lib/runtime/tools.cpp
@@ -330,7 +330,7 @@ template <int KIND> struct FitsInIntegerKind {
return true;
} else {
return value <=
- std::numeric_limits<
+ common::numeric_limits<
CppTypeFor<Fortran::common::TypeCategory::Integer, KIND>>::max();
}
}
diff --git a/flang-rt/lib/runtime/transformational.cpp b/flang-rt/lib/runtime/transformational.cpp
index 395721ca2b9bd..4e6f24ed79e8c 100644
--- a/flang-rt/lib/runtime/transformational.cpp
+++ b/flang-rt/lib/runtime/transformational.cpp
@@ -320,7 +320,7 @@ static inline RT_API_ATTRS void DoBesselYnX0(Descriptor &result, int32_t n1,
for (int j{1}; j <= n2 - n1 + 1; ++j) {
at[0] = j;
*result.Element<CppTypeFor<CAT, KIND>>(at) =
- -std::numeric_limits<CppTypeFor<CAT, KIND>>::infinity();
+ -common::numeric_limits<CppTypeFor<CAT, KIND>>::infinity();
}
}
diff --git a/flang-rt/unittests/Runtime/ExternalIOTest.cpp b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
index 1fe3b08126c5d..cf469e5b34d40 100644
--- a/flang-rt/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
@@ -978,12 +978,15 @@ TEST(ExternalIOTests, TestUCS) {
}
TEST(ExternalIOTests, BigUnitNumbers) {
- if (std::numeric_limits<ExternalUnit>::max() <
- std::numeric_limits<std::int64_t>::max()) {
- std::int64_t unit64Ok = std::numeric_limits<ExternalUnit>::max();
+ if (Fortran::common::numeric_limits<ExternalUnit>::max() <
+ Fortran::common::numeric_limits<std::int64_t>::max()) {
+ std::int64_t unit64Ok =
+ Fortran::common::numeric_limits<ExternalUnit>::max();
std::int64_t unit64Bad = unit64Ok + 1;
std::int64_t unit64Bad2 =
- static_cast<std::int64_t>(std::numeric_limits<ExternalUnit>::min()) - 1;
+ static_cast<std::int64_t>(
+ Fortran::common::numeric_limits<ExternalUnit>::min()) -
+ 1;
EXPECT_EQ(IONAME(CheckUnitNumberInRange64)(unit64Ok, true), IostatOk);
EXPECT_EQ(IONAME(CheckUnitNumberInRange64)(unit64Ok, false), IostatOk);
EXPECT_EQ(
diff --git a/flang-rt/unittests/Runtime/Numeric.cpp b/flang-rt/unittests/Runtime/Numeric.cpp
index 4baad3fc9ad0e..1c8ccc4262668 100644
--- a/flang-rt/unittests/Runtime/Numeric.cpp
+++ b/flang-rt/unittests/Runtime/Numeric.cpp
@@ -13,6 +13,7 @@
#include <limits>
using namespace Fortran::runtime;
+using Fortran::common::numeric_limits;
using Fortran::common::TypeCategory;
template <int KIND> using Int = CppTypeFor<TypeCategory::Integer, KIND>;
template <int KIND> using Real = CppTypeFor<TypeCategory::Real, KIND>;
@@ -43,25 +44,25 @@ TEST(Numeric, Exponent) {
EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
- EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
- std::numeric_limits<Int<8>>::max());
- EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
- std::numeric_limits<Int<8>>::max());
+ EXPECT_EQ(RTNAME(Exponent8_8)(numeric_limits<Real<8>>::infinity()),
+ numeric_limits<Int<8>>::max());
+ EXPECT_EQ(RTNAME(Exponent8_8)(numeric_limits<Real<8>>::quiet_NaN()),
+ numeric_limits<Int<8>>::max());
}
TEST(Numeric, Fraction) {
EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0);
EXPECT_EQ(RTNAME(Fraction8)(Real<8>{3.0}), 0.75);
EXPECT_TRUE(
- std::isnan(RTNAME(Fraction4)(std::numeric_limits<Real<4>>::infinity())));
+ std::isnan(RTNAME(Fraction4)(numeric_limits<Real<4>>::infinity())));
EXPECT_TRUE(
- std::isnan(RTNAME(Fraction8)(std::numeric_limits<Real<8>>::quiet_NaN())));
+ std::isnan(RTNAME(Fraction8)(numeric_limits<Real<8>>::quiet_NaN())));
}
TEST(Numeric, IsNaN) {
EXPECT_FALSE(RTNAME(IsNaN4)(Real<4>{0}));
- EXPECT_FALSE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::infinity()));
- EXPECT_TRUE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::quiet_NaN()));
+ EXPECT_FALSE(RTNAME(IsNaN8)(numeric_limits<Real<8>>::infinity()));
+ EXPECT_TRUE(RTNAME(IsNaN8)(numeric_limits<Real<8>>::quiet_NaN()));
}
TEST(Numeric, Mod) {
@@ -74,28 +75,26 @@ TEST(Numeric, Mod) {
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{8.0}, Real<8>(-5.0)), 3.0);
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
EXPECT_EQ(
- RTNAME(ModReal4)(Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity()),
- 0.5);
+ RTNAME(ModReal4)(Real<4>{0.5}, numeric_limits<Real<4>>::infinity()), 0.5);
EXPECT_EQ(
- RTNAME(ModReal4)(Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity()),
+ RTNAME(ModReal4)(Real<4>{-0.5}, numeric_limits<Real<4>>::infinity()),
-0.5);
EXPECT_EQ(
- RTNAME(ModReal4)(Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity()),
+ RTNAME(ModReal4)(Real<4>{0.5}, -numeric_limits<Real<4>>::infinity()),
0.5);
- EXPECT_EQ(RTNAME(ModReal4)(
- Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity()),
+ EXPECT_EQ(
+ RTNAME(ModReal4)(Real<4>{-0.5}, -numeric_limits<Real<4>>::infinity()),
-0.5);
EXPECT_EQ(
- RTNAME(ModReal8)(Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity()),
- 0.5);
+ RTNAME(ModReal8)(Real<8>{0.5}, numeric_limits<Real<8>>::infinity()), 0.5);
EXPECT_EQ(
- RTNAME(ModReal8)(Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity()),
+ RTNAME(ModReal8)(Real<8>{-0.5}, numeric_limits<Real<8>>::infinity()),
-0.5);
EXPECT_EQ(
- RTNAME(ModReal8)(Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity()),
+ RTNAME(ModReal8)(Real<8>{0.5}, -numeric_limits<Real<8>>::infinity()),
0.5);
- EXPECT_EQ(RTNAME(ModReal8)(
- Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity()),
+ EXPECT_EQ(
+ RTNAME(ModReal8)(Real<8>{-0.5}, -numeric_limits<Real<8>>::infinity()),
-0.5);
}
@@ -109,22 +108,22 @@ TEST(Numeric, Modulo) {
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{8.0}, Real<8>(-5.0)), -2.0);
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
// MODULO(x, INF) == NaN
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal4)(Real<4>{0.5}, numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal4)(Real<4>{-0.5}, numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal4)(Real<4>{0.5}, -numeric_limits<Real<4>>::infinity())));
EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
- Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
- Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
- Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
- Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
- Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
- Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity())));
- EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
- Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity())));
+ Real<4>{-0.5}, -numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal8)(Real<8>{-0.5}, numeric_limits<Real<8>>::infinity())));
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal8)(Real<8>{0.5}, numeric_limits<Real<8>>::infinity())));
EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
- Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity())));
+ Real<8>{-0.5}, -numeric_limits<Real<8>>::infinity())));
+ EXPECT_TRUE(std::isnan(
+ RTNAME(ModuloReal8)(Real<8>{0.5}, -numeric_limits<Real<8>>::infinity())));
// MODULO(x, y) for integer values of x and y with 0 remainder.
EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(1.0)), 0.0);
EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(-1.0)), -0.0);
@@ -134,7 +133,7 @@ TEST(Numeric, Modulo) {
TEST(Numeric, Nearest) {
EXPECT_EQ(RTNAME(Nearest4)(Real<4>{0}, true),
- std::numeric_limits<Real<4>>::denorm_min());
+ numeric_limits<Real<4>>::denorm_min());
EXPECT_EQ(RTNAME(Nearest4)(Real<4>{3.0}, true),
Real<4>{3.0} + std::ldexp(Real<4>{1.0}, -22));
EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true),
@@ -156,9 +155,9 @@ TEST(Numeric, RRSpacing) {
EXPECT_EQ(RTNAME(RRSpacing4)(Real<4>{-3.0}), 0.75 * (1 << 24));
EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{-3.0}), 0.75 * (std::int64_t{1} << 53));
EXPECT_TRUE(
- std::isnan(RTNAME(RRSpacing4)(std::numeric_limits<Real<4>>::infinity())));
- EXPECT_TRUE(std::isnan(
- RTNAME(RRSpacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
+ std::isnan(RTNAME(RRSpacing4)(numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(
+ std::isnan(RTNAME(RRSpacing8)(numeric_limits<Real<8>>::quiet_NaN())));
}
TEST(Numeric, Scale) {
@@ -167,9 +166,9 @@ TEST(Numeric, Scale) {
EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 1), 2.0);
EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, -1), 0.5);
EXPECT_TRUE(
- std::isinf(RTNAME(Scale4)(std::numeric_limits<Real<4>>::infinity(), 1)));
+ std::isinf(RTNAME(Scale4)(numeric_limits<Real<4>>::infinity(), 1)));
EXPECT_TRUE(
- std::isnan(RTNAME(Scale8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
+ std::isnan(RTNAME(Scale8)(numeric_limits<Real<8>>::quiet_NaN(), 1)));
}
TEST(Numeric, SetExponent) {
@@ -179,10 +178,10 @@ TEST(Numeric, SetExponent) {
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 0), 0.5);
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 1), 1.0);
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, -1), 0.25);
+ EXPECT_TRUE(
+ std::isnan(RTNAME(SetExponent4)(numeric_limits<Real<4>>::infinity(), 1)));
EXPECT_TRUE(std::isnan(
- RTNAME(SetExponent4)(std::numeric_limits<Real<4>>::infinity(), 1)));
- EXPECT_TRUE(std::isnan(
- RTNAME(SetExponent8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
+ RTNAME(SetExponent8)(numeric_limits<Real<8>>::quiet_NaN(), 1)));
}
TEST(Numeric, SelectedIntKind) {
@@ -253,17 +252,16 @@ TEST(Numeric, SelectedRealKind) {
}
TEST(Numeric, Spacing) {
- EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min());
+ EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), numeric_limits<Real<8>>::min());
EXPECT_EQ(RTNAME(Spacing4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -22));
EXPECT_TRUE(
- std::isnan(RTNAME(Spacing4)(std::numeric_limits<Real<4>>::infinity())));
+ std::isnan(RTNAME(Spacing4)(numeric_limits<Real<4>>::infinity())));
EXPECT_TRUE(
- std::isnan(RTNAME(Spacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
+ std::isnan(RTNAME(Spacing8)(numeric_limits<Real<8>>::quiet_NaN())));
EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -9));
EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{0.0}), Real<4>{0.00006103515625E-04});
EXPECT_EQ(RTNAME(Spacing3By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -6));
- EXPECT_EQ(
- RTNAME(Spacing3By4)(Real<4>{0.0}), std::numeric_limits<Real<4>>::min());
+ EXPECT_EQ(RTNAME(Spacing3By4)(Real<4>{0.0}), numeric_limits<Real<4>>::min());
}
TEST(Numeric, FPowI) {
@@ -334,7 +332,7 @@ TEST(Numeric, FPowI) {
double result;
*reinterpret_cast<std::uint64_t *>(&result) = 4607182414505051137ULL;
EXPECT_TRUE(std::abs(RTNAME(FPow8i)(Real<8>{base},
- Int<4>{std::numeric_limits<Int<4>>::min()}) -
+ Int<4>{numeric_limits<Int<4>>::min()}) -
Real<8>{result}) < 0.00000000001);
// (0x3FF0000000000001 ** 4294967296ULL) ~ 0x3FF00001000007FF
diff --git a/flang-rt/unittests/Runtime/Transformational.cpp b/flang-rt/unittests/Runtime/Transformational.cpp
index e61f5a64fcdb0..b883aefc1f85d 100644
--- a/flang-rt/unittests/Runtime/Transformational.cpp
+++ b/flang-rt/unittests/Runtime/Transformational.cpp
@@ -11,6 +11,7 @@
#include "gtest/gtest.h"
#include "flang-rt/runtime/type-code.h"
#include "flang/Common/float128.h"
+#include "flang/Common/uint128.h"
#include <vector>
using namespace Fortran::runtime;
@@ -26,8 +27,8 @@ using BesselX0FuncType =
std::function<void(Descriptor &, int32_t, int32_t, const char *, int)>;
template <int KIND>
-constexpr CppTypeFor<TypeCategory::Real, KIND>
- besselEpsilon = CppTypeFor<TypeCategory::Real, KIND>(1e-4);
+constexpr CppTypeFor<TypeCategory::Real, KIND> besselEpsilon =
+ CppTypeFor<TypeCategory::Real, KIND>(1e-4);
template <int KIND>
static void testBesselJn(BesselFuncType<KIND> rtFunc, int32_t n1, int32_t n2,
@@ -176,7 +177,7 @@ static void testBesselYnX0(
EXPECT_EQ(
(*result.ZeroBasedIndexedElement<CppTypeFo...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/228108
More information about the flang-commits
mailing list