Re: libgo patch committed: Compile math library with -ffp-contract=off

2014-03-16 Thread Michael Hudson-Doyle
Michael Hudson-Doyle michael.hud...@linaro.org writes:

 Ian Lance Taylor i...@google.com writes:

 On Thu, Mar 13, 2014 at 6:27 PM, Michael Hudson-Doyle
 michael.hud...@linaro.org wrote:
 Ian Lance Taylor i...@google.com writes:

 The bug report http://golang.org/issue/7074 shows that math.Log2(1)
 produces the wrong result on Aarch64, because the Go math package is
 compiled to use a fused multiply-add instruction.  This patch to the
 libgo configure script will use -ffp-contract=off when compiling the
 math package on processors other than x86.  Bootstrapped and ran Go
 testsuite on x86_64-unknown-linux-gnu, not that that tests much.
 Committed to mainline.

 Thanks for this!  If you are willing to go into battle enough to argue
 that libgcc should also be compiled with -ffp-contract=off (I did not
 have the stomach for that fight) then we'll be down to 1 check-go
 failure on aarch64 (which is peano -- due to the absence of
 split/copyable stacks and should probably xfail).

 Hmmm, what is it that fails with libgcc?  Is there a bug report for
 it?

 https://code.google.com/p/go/issues/detail?id=7066

 and then

 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714

 I wanted to propose a version using Kahan's algorithm for the
 determinant as described in

 http://hal-ens-lyon.archives-ouvertes.fr/docs/00/78/57/86/PDF/Jeannerod_Louvet_Muller_final.pdf

 but I haven't gotten around to it...

I got bored / distracted and hacked up this:

diff --git a/libgo/runtime/go-cdiv.c b/libgo/runtime/go-cdiv.c
index 0a81e45..b96576a 100644
--- a/libgo/runtime/go-cdiv.c
+++ b/libgo/runtime/go-cdiv.c
@@ -13,6 +13,8 @@
the the whole number is Inf, but an operation involving NaN ought
to result in NaN, not Inf.  */
 
+#include math.h
+
 __complex float
 __go_complex64_div (__complex float a, __complex float b)
 {
@@ -29,6 +31,48 @@ __go_complex64_div (__complex float a, __complex float b)
   return a / b;
 }
 
+#ifdef FP_FAST_FMA
+
+// This implements what is sometimes called Kahan's compensated algorithm for
+// 2 by 2 determinants.  It returns a*b + c*d to a high degree of precision
+// but depends on a fused-multiply add operation that rounds once.
+//
+// The obvious algorithm has problems when a*b and c*d nearly cancel, but the
+// trick is the calculation of 'e': a*b = w + e is exact when the operands
+// are considered as real numbers.  So if c*d nearly cancels out w, e restores
+// the result to accuracy.
+double
+Kahan(double a, double b, double c, double d)
+{
+  double w, e, f;
+  w = b * a;
+  e = fma(b, a, -w);
+  f = fma(d, c, w);
+  return f + e;
+}
+
+__complex double
+__go_complex128_div (__complex double a, __complex double b)
+{
+  double r, i, denom;
+  if (__builtin_expect (b == 0+0i, 0))
+{
+  if (!__builtin_isinf (__real__ a)
+  !__builtin_isinf (__imag__ a)
+  (__builtin_isnan (__real__ a) || __builtin_isnan (__imag__ a)))
+   {
+ /* Pass 1 to nan to match math/bits.go.  */
+ return __builtin_nan(1) + __builtin_nan(1)*1i;
+   }
+}
+  r = Kahan(__real__ a, __real__ b, __imag__ a, __imag__ b);
+  i = Kahan(__imag__ a, __real__ b, - __real__ a, __imag__ b);
+  denom = (__real__ b)*(__real__ b) + (__imag__ b)*(__imag__ b);
+  return r/denom + i*1.0i/denom;
+}
+
+#else
+
 __complex double
 __go_complex128_div (__complex double a, __complex double b)
 {
@@ -44,3 +88,5 @@ __go_complex128_div (__complex double a, __complex double b)
 }
   return a / b;
 }
+
+#endif

it would be better to do this in libgcc of course but I think that's
awkward because libgcc can't link to libm and so on...  It's probably a
little slower than the libgcc version (although this is straight line
code) but I don't really care about that :-)

