Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58381
-- v3: musl: Optimize rint when floating point operations use 53-bit precision. musl: Don't use __builtin_rint in clang builds.
From: Piotr Caban piotr@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58381 --- libs/musl/src/math/rint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/musl/src/math/rint.c b/libs/musl/src/math/rint.c index 61df07485b8..7ecf9d8625c 100644 --- a/libs/musl/src/math/rint.c +++ b/libs/musl/src/math/rint.c @@ -7,7 +7,7 @@ static const float_t toint = 1 / FLT_EPSILON;
double __cdecl rint(double x) { -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) && !defined(__clang__) return __builtin_rint(x); #else union {double f; uint64_t i;} u = {x};
From: Piotr Caban piotr@codeweavers.com
--- libs/musl/src/math/rint.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/libs/musl/src/math/rint.c b/libs/musl/src/math/rint.c index 7ecf9d8625c..d9857272747 100644 --- a/libs/musl/src/math/rint.c +++ b/libs/musl/src/math/rint.c @@ -3,12 +3,28 @@ #include <stdint.h> #include "libm.h"
-static const float_t toint = 1 / FLT_EPSILON; +static const float_t tointf = 1 / FLT_EPSILON; +static const double_t toint = 1 / DBL_EPSILON;
double __cdecl rint(double x) { #if defined(__GNUC__) && !defined(__clang__) return __builtin_rint(x); +#elif defined(__SSE_MATH__) + union {double f; uint64_t i;} u = {x}; + int e = u.i>>52 & 0x7ff; + int s = u.i>>63; + double_t y; + + if (e >= 0x3ff+52) + return x; + if (s) + y = x - toint + toint; + else + y = x + toint - toint; + if (y == 0) + return s ? -0.0 : 0; + return y; #else union {double f; uint64_t i;} u = {x}; int e = (u.i >> 52 & 0x7ff) - 0x3ff; @@ -32,7 +48,7 @@ double __cdecl rint(double x) else f = 0.0;
f = (even ? -0.0 : -1.0) + f; - f = fp_barrierf(f - toint) + toint; + f = fp_barrierf(f - tointf) + tointf; if (f == (even ? 0.0 : -1.0)) z = y; else z = floor(x); } @@ -46,7 +62,7 @@ double __cdecl rint(double x) else f = 0.0;
f = (even ? 0.0 : 1.0) + f; - f = fp_barrierf(f + toint) - toint; + f = fp_barrierf(f + tointf) - tointf; if (f == (even ? 0.0 : 1.0)) z = y; else z = ceil(x); }