diff --git a/libcxx/include/limits b/libcxx/include/limits --- a/libcxx/include/limits +++ b/libcxx/include/limits @@ -339,7 +339,11 @@ static _LIBCPP_CONSTEXPR const bool is_modulo = false; static _LIBCPP_CONSTEXPR const bool traps = false; +#ifdef __arm__ + static _LIBCPP_CONSTEXPR const bool tinyness_before = true; +#else static _LIBCPP_CONSTEXPR const bool tinyness_before = false; +#endif static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; }; @@ -385,7 +389,11 @@ static _LIBCPP_CONSTEXPR const bool is_modulo = false; static _LIBCPP_CONSTEXPR const bool traps = false; +#ifdef __arm__ + static _LIBCPP_CONSTEXPR const bool tinyness_before = true; +#else static _LIBCPP_CONSTEXPR const bool tinyness_before = false; +#endif static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; }; @@ -435,7 +443,11 @@ static _LIBCPP_CONSTEXPR const bool is_modulo = false; static _LIBCPP_CONSTEXPR const bool traps = false; +#ifdef __arm__ + static _LIBCPP_CONSTEXPR const bool tinyness_before = true; +#else static _LIBCPP_CONSTEXPR const bool tinyness_before = false; +#endif static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; }; diff --git a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp --- a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp @@ -11,6 +11,9 @@ // tinyness_before #include +#include +#include +#include #include "test_macros.h" @@ -22,6 +25,19 @@ static_assert(std::numeric_limits::tinyness_before == expected, "tinyness_before test 2"); static_assert(std::numeric_limits::tinyness_before == expected, "tinyness_before test 3"); static_assert(std::numeric_limits::tinyness_before == expected, "tinyness_before test 4"); + + if (std::is_floating_point::value) { + T denorm_max = std::nextafter(std::numeric_limits::min(), 0); + T multiplier = 1 + std::numeric_limits::epsilon(); + + std::feclearexcept(FE_ALL_EXCEPT); + + T result = denorm_max * multiplier; + (void)result; + + // Underflow will occur only if tinyness is evaluated before rounding. + assert(std::fetestexcept(FE_UNDERFLOW) == std::numeric_limits::tinyness_before); + } } int main(int, char**) @@ -50,9 +66,15 @@ test<__int128_t, false>(); test<__uint128_t, false>(); #endif +#ifdef __arm__ + test(); + test(); + test(); +#else test(); test(); test(); +#endif return 0; }