From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lxmtout4.gsi.de (lxmtout4.gsi.de [140.181.3.147]) by sourceware.org (Postfix) with ESMTPS id 9BF1C386F829; Mon, 27 Apr 2020 15:09:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9BF1C386F829 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gsi.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=M.Kretz@gsi.de Received: from localhost (localhost [127.0.0.1]) by lxmtout4.gsi.de (Postfix) with ESMTP id D1468207C2EF; Mon, 27 Apr 2020 17:09:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at lxmtout4.gsi.de Received: from lxmtout4.gsi.de ([127.0.0.1]) by localhost (lxmtout4.gsi.de [127.0.0.1]) (amavisd-new, port 10024) with LMTP id iuolvQvvJyRB; Mon, 27 Apr 2020 17:09:40 +0200 (CEST) Received: from srvex3.campus.gsi.de (srvex3.campus.gsi.de [10.10.4.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by lxmtout4.gsi.de (Postfix) with ESMTPS id AD493207C2E0; Mon, 27 Apr 2020 17:09:40 +0200 (CEST) Received: from excalibur.localnet (140.181.3.12) by srvex3.campus.gsi.de (10.10.4.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Mon, 27 Apr 2020 17:09:40 +0200 From: Matthias Kretz To: CC: libstdc++ Subject: [PATCH] Let numeric_limits::is_iec559 reflect -ffast-math Date: Mon, 27 Apr 2020 17:09:34 +0200 Message-ID: <2471679.QqfNXX16uU@excalibur> Organization: GSI Helmholtzzentrum =?UTF-8?B?ZsO8cg==?= Schwerionenforschung MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart5157850.6WO6ZSibLh" Content-Transfer-Encoding: 7Bit X-Originating-IP: [140.181.3.12] X-ClientProxiedBy: SRVEX2.campus.gsi.de (10.10.4.15) To srvex3.campus.gsi.de (10.10.4.16) X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_PASS, T_SPF_HELO_PERMERROR autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Apr 2020 15:09:52 -0000 --nextPart5157850.6WO6ZSibLh Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" From: Matthias Kretz PR libstdc++/84949 * include/std/limits: Let is_iec559 reflect whether __GCC_IEC_559 says float and double support IEEE 754-2008. * testsuite/18_support/numeric_limits/is_iec559.cc: Test IEC559 mandated behavior if is_iec559 is true. * testsuite/18_support/numeric_limits/infinity.cc: Only test inf behavior if is_iec559 is true, otherwise there is no guarantee how arithmetic on inf behaves. * testsuite/18_support/numeric_limits/quiet_NaN.cc: ditto for NaN. * testsuite/18_support/numeric_limits/denorm_min-1.cc: Compile with -ffast-math. * testsuite/18_support/numeric_limits/epsilon-1.cc: ditto. * testsuite/18_support/numeric_limits/infinity-1.cc: ditto. * testsuite/18_support/numeric_limits/is_iec559-1.cc: ditto. * testsuite/18_support/numeric_limits/quiet_NaN-1.cc: ditto. --- libstdc++-v3/include/std/limits | 9 ++-- .../18_support/numeric_limits/denorm_min-1.cc | 2 + .../18_support/numeric_limits/epsilon-1.cc | 2 + .../18_support/numeric_limits/infinity-1.cc | 2 + .../18_support/numeric_limits/infinity.cc | 4 +- .../18_support/numeric_limits/is_iec559-1.cc | 2 + .../18_support/numeric_limits/is_iec559.cc | 44 ++++++++++++++----- .../18_support/numeric_limits/quiet_NaN-1.cc | 2 + .../18_support/numeric_limits/quiet_NaN.cc | 5 ++- 9 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 libstdc++-v3/testsuite/18_support/numeric_limits/ denorm_min-1.cc create mode 100644 libstdc++-v3/testsuite/18_support/numeric_limits/ epsilon-1.cc create mode 100644 libstdc++-v3/testsuite/18_support/numeric_limits/ infinity-1.cc create mode 100644 libstdc++-v3/testsuite/18_support/numeric_limits/ is_iec559-1.cc create mode 100644 libstdc++-v3/testsuite/18_support/numeric_limits/ quiet_NaN-1.cc --nextPart5157850.6WO6ZSibLh Content-Disposition: inline; filename="0002-Let-numeric_limits-is_iec559-reflect-ffast-math.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="utf-8"; name="0002-Let-numeric_limits-is_iec559-reflect-ffast-math.patch" diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index 898406f91ee..c27350c9ec4 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -1714,8 +1714,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX_CONSTEXPR float denorm_min() _GLIBCXX_USE_NOEXCEPT { return __FLT_DENORM_MIN__; } - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 - = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = __GCC_IEC_559 >= 2; static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; @@ -1789,8 +1788,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX_CONSTEXPR double denorm_min() _GLIBCXX_USE_NOEXCEPT { return __DBL_DENORM_MIN__; } - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 - = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = __GCC_IEC_559 >= 2; static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; @@ -1864,8 +1862,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX_CONSTEXPR long double denorm_min() _GLIBCXX_USE_NOEXCEPT { return __LDBL_DENORM_MIN__; } - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 - = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = __GCC_IEC_559 >= 2; static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/denorm_min-1.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/denorm_min-1.cc new file mode 100644 index 00000000000..8ff2950d77e --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/denorm_min-1.cc @@ -0,0 +1,2 @@ +// { dg-options "-ffast-math" } +#include "denorm_min.cc" diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon-1.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon-1.cc new file mode 100644 index 00000000000..34548976bea --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon-1.cc @@ -0,0 +1,2 @@ +// { dg-options "-ffast-math" } +#include "epsilon.cc" diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/infinity-1.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/infinity-1.cc new file mode 100644 index 00000000000..7ff8ea81242 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/infinity-1.cc @@ -0,0 +1,2 @@ +// { dg-options "-ffast-math" } +#include "infinity.cc" diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/infinity.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/infinity.cc index 3a5bce57c35..9585ab38216 100644 --- a/libstdc++-v3/testsuite/18_support/numeric_limits/infinity.cc +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/infinity.cc @@ -33,10 +33,10 @@ test_infinity() { bool test; - if (std::numeric_limits::has_infinity) + if (std::numeric_limits::has_infinity && std::numeric_limits::is_iec559) { T inf = std::numeric_limits::infinity(); - test = (inf + inf == inf); + test = (inf + inf == inf); } else test = true; diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559-1.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559-1.cc new file mode 100644 index 00000000000..91dd8163126 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559-1.cc @@ -0,0 +1,2 @@ +// { dg-options "-ffast-math" } +#include "is_iec559.cc" diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559.cc index d15ae5cae14..c71da192d1d 100644 --- a/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559.cc +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/is_iec559.cc @@ -27,28 +27,50 @@ #include #include +// make these values "invisible" to the optimizer so that we really test the FPU +template +T min = std::numeric_limits::min(); +template +T denorm_min = std::numeric_limits::denorm_min(); +template +T inf = std::numeric_limits::infinity(); +template +T max = std::numeric_limits::max(); +template +T qnan = std::numeric_limits::quiet_NaN(); + template void test_is_iec559() { - bool test; - if (std::numeric_limits::is_iec559) { // IEC 559 requires all of the following. - test = (std::numeric_limits::has_infinity - && std::numeric_limits::has_quiet_NaN - && std::numeric_limits::has_signaling_NaN); + VERIFY(std::numeric_limits::has_infinity && + std::numeric_limits::has_quiet_NaN && + std::numeric_limits::has_signaling_NaN); + + // Test a few random IEC559 features + VERIFY(min / 2 > T()); // min/2 is denormal, but not 0 + VERIFY(denorm_min / 3 == T()); // calculation with denormals works + T x = denorm_min; + for (int i = 1; i < std::numeric_limits::digits; ++i) + x *= 2; + VERIFY(x == min); + VERIFY(inf * 2 == inf); // infinity saturates + VERIFY(max * 2 == inf); // max*2 saturates to infinity + T inf0 = inf * T(); // NaN + VERIFY(inf0 != inf); + VERIFY(inf0 != 0); + VERIFY((inf0 == inf0) == false); + VERIFY(qnan != qnan); } else { - // If we had all of the following, why didn't we set IEC 559? - test = (!std::numeric_limits::has_infinity - || !std::numeric_limits::has_quiet_NaN - || !std::numeric_limits::has_signaling_NaN); + // We could have representations for inf, NaN, and SNaN and still not be + // IEC559 compliant. At this point, the meaning of operations on NaNs and + // infinities is unspecified. } - - VERIFY (test); } // libstdc++/8949 diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN-1.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN-1.cc new file mode 100644 index 00000000000..45bef204a65 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN-1.cc @@ -0,0 +1,2 @@ +// { dg-options "-ffast-math" } +#include "quiet_NaN.cc" diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN.cc index 97406aed2b3..b17df1cc3d7 100644 --- a/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN.cc +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/quiet_NaN.cc @@ -33,10 +33,11 @@ test_qnan() { bool test; - if (std::numeric_limits::has_quiet_NaN) + if (std::numeric_limits::has_quiet_NaN && + std::numeric_limits::is_iec559) { T nan = std::numeric_limits::quiet_NaN(); - test = (nan != nan); + test = (nan != nan); } else test = true; --nextPart5157850.6WO6ZSibLh--