From 26bbe2ad50cd7003b8220cfec2bff16dbc032ca8 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 6 Nov 2020 17:30:33 -0500 Subject: [PATCH] : Use intrinsics where possible (#1336) Co-authored-by: Stephan T. Lavavej --- stl/inc/cmath | 117 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 15 deletions(-) diff --git a/stl/inc/cmath b/stl/inc/cmath index cdc55d438d..354587044f 100644 --- a/stl/inc/cmath +++ b/stl/inc/cmath @@ -12,6 +12,10 @@ #include #include +#if !defined(_M_CEE) && !defined(__clang__) +#include +#endif // !defined(_M_CEE) && !defined(__clang__) + #if _HAS_CXX20 #include #endif // _HAS_CXX20 @@ -56,11 +60,23 @@ _NODISCARD _Check_return_ inline float cbrt(_In_ float _Xx) noexcept /* strength } _NODISCARD _Check_return_ inline float ceil(_In_ float _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD ceilf(_Xx); +#elif defined(__clang__) + return __builtin_ceilf(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __ceilf(_Xx); +#endif // __clang__ } _NODISCARD _Check_return_ inline float copysign(_In_ float _Number, _In_ float _Sign) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD copysignf(_Number, _Sign); +#elif defined(__clang__) + return __builtin_copysignf(_Number, _Sign); +#else // ^^^ __clang__ / !__clang__ vvv + return __copysignf(_Number, _Sign); +#endif // __clang__ } _NODISCARD _Check_return_ inline float cos(_In_ float _Xx) noexcept /* strengthened */ { @@ -100,7 +116,13 @@ _NODISCARD _Check_return_ inline float fdim(_In_ float _Xx, _In_ float _Yx) noex } _NODISCARD _Check_return_ inline float floor(_In_ float _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD floorf(_Xx); +#elif defined(__clang__) + return __builtin_floorf(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __floorf(_Xx); +#endif // __clang__ } _NODISCARD _Check_return_ inline float fma(_In_ float _Xx, _In_ float _Yx, _In_ float _Zx) noexcept /* strengthened */ { @@ -208,7 +230,13 @@ _NODISCARD _Check_return_ inline float rint(_In_ float _Xx) noexcept /* strength } _NODISCARD _Check_return_ inline float round(_In_ float _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD roundf(_Xx); +#elif defined(__clang__) + return __builtin_roundf(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __roundf(_Xx); +#endif // __clang__ } _NODISCARD _Check_return_ inline float scalbln(_In_ float _Xx, _In_ long _Yx) noexcept /* strengthened */ { @@ -244,7 +272,13 @@ _NODISCARD _Check_return_ inline float tgamma(_In_ float _Xx) noexcept /* streng } _NODISCARD _Check_return_ inline float trunc(_In_ float _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD truncf(_Xx); +#elif defined(__clang__) + return __builtin_truncf(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __truncf(_Xx); +#endif // __clang__ } _NODISCARD _Check_return_ inline long double acos(_In_ long double _Xx) noexcept /* strengthened */ { @@ -281,12 +315,24 @@ _NODISCARD _Check_return_ inline long double cbrt(_In_ long double _Xx) noexcept } _NODISCARD _Check_return_ inline long double ceil(_In_ long double _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD ceill(_Xx); +#elif defined(__clang__) + return __builtin_ceill(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __ceil(static_cast(_Xx)); +#endif // __clang__ } _NODISCARD _Check_return_ inline long double copysign(_In_ long double _Number, _In_ long double _Sign) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD copysignl(_Number, _Sign); +#elif defined(__clang__) + return __builtin_copysignl(_Number, _Sign); +#else // ^^^ __clang__ / !__clang__ vvv + return __copysign(static_cast(_Number), static_cast(_Sign)); +#endif // __clang__ } _NODISCARD _Check_return_ inline long double cos(_In_ long double _Xx) noexcept /* strengthened */ { @@ -327,7 +373,13 @@ _NODISCARD _Check_return_ inline long double fdim(_In_ long double _Xx, _In_ lon } _NODISCARD _Check_return_ inline long double floor(_In_ long double _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD floorl(_Xx); +#elif defined(__clang__) + return __builtin_floorl(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __floor(static_cast(_Xx)); +#endif // __clang__ } _NODISCARD _Check_return_ inline long double fma( @@ -444,7 +496,13 @@ _NODISCARD _Check_return_ inline long double rint(_In_ long double _Xx) noexcept } _NODISCARD _Check_return_ inline long double round(_In_ long double _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD roundl(_Xx); +#elif defined(__clang__) + return __builtin_roundl(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __round(static_cast(_Xx)); +#endif // __clang__ } _NODISCARD _Check_return_ inline long double scalbln(_In_ long double _Xx, _In_ long _Yx) noexcept /* strengthened */ { @@ -480,7 +538,13 @@ _NODISCARD _Check_return_ inline long double tgamma(_In_ long double _Xx) noexce } _NODISCARD _Check_return_ inline long double trunc(_In_ long double _Xx) noexcept /* strengthened */ { +#ifdef _M_CEE return _CSTD truncl(_Xx); +#elif defined(__clang__) + return __builtin_truncl(_Xx); +#else // ^^^ __clang__ / !__clang__ vvv + return __trunc(static_cast(_Xx)); +#endif // __clang__ } @@ -561,13 +625,22 @@ _STD _Common_float_type_t<_Ty1, _Ty2> remquo(_Ty1 _Left, _Ty2 _Right, int* _Pquo #endif // _HAS_IF_CONSTEXPR } -#define _GENERIC_MATH1R(FUN, RET) \ +#define _GENERIC_MATH1_BASE(NAME, RET, FUN) \ template , int> = 0> \ - _NODISCARD RET FUN(_Ty _Left) noexcept /* strengthened */ { \ - return _CSTD FUN(static_cast(_Left)); \ + _NODISCARD RET NAME(_Ty _Left) noexcept /* strengthened */ { \ + return FUN(static_cast(_Left)); \ } -#define _GENERIC_MATH1(FUN) _GENERIC_MATH1R(FUN, double) +#define _GENERIC_MATH1R(FUN, RET) _GENERIC_MATH1_BASE(FUN, RET, _CSTD FUN) +#define _GENERIC_MATH1(FUN) _GENERIC_MATH1R(FUN, double) + +#ifdef _M_CEE +#define _GENERIC_MATH1I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH1_BASE(FUN, double, _CSTD FUN) +#elif defined(__clang__) +#define _GENERIC_MATH1I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH1_BASE(FUN, double, CLANG_INTRIN) +#else // ^^^ __clang__ / !__clang__ vvv +#define _GENERIC_MATH1I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH1_BASE(FUN, double, MSVC_INTRIN) +#endif // __clang__ #define _GENERIC_MATH1X(FUN, ARG2) \ template , int> = 0> \ @@ -575,14 +648,24 @@ _STD _Common_float_type_t<_Ty1, _Ty2> remquo(_Ty1 _Left, _Ty2 _Right, int* _Pquo return _CSTD FUN(static_cast(_Left), _Arg2); \ } -#define _GENERIC_MATH2(FUN) \ - template && _STD is_arithmetic_v<_Ty2>, int> = 0> \ - _NODISCARD _STD _Common_float_type_t<_Ty1, _Ty2> FUN(_Ty1 _Left, _Ty2 _Right) noexcept /* strengthened */ { \ - using _Common = _STD _Common_float_type_t<_Ty1, _Ty2>; \ - return _CSTD FUN(static_cast<_Common>(_Left), static_cast<_Common>(_Right)); \ +#define _GENERIC_MATH2_BASE(NAME, FUN) \ + template && _STD is_arithmetic_v<_Ty2>, int> = 0> \ + _NODISCARD _STD _Common_float_type_t<_Ty1, _Ty2> NAME(_Ty1 _Left, _Ty2 _Right) noexcept /* strengthened */ { \ + using _Common = _STD _Common_float_type_t<_Ty1, _Ty2>; \ + return FUN(static_cast<_Common>(_Left), static_cast<_Common>(_Right)); \ } +#define _GENERIC_MATH2(FUN) _GENERIC_MATH2_BASE(FUN, _CSTD FUN) + +#ifdef _M_CEE +#define _GENERIC_MATH2I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH2_BASE(FUN, _CSTD FUN) +#elif defined(__clang__) +#define _GENERIC_MATH2I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH2_BASE(FUN, CLANG_INTRIN) +#else // ^^^ __clang__ / !__clang__ vvv +#define _GENERIC_MATH2I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH2_BASE(FUN, MSVC_INTRIN) +#endif // __clang__ + // The following order matches N4820 26.8.1 [cmath.syn]. _GENERIC_MATH1(acos) _GENERIC_MATH1(asin) @@ -622,20 +705,20 @@ _GENERIC_MATH1(erf) _GENERIC_MATH1(erfc) _GENERIC_MATH1(lgamma) _GENERIC_MATH1(tgamma) -_GENERIC_MATH1(ceil) -_GENERIC_MATH1(floor) +_GENERIC_MATH1I(ceil, __builtin_ceil, __ceil) +_GENERIC_MATH1I(floor, __builtin_floor, __floor) _GENERIC_MATH1(nearbyint) _GENERIC_MATH1(rint) _GENERIC_MATH1R(lrint, long) _GENERIC_MATH1R(llrint, long long) -_GENERIC_MATH1(round) +_GENERIC_MATH1I(round, __builtin_round, __round) _GENERIC_MATH1R(lround, long) _GENERIC_MATH1R(llround, long long) -_GENERIC_MATH1(trunc) +_GENERIC_MATH1I(trunc, __builtin_trunc, __trunc) _GENERIC_MATH2(fmod) _GENERIC_MATH2(remainder) // remquo() is hand-crafted -_GENERIC_MATH2(copysign) +_GENERIC_MATH2I(copysign, __builtin_copysign, __copysign) // nan(const char*) is exempt _GENERIC_MATH2(nextafter) _GENERIC_MATH1X(nexttoward, long double) @@ -647,10 +730,14 @@ _GENERIC_MATH2(fmin) // The "classification/comparison functions" (fpclassify(), etc.) are exempt, LWG-1327 // TRANSITION, VSO-945789, Special Math shouldn't be exempt +#undef _GENERIC_MATH1_BASE #undef _GENERIC_MATH1R #undef _GENERIC_MATH1 +#undef _GENERIC_MATH1I #undef _GENERIC_MATH1X +#undef _GENERIC_MATH2_BASE #undef _GENERIC_MATH2 +#undef _GENERIC_MATH2I _STD_BEGIN