public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-6291] libstdc++: Disable floating-point std::to_chars on unsupported targets
@ 2020-12-21 20:16 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2020-12-21 20:16 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:6a31d47e271d066ea85b3716f7b77f18e6b55242

commit r11-6291-g6a31d47e271d066ea85b3716f7b77f18e6b55242
Author: Patrick Palka <ppalka@redhat.com>
Date:   Mon Dec 21 15:15:36 2020 -0500

    libstdc++: Disable floating-point std::to_chars on unsupported targets
    
    This patch conditionally disables the floating-point std::to_chars
    implementation on targets whose float and double aren't IEEE binary32
    and binary64, until a proper fallback can be added for such targets.
    This fixes a bootstrap failure on non-IEEE-754 FP targets such as
    vax-netbsdelf.
    
    The new preprocessor tests in c++config that detect the binary32 and
    binary64 formats were copied from gcc/testsuite/gcc.dg/float-exact-1.c.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/c++config (_GLIBCXX_FLOAT_IS_IEEE_BINARY_32):
            Define this macro.
            (_GLIBCXX_DOUBLE_IS_IEEE_BINARY_64): Likewise.
            * include/std/charconv (to_chars): Use these macros to
            conditionally hide the overloads for floating-point types.
            * src/c++17/floating_to_chars.cc: Use the macros to
            conditionally disable this file.
            (floating_type_traits<float>): Remove redundant static assert.
            (floating_type_traits<double>): Likewise.
            * testsuite/20_util/to_chars/double.cc: Run this test only on
            ieee-floats effective targets.
            * testsuite/20_util/to_chars/float.cc: Likewise.
            * testsuite/20_util/to_chars/long_double.cc: Likewise.
            * testsuite/lib/libstdc++.exp
            (check_effective_target_ieee-floats): Define new proc for
            detecting whether float and double have the IEEE binary32 and
            binary64 formats.

Diff:
---
 libstdc++-v3/include/bits/c++config                    | 14 ++++++++++++++
 libstdc++-v3/include/std/charconv                      |  2 ++
 libstdc++-v3/src/c++17/floating_to_chars.cc            | 10 ++++++----
 libstdc++-v3/testsuite/20_util/to_chars/double.cc      |  1 +
 libstdc++-v3/testsuite/20_util/to_chars/float.cc       |  1 +
 libstdc++-v3/testsuite/20_util/to_chars/long_double.cc |  1 +
 libstdc++-v3/testsuite/lib/libstdc++.exp               |  8 ++++++++
 7 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 8cce88aa87b..be0961a9d9e 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -688,6 +688,20 @@ namespace std
 # endif
 #endif
 
+// Define if float has the IEEE binary32 format.
+#if __FLT_MANT_DIG__ == 24 \
+  && __FLT_MIN_EXP__ == -125 \
+  && __FLT_MAX_EXP__ == 128
+# define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1
+#endif
+
+// Define if double has the IEEE binary64 format.
+#if __DBL_MANT_DIG__ == 53 \
+  && __DBL_MIN_EXP__ == -1021 \
+  && __DBL_MAX_EXP__ == 1024
+# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
+#endif
+
 #ifdef __has_builtin
 # ifdef __is_identifier
 // Intel and older Clang require !__is_identifier for some built-ins:
diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
index b57b0a16db2..c6e80693aad 100644
--- a/libstdc++-v3/include/std/charconv
+++ b/libstdc++-v3/include/std/charconv
@@ -702,6 +702,7 @@ namespace __detail
 	     chars_format __fmt = chars_format::general) noexcept;
 #endif
 
+#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
   // Floating-point std::to_chars
 
   // Overloads for float.
@@ -725,6 +726,7 @@ namespace __detail
 			   chars_format __fmt) noexcept;
   to_chars_result to_chars(char* __first, char* __last, long double __value,
 			   chars_format __fmt, int __precision) noexcept;
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
diff --git a/libstdc++-v3/src/c++17/floating_to_chars.cc b/libstdc++-v3/src/c++17/floating_to_chars.cc
index b7c31c746cc..6e154365aee 100644
--- a/libstdc++-v3/src/c++17/floating_to_chars.cc
+++ b/libstdc++-v3/src/c++17/floating_to_chars.cc
@@ -40,6 +40,10 @@
 #include <string_view>
 #include <type_traits>
 
+// This implementation crucially assumes float/double have the
+// IEEE binary32/binary64 formats.
+#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
+
 // Determine the binary format of 'long double'.
 
 // We support the binary64, float80 (i.e. x86 80-bit extended precision),
@@ -109,8 +113,6 @@ namespace
   template<>
     struct floating_type_traits<float>
     {
-      // We (and Ryu) assume float has the IEEE binary32 format.
-      static_assert(__FLT_MANT_DIG__ == 24);
       static constexpr int mantissa_bits = 23;
       static constexpr int exponent_bits = 8;
       static constexpr bool has_implicit_leading_bit = true;
@@ -124,8 +126,6 @@ namespace
   template<>
     struct floating_type_traits<double>
     {
-      // We (and Ryu) assume double has the IEEE binary64 format.
-      static_assert(__DBL_MANT_DIG__ == 53);
       static constexpr int mantissa_bits = 52;
       static constexpr int exponent_bits = 11;
       static constexpr bool has_implicit_leading_bit = true;
@@ -1565,3 +1565,5 @@ _ZSt8to_charsPcS_eSt12chars_formati(char* first, char* last, double value,
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
+
+#endif // _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/double.cc b/libstdc++-v3/testsuite/20_util/to_chars/double.cc
index 9d1f37d3026..bb6f74424ed 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/double.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/double.cc
@@ -32,6 +32,7 @@
 // DEALINGS IN THE SOFTWARE.
 
 // { dg-do run { target c++17 } }
+// { dg-require-effective-target ieee-floats }
 
 #include <charconv>
 
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/float.cc b/libstdc++-v3/testsuite/20_util/to_chars/float.cc
index b8901063ea0..0c8dd4f66df 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/float.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/float.cc
@@ -32,6 +32,7 @@
 // DEALINGS IN THE SOFTWARE.
 
 // { dg-do run { target c++17 } }
+// { dg-require-effective-target ieee-floats }
 
 #include <charconv>
 
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
index 12ac8ae7822..f89daa2c665 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
@@ -19,6 +19,7 @@
 // hexadecimal floating-point literals.
 // { dg-do run { target c++17 } }
 // { dg-xfail-run-if "Ryu needs __int128" { large_long_double && { ! int128 } } }
+// { dg-require-effective-target ieee-floats }
 
 #include <charconv>
 
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index b7d7b906de4..6e5634ef1d2 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1323,6 +1323,14 @@ proc check_effective_target_futex { } {
     }]
 }
 
+# Return 1 if float and double have the IEEE binary32 and binary64 formats.
+proc check_effective_target_ieee-floats { } {
+    return [check_v3_target_prop_cached et_ieee_floats {
+	set cond "_GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64"
+	return [v3_check_preprocessor_condition ieee_floats $cond]
+    }]
+}
+
 set additional_prunes ""
 
 if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-12-21 20:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-21 20:16 [gcc r11-6291] libstdc++: Disable floating-point std::to_chars on unsupported targets Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).