From patchwork Sun Mar 16 23:43:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael-Doyle Hudson X-Patchwork-Id: 26337 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f72.google.com (mail-yh0-f72.google.com [209.85.213.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9A63520369 for ; Sun, 16 Mar 2014 23:43:56 +0000 (UTC) Received: by mail-yh0-f72.google.com with SMTP id f10sf12911953yha.7 for ; Sun, 16 Mar 2014 16:43:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mailing-list:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:sender :delivered-to:from:to:cc:subject:in-reply-to:references:user-agent :date:message-id:mime-version:x-original-sender :x-original-authentication-results:content-type; bh=tU64prAPVROpUwS3lqpOr3Amd1NBBId/8U7mH5GDs1Q=; b=BuuX9w6AJxhRkfLa5l9nhZNG3D5uZ6tmjAN45IJ+TlKlAkTJaFrjQXpzRFdNlgh38x nrupsBJzp4ZQD3ZvXU5Y+x5VTyTgdPWIbKjBguwtum8MYMfux0Th8pzOLZl+wqmVCDU3 WGhruKgJgT5JQTWYz1vcU+mMeJLhk77KHpVTx7LS350tvTzH7Xh2kV+3Et92F9naT1jn 0BWSUw8u3X8Ve6pb8xIfOenTkipr65H281Iemg4GOklIDSJgoGbEdSWD646glL99214K fu/InyCaTVZPwoIeK7Atx/sVl0wEiOHUZkvngNgUotu+guN0jpPmhFn8Hu3FHm3RD9qr Vz2g== X-Gm-Message-State: ALoCoQlmJGxFrpAB0Li3Do1Mv8lvgEXt8BSsEOd0EeMe7KTvlyG/4NuABfnrQObQYYEcGLJBXIFT X-Received: by 10.58.39.202 with SMTP id r10mr8553056vek.12.1395013436022; Sun, 16 Mar 2014 16:43:56 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.109.9 with SMTP id k9ls1473490qgf.78.gmail; Sun, 16 Mar 2014 16:43:55 -0700 (PDT) X-Received: by 10.220.191.134 with SMTP id dm6mr17530553vcb.16.1395013435900; Sun, 16 Mar 2014 16:43:55 -0700 (PDT) Received: from mail-vc0-x232.google.com (mail-vc0-x232.google.com [2607:f8b0:400c:c03::232]) by mx.google.com with ESMTPS id nd7si2387630vec.157.2014.03.16.16.43.55 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 16 Mar 2014 16:43:55 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c03::232 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c03::232; Received: by mail-vc0-f178.google.com with SMTP id im17so5174450vcb.9 for ; Sun, 16 Mar 2014 16:43:55 -0700 (PDT) X-Received: by 10.52.247.231 with SMTP id yh7mr33361vdc.34.1395013435673; Sun, 16 Mar 2014 16:43:55 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.78.9 with SMTP id i9csp89345vck; Sun, 16 Mar 2014 16:43:55 -0700 (PDT) X-Received: by 10.69.31.75 with SMTP id kk11mr21845105pbd.101.1395013434615; Sun, 16 Mar 2014 16:43:54 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id e6si10556390pbj.223.2014.03.16.16.43.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 16 Mar 2014 16:43:54 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-363356-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 19411 invoked by alias); 16 Mar 2014 23:43:40 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19402 invoked by uid 89); 16 Mar 2014 23:43:39 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: youngberry.canonical.com Received: from youngberry.canonical.com (HELO youngberry.canonical.com) (91.189.89.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 16 Mar 2014 23:43:37 +0000 Received: from [120.136.5.22] (helo=narsil) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1WPKiN-0008LF-5S; Sun, 16 Mar 2014 23:43:35 +0000 Received: by narsil (Postfix, from userid 1000) id 963445262A5; Mon, 17 Mar 2014 07:43:30 +0800 (CST) From: Michael Hudson-Doyle To: Ian Lance Taylor Cc: gcc-patches , "gofrontend-dev\@googlegroups.com" Subject: Re: libgo patch committed: Compile math library with -ffp-contract=off In-Reply-To: <87eh255yq0.fsf@canonical.com> References: <87mwgt602z.fsf@canonical.com> <87eh255yq0.fsf@canonical.com> User-Agent: Notmuch/0.17~rc1+4~g7f07bfd (http://notmuchmail.org) Emacs/24.3.50.2 (x86_64-pc-linux-gnu) Date: Mon, 17 Mar 2014 12:43:30 +1300 Message-ID: <87zjkp4sm5.fsf@canonical.com> MIME-Version: 1.0 X-Original-Sender: michael.hudson@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c03::232 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@gcc.gnu.org X-Google-Group-Id: 836684582541 Michael Hudson-Doyle writes: > Ian Lance Taylor writes: > >> On Thu, Mar 13, 2014 at 6:27 PM, Michael Hudson-Doyle >> wrote: >>> Ian Lance Taylor 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: 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 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 + __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