[flang-commits] [flang] 8985cfd - [flang][runtime] Fixed identity value for REAL(16) == __float128.
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Wed Sep 28 10:13:22 PDT 2022
Author: Slava Zakharin
Date: 2022-09-28T10:11:37-07:00
New Revision: 8985cfd93980a1d7d92699bfefce34e7bf5887fb
URL: https://github.com/llvm/llvm-project/commit/8985cfd93980a1d7d92699bfefce34e7bf5887fb
DIFF: https://github.com/llvm/llvm-project/commit/8985cfd93980a1d7d92699bfefce34e7bf5887fb.diff
LOG: [flang][runtime] Fixed identity value for REAL(16) == __float128.
std::numeric_limits<__float128>::max/lowest return 0.0, so recreate
value of FLT128_MAX ourselves to avoid using quadmath.h's FLT128_MAX
that is currently causes warnings with GCC -Wpedantic.
Differential Revision: https://reviews.llvm.org/D134496
Added:
Modified:
flang/runtime/extrema.cpp
flang/unittests/Runtime/Reduction.cpp
Removed:
################################################################################
diff --git a/flang/runtime/extrema.cpp b/flang/runtime/extrema.cpp
index f96a91c059512..a1413b4734446 100644
--- a/flang/runtime/extrema.cpp
+++ b/flang/runtime/extrema.cpp
@@ -301,7 +301,8 @@ void RTNAME(MinlocDim)(Descriptor &result, const Descriptor &x, int kind,
// MAXVAL and MINVAL
-template <TypeCategory CAT, int KIND, bool IS_MAXVAL> struct MaxOrMinIdentity {
+template <TypeCategory CAT, int KIND, bool IS_MAXVAL, typename Enable = void>
+struct MaxOrMinIdentity {
using Type = CppTypeFor<CAT, KIND>;
static constexpr Type Value() {
return IS_MAXVAL ? std::numeric_limits<Type>::lowest()
@@ -318,6 +319,44 @@ struct MaxOrMinIdentity<TypeCategory::Integer, 16, IS_MAXVAL> {
}
};
+#if HAS_FLOAT128
+// std::numeric_limits<> may not support __float128.
+//
+// Usage of GCC quadmath.h's FLT128_MAX is complicated by the fact that
+// even GCC complains about 'Q' literal suffix under -Wpedantic.
+// We just recreate FLT128_MAX ourselves.
+//
+// This specialization must engage only when
+// CppTypeFor<TypeCategory::Real, 16> is __float128.
+template <bool IS_MAXVAL>
+struct MaxOrMinIdentity<TypeCategory::Real, 16, IS_MAXVAL,
+ typename std::enable_if_t<
+ std::is_same_v<CppTypeFor<TypeCategory::Real, 16>, __float128>>> {
+ using Type = __float128;
+ static Type Value() {
+ // Create a buffer to store binary representation of __float128 constant.
+ constexpr std::size_t alignment =
+ std::max(alignof(Type), alignof(std::uint64_t));
+ alignas(alignment) char data[sizeof(Type)];
+
+ // First, verify that our interpretation of __float128 format is correct,
+ // e.g. by checking at least one known constant.
+ *reinterpret_cast<Type *>(data) = Type(1.0);
+ if (*reinterpret_cast<std::uint64_t *>(data) != 0 ||
+ *(reinterpret_cast<std::uint64_t *>(data) + 1) != 0x3FFF000000000000) {
+ Terminator terminator{__FILE__, __LINE__};
+ terminator.Crash("not yet implemented: no full support for __float128");
+ }
+
+ // Recreate FLT128_MAX.
+ *reinterpret_cast<std::uint64_t *>(data) = 0xFFFFFFFFFFFFFFFF;
+ *(reinterpret_cast<std::uint64_t *>(data) + 1) = 0x7FFEFFFFFFFFFFFF;
+ Type max = *reinterpret_cast<Type *>(data);
+ return IS_MAXVAL ? -max : max;
+ }
+};
+#endif // HAS_FLOAT128
+
template <TypeCategory CAT, int KIND, bool IS_MAXVAL>
class NumericExtremumAccumulator {
public:
diff --git a/flang/unittests/Runtime/Reduction.cpp b/flang/unittests/Runtime/Reduction.cpp
index a9207521dfe2d..6f499b7203438 100644
--- a/flang/unittests/Runtime/Reduction.cpp
+++ b/flang/unittests/Runtime/Reduction.cpp
@@ -616,3 +616,20 @@ TEST(Reductions, DotProduct) {
EXPECT_FALSE(RTNAME(DotProductLogical)(
*logicalVector2, *logicalVector1, __FILE__, __LINE__));
}
+
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+TEST(Reductions, ExtremaReal16) {
+ // The identity value for Min/Maxval for REAL(16) was mistakenly
+ // set to 0.0.
+ using ElemType = CppTypeFor<TypeCategory::Real, 16>;
+ std::vector<int> shape{3};
+ // 1.0 2.0 3.0
+ std::vector<ElemType> rawMinData{1.0, 2.0, 3.0};
+ auto minArray{MakeArray<TypeCategory::Real, 16>(shape, rawMinData)};
+ EXPECT_EQ(RTNAME(MinvalReal16)(*minArray, __FILE__, __LINE__), 1.0);
+ // -1.0 -2.0 -3.0
+ std::vector<ElemType> rawMaxData{-1.0, -2.0, -3.0};
+ auto maxArray{MakeArray<TypeCategory::Real, 16>(shape, rawMaxData)};
+ EXPECT_EQ(RTNAME(MaxvalReal16)(*maxArray, __FILE__, __LINE__), -1.0);
+}
+#endif // LDBL_MANT_DIG == 113 || HAS_FLOAT128
More information about the flang-commits
mailing list