I'm not sure if it's the best way of fixing the bug. I was trying to set compilation options to workaround the problem but it didn't work well (probably due to my limited knowledge in this area).
The patch was originally sent in !5276.
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; }
This merge request was approved by Piotr Caban.
Thanks for picking this up! The commit message (the last paragraph) is a bit out of sync with the actual implementation at this point though.