From: Martin Storsjö martin@martin.st
musl itself expects to be configured to compile with either -ffloat-store or -fexcess-precision=standard - but when imported into Wine, those flags aren't used.
This seems to be essential for getting reasonable precision from some math functions such as exp2() - without the expected precision truncation, the output value of exp2() can be off by as much as 0.2% in some cases.
As Wine doesn't build the musl sources with those flags, use volatile to force storing/reloading floats in order to limit their intermediate precision, as musl expects. Only do this on i386 where this is known be required.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56372 --- libs/musl/src/internal/libm.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/libs/musl/src/internal/libm.h b/libs/musl/src/internal/libm.h index a1e9bc08716..fa3ec4bd607 100644 --- a/libs/musl/src/internal/libm.h +++ b/libs/musl/src/internal/libm.h @@ -104,17 +104,20 @@ static int32_t converttoint(double_t); /* Evaluate an expression as the specified type. With standard excess precision handling a type cast or assignment is enough (with -ffloat-store an assignment is required, in old compilers argument - passing and return statement may not drop excess precision). */ + passing and return statement may not drop excess precision). + + If compiled without -ffloat-store or -fexcess-precision=standard, + an extra volatile qualifier here will force limiting the precision. */
static inline float eval_as_float(float x) { - float y = x; + volatile float y = x; return y; }
static inline double eval_as_double(double x) { - double y = x; + volatile double y = x; return y; }