Cheers,
mwh


Re: libgo patch committed: Compile math library with -ffp-contract=off

2014-03-13 Thread Michael Hudson-Doyle
Ian Lance Taylor i...@google.com writes:

 The bug report http://golang.org/issue/7074 shows that math.Log2(1)
 produces the wrong result on Aarch64, because the Go math package is
 compiled to use a fused multiply-add instruction.  This patch to the
 libgo configure script will use -ffp-contract=off when compiling the
 math package on processors other than x86.  Bootstrapped and ran Go
 testsuite on x86_64-unknown-linux-gnu, not that that tests much.
 Committed to mainline.

Thanks for this!  If you are willing to go into battle enough to argue
that libgcc should also be compiled with -ffp-contract=off (I did not
have the stomach for that fight) then we'll be down to 1 check-go
failure on aarch64 (which is peano -- due to the absence of
split/copyable stacks and should probably xfail).

Cheers,
mwh

 Ian

 diff -r 76dbb6f77e3d libgo/configure.ac
 --- a/libgo/configure.ac  Tue Mar 11 12:53:06 2014 -0700
 +++ b/libgo/configure.ac  Tue Mar 11 21:26:35 2014 -0700
 @@ -620,6 +620,8 @@
  MATH_FLAG=
  if test $libgo_cv_c_fancymath = yes; then
MATH_FLAG=-mfancy-math-387 -funsafe-math-optimizations
 +else
 +  MATH_FLAG=-ffp-contract=off
  fi
  AC_SUBST(MATH_FLAG)
  


Re: libgo patch committed: Compile math library with -ffp-contract=off

2014-03-13 Thread Ian Lance Taylor
On Thu, Mar 13, 2014 at 6:27 PM, Michael Hudson-Doyle
michael.hud...@linaro.org wrote:
 Ian Lance Taylor i...@google.com writes:

 The bug report http://golang.org/issue/7074 shows that math.Log2(1)
 produces the wrong result on Aarch64, because the Go math package is
 compiled to use a fused multiply-add instruction.  This patch to the
 libgo configure script will use -ffp-contract=off when compiling the
 math package on processors other than x86.  Bootstrapped and ran Go
 testsuite on x86_64-unknown-linux-gnu, not that that tests much.
 Committed to mainline.

 Thanks for this!  If you are willing to go into battle enough to argue
 that libgcc should also be compiled with -ffp-contract=off (I did not
 have the stomach for that fight) then we'll be down to 1 check-go
 failure on aarch64 (which is peano -- due to the absence of
 split/copyable stacks and should probably xfail).

Hmmm, what is it that fails with libgcc?  Is there a bug report for
it?

I agree that peano is likely to fail without split stacks.

Ian


Re: libgo patch committed: Compile math library with -ffp-contract=off

2014-03-13 Thread Michael Hudson-Doyle
Ian Lance Taylor i...@google.com writes:

 On Thu, Mar 13, 2014 at 6:27 PM, Michael Hudson-Doyle
 michael.hud...@linaro.org wrote:
 Ian Lance Taylor i...@google.com writes:

 The bug report http://golang.org/issue/7074 shows that math.Log2(1)
 produces the wrong result on Aarch64, because the Go math package is
 compiled to use a fused multiply-add instruction.  This patch to the
 libgo configure script will use -ffp-contract=off when compiling the
 math package on processors other than x86.  Bootstrapped and ran Go
 testsuite on x86_64-unknown-linux-gnu, not that that tests much.
 Committed to mainline.

 Thanks for this!  If you are willing to go into battle enough to argue
 that libgcc should also be compiled with -ffp-contract=off (I did not
 have the stomach for that fight) then we'll be down to 1 check-go
 failure on aarch64 (which is peano -- due to the absence of
 split/copyable stacks and should probably xfail).

 Hmmm, what is it that fails with libgcc?  Is there a bug report for
 it?

https://code.google.com/p/go/issues/detail?id=7066

and then

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714

I wanted to propose a version using Kahan's algorithm for the
determinant as described in

http://hal-ens-lyon.archives-ouvertes.fr/docs/00/78/57/86/PDF/Jeannerod_Louvet_Muller_final.pdf

but I haven't gotten around to it...

Cheers,
mwh

 I agree that peano is likely to fail without split stacks.

 Ian