Message ID | ZyCj3ly2nCDEcXDo@tucnak |
---|---|
State | New |
Headers | show |
Series | libstdc++: Use if consteval rather than if (std::__is_constant_evaluated()) for {,b}float16_t nextafter [PR117321] | expand |
On Tue, 29 Oct 2024, 09:00 Jakub Jelinek, <jakub@redhat.com> wrote: > Hi! > > 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. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > OK, thanks > 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. > > --- libstdc++-v3/include/c_global/cmath.jj 2024-09-25 > 17:25:07.227360607 +0200 > +++ libstdc++-v3/include/c_global/cmath 2024-10-28 13:10:46.348655046 +0100 > @@ -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 > --- libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc.jj > 2024-10-28 12:56:10.699876240 +0100 > +++ libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc 2024-10-28 > 12:56:59.875189173 +0100 > @@ -0,0 +1,5 @@ > +// { dg-do run { target c++23 } } > +// { dg-require-cmath "" } > +// { dg-additional-options "-O0" } > + > +#include "nextafter_c++23.cc" > > Jakub > >
--- libstdc++-v3/include/c_global/cmath.jj 2024-09-25 17:25:07.227360607 +0200 +++ libstdc++-v3/include/c_global/cmath 2024-10-28 13:10:46.348655046 +0100 @@ -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 --- libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc.jj 2024-10-28 12:56:10.699876240 +0100 +++ libstdc++-v3/testsuite/26_numerics/headers/cmath/117321.cc 2024-10-28 12:56:59.875189173 +0100 @@ -0,0 +1,5 @@ +// { dg-do run { target c++23 } } +// { dg-require-cmath "" } +// { dg-additional-options "-O0" } + +#include "nextafter_c++23.cc"