https://gcc.gnu.org/g:ec43369c7e2c4b930a501252fa048df51c141970
commit r14-10870-gec43369c7e2c4b930a501252fa048df51c141970 Author: Jakub Jelinek <ja...@redhat.com> Date: Tue Oct 29 11:14:12 2024 +0100 libstdc++: Use if consteval rather than if (std::__is_constant_evaluated()) for {,b}float16_t nextafter [PR117321] The nextafter_c++23.cc testcase fails to link at -O0. The problem is that eventhough std::__is_constant_evaluated() has always_inline attribute, that at -O0 just means that we inline the call, but its result is still assigned to a temporary which is tested later, nothing at -O0 propagates that false into the if and optimizes away the if body. And the __builtin_nextafterf16{,b} calls are meant to be used solely for constant evaluation, the C libraries don't define nextafterf16 these days. As __STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ are predefined right now only by GCC, not by clang which doesn't implement the extended floating point types paper, and as they are predefined in C++23 and later modes only, I think we can just use if consteval which is folded already during the FE and the body isn't included even at -O0. I've added a feature test for that just in case clang implements those and implements those in some weird way. Note, if (__builtin_is_constant_evaluted()) would work correctly too, that is also folded to false at gimplification time and the corresponding if block not emitted at all. But for -O0 it can't be wrapped into a helper inline function. 2024-10-29 Jakub Jelinek <ja...@redhat.com> PR libstdc++/117321 * include/c_global/cmath (nextafter(_Float16, _Float16)): Use if consteval rather than if (std::__is_constant_evaluated()) around the __builtin_nextafterf16 call. (nextafter(__gnu_cxx::__bfloat16_t, __gnu_cxx::__bfloat16_t)): Use if consteval rather than if (std::__is_constant_evaluated()) around the __builtin_nextafterf16b call. * testsuite/26_numerics/headers/cmath/117321.cc: New test. (cherry picked from commit 5e247ac0c28b9a2662f99c4a5420c5f7c2d0c6bd) Diff: --- libstdc++-v3/include/c_global/cmath | 16 ++++++++++++---- .../testsuite/26_numerics/headers/cmath/117321.cc | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index dd0174f1987f..c5ebebd6b861 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -2873,8 +2873,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Float16 nextafter(_Float16 __x, _Float16 __y) { - if (std::__is_constant_evaluated()) - return __builtin_nextafterf16(__x, __y); +#if __cpp_if_consteval >= 202106L + // Can't use if (std::__is_constant_evaluated()) here, as it + // doesn't guarantee optimizing the body away at -O0 and + // nothing defines nextafterf16. + if consteval { return __builtin_nextafterf16(__x, __y); } +#endif #ifdef __INT16_TYPE__ using __float16_int_type = __INT16_TYPE__; #else @@ -3591,8 +3595,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr __gnu_cxx::__bfloat16_t nextafter(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y) { - if (std::__is_constant_evaluated()) - return __builtin_nextafterf16b(__x, __y); +#if __cpp_if_consteval >= 202106L + // Can't use if (std::__is_constant_evaluated()) here, as it + // doesn't guarantee optimizing the body away at -O0 and + // nothing defines nextafterf16b. + if consteval { return __builtin_nextafterf16b(__x, __y); } +#endif #ifdef __INT16_TYPE__ using __bfloat16_int_type = __INT16_TYPE__; #else diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc new file mode 100644 index 000000000000..18d108c6a3e2 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc @@ -0,0 +1,5 @@ +// { dg-do run { target c++23 } } +// { dg-require-cmath "" } +// { dg-additional-options "-O0" } + +#include "nextafter_c++23.cc"