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  <jakub@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.
This commit is contained in:
Jakub Jelinek 2024-10-29 11:14:12 +01:00 committed by Jakub Jelinek
parent 61977b8af0
commit 5e247ac0c2
2 changed files with 17 additions and 4 deletions

View File

@ -2880,8 +2880,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
@ -3598,8 +3602,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

View File

@ -0,0 +1,5 @@
// { dg-do run { target c++23 } }
// { dg-require-cmath "" }
// { dg-additional-options "-O0" }
#include "nextafter_c++23.cc"