qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH] fpu: add compile time check for old glibc/libm


From: Alex Bennée
Subject: [Qemu-devel] [RFC PATCH] fpu: add compile time check for old glibc/libm and fma
Date: Thu, 20 Dec 2018 11:10:08 +0000

Some versions of glibc have been reported to have problems with
fused-multiply-accumulate operations. If the underlying fma
implementation does a two step operation it will instroduce subtle
rounding errors. Newer versions of the library seem to deal with this
better and modern hardware has fused operations which the library can
use.

Reported-by: Laurent Desnogues <address@hidden>
Signed-off-by: Alex Bennée <address@hidden>
Cc: Emilio G. Cota <address@hidden>
---
 fpu/softfloat.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 59eac97d10..9c2dbd04b5 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -203,6 +203,25 @@ GEN_INPUT_FLUSH3(float64_input_flush3, float64)
 # define QEMU_HARDFLOAT_3F64_USE_FP 0
 #endif
 
+/*
+ * Choose whether to accelerate fused multiply-accumulate operations
+ * with hard float functions. Some versions of glibc's maths library
+ * have been reported to be broken on x86 without FMA instructions.
+ */
+#if defined(__x86_64__)
+/* this was actually reported as glibc-2.12-1.149.el6_6.5.x86_64 was
+ * broken but glibc 2.12-1.209 works but out of caution lets disable
+ * for all older glibcs.
+ */
+#if defined(__GLIBC__) && (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 12)
+#define QEMU_HARDFLOAT_USE_FMA 0
+#else
+#define QEMU_HARDFLOAT_USE_FMA 1
+#endif
+#else
+#define QEMU_HARDFLOAT_USE_FMA 1
+#endif
+
 /*
  * QEMU_HARDFLOAT_USE_ISINF chooses whether to use isinf() over
  * float{32,64}_is_infinity when !USE_FP.
@@ -1551,6 +1570,9 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int 
flags, float_status *s)
     ub.s = xb;
     uc.s = xc;
 
+    if (!QEMU_HARDFLOAT_USE_FMA) {
+        goto soft;
+    }
     if (unlikely(!can_use_fpu(s))) {
         goto soft;
     }
@@ -1612,6 +1634,9 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int 
flags, float_status *s)
     ub.s = xb;
     uc.s = xc;
 
+    if (!QEMU_HARDFLOAT_USE_FMA) {
+        goto soft;
+    }
     if (unlikely(!can_use_fpu(s))) {
         goto soft;
     }
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]