fmal: Avoid test failure on OpenBSD 5.1/SPARC64.
authorBruno Haible <bruno@clisp.org>
Thu, 15 Mar 2012 11:12:49 +0000 (12:12 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 15 Mar 2012 11:12:49 +0000 (12:12 +0100)
* lib/fma.c (VOLATILE): New macro.
(FUNC): Use it to work around a GCC compiler bug.

ChangeLog
lib/fma.c

index bd1b234..e600a1d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-15  Bruno Haible  <bruno@clisp.org>
+
+       fmal: Avoid test failure on OpenBSD 5.1/SPARC64.
+       * lib/fma.c (VOLATILE): New macro.
+       (FUNC): Use it to work around a GCC compiler bug.
+
 2012-03-13  Bruno Haible  <bruno@clisp.org>
 
        hypotl: Bypass broken implementation in OpenBSD 5.1/SPARC.
index 9882e88..18f0eca 100644 (file)
--- a/lib/fma.c
+++ b/lib/fma.c
 # pragma fenv_access (off)
 #endif
 
+/* Work around GCC 4.2.1 bug on OpenBSD 5.1/SPARC64.  */
+#if defined __GNUC__ && defined __sparc__
+# define VOLATILE volatile
+#else
+# define VOLATILE
+#endif
+
 /* It is possible to write an implementation of fused multiply-add with
    floating-point operations alone.  See
      Sylvie Boldo, Guillaume Melquiond:
@@ -866,16 +873,22 @@ FUNC (DOUBLE x, DOUBLE y, DOUBLE z)
                     else
                       {
                         /* First loop round.  */
-                        fsum = (DOUBLE)
-                               ((sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
-                                | (sum_len >= k + 2 ? sum[sum_len - k - 2] >> shift : 0));
+                        {
+                          VOLATILE mp_limb_t chunk =
+                            (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
+                            | (sum_len >= k + 2 ? sum[sum_len - k - 2] >> shift : 0);
+                          fsum = (DOUBLE) chunk;
+                        }
                         /* General loop.  */
                         while (--k >= 0)
                           {
                             fsum *= chunk_multiplier;
-                            fsum += (DOUBLE)
-                                    ((sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
-                                     | (sum[sum_len - k - 2] >> shift));
+                            {
+                              VOLATILE mp_limb_t chunk =
+                                (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
+                                | (sum[sum_len - k - 2] >> shift);
+                              fsum += (DOUBLE) chunk;
+                            }
                           }
                       }
                   }