From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 103948 invoked by alias); 15 Jun 2015 20:30:35 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 103938 invoked by uid 89); 15 Jun 2015 20:30:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=no version=3.3.2 X-HELO: cvs.linux-mips.org Received: from eddie.linux-mips.org (HELO cvs.linux-mips.org) (148.251.95.138) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 15 Jun 2015 20:30:33 +0000 Received: (from localhost user: 'macro', uid#1010) by eddie.linux-mips.org with ESMTP id S27007725AbbFOUaa5GrKY (ORCPT ); Mon, 15 Jun 2015 22:30:30 +0200 Date: Mon, 15 Jun 2015 20:52:00 -0000 From: "Maciej W. Rozycki" To: Joseph Myers cc: Steve Ellcey , gcc-patches@gcc.gnu.org, Catherine Moore , Matthew Fortune Subject: Re: [Patch, MIPS] Enable fp-contract on MIPS and update -mfused-madd In-Reply-To: Message-ID: References: <4c25620c-546c-40ae-b330-3652fe25f791@BAMAIL02.ba.imgtec.org> User-Agent: Alpine 2.11 (LFD 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg01047.txt.bz2 On Thu, 11 Jun 2015, Joseph Myers wrote: > > loongson and r8000 have the most changes, they no longer generate msub > > instructions with -mfused-madd because that instruction does not generate > > the correct NAN in some cases (the sign may be wrong). If HONOR_NANS > > is not set then they will generate msub instructions. > > There's no such thing as a correct NaN sign for fused multiply-add (at the > C / GIMPLE / RTL level, that is; there may be a correct sign at the level > of semantics for processor instructions). IEEE 754 only specifies signs > of NaNs for a few operations (copy, negate, abs, copySign). So while you > need to avoid negate / abs instructions that don't work properly on NaNs, > if signs of NaNs are the only concern then that's not a reason to avoid > any other arithmetic operations. You are right about fused multiply-add (FMA) as far as IEEE Std 754-2008 is concerned, however these instructions implement fused multiply-subtract (FMS) which is an operation that hasn't been defined by IEEE Std 754-2008 and neither is expressed by GCC at the RTL level (there's only (fma:M OP1 OP2 OP3); there's no (fms:M OP1 OP2 OP3) or suchlike). Consequently expander patterns like `fmsM4', `fnmaM4', `fnmsM4' and any further ones that might be invented for similar operations, that e.g. reverse the subtraction, are built around FMA with some of its input operands negated. That negation, implemented with the IEEE Std 754-2008 `negate' operation that you referred to, by definition is required to operate on the sign of its operand in a specific way even if the operand is a qNaN. So for example `fmsM4', that is specified at the RTL level as (fma:M OP1 OP2 (neg:M OP3)) will not produce the correct result with the fused version of the MIPS MSUB.fmt instruction in the case where OP1 and OP2 are numeric data patterns and OP3 is a qNaN data pattern that has its sign bit clear. As specified by IEEE Std 754-2008 the (neg:M OP3) operation is required to invert the sign bit of the qNaN data pattern in calculating TMP3, and then the (fma:M OP1 OP2 TMP3) operation is required to pass the TMP3 qNaN data pattern unchanged in calculating the final result. > > One thing I did not put in this patch was to add code to use the > > mips32r6/mips64r6 msubf instruction. This instruction implements > > 'c - (a * b)', not '(a * b) - c' and since it not currently used by > > GCC I decided not to add it to this patch. > > Fused c - (a * b) is exactly equivalent to fused (-a * b) + c or > (a * -b) + c (I don't know which is canonical in RTL). (It's *not* > equivalent to fused -((a * b) - c), when the result is an exact zero. > And moving negation inside multiplication like that is only valid for a > fused operation, not unfused if -frounding-math.) Well as I say, IEEE Std 754-2008 does not define a fused (c - (a * b)) or fused ((-a * b) + c) operation. The only fused operation defined by the standard is ((a * b) + c) and consequently, as I noted above, any additional IEEE Std 754-2008 compliant fused operations have to be implemented in terms of negating one or more of input operands, or the result. That is at least my understanding of IEEE Std 754-2008 -- if you think otherwise, can you prove me wrong? When going beyond IEEE Std 754-2008 we can of course define anything we want, but I think that'd have to be controlled with a separate compilation flag, assuming that we do want to go there (beyond -ffinite-math-only that we already have and that in turn causes HONOR_NANS to return FALSE). One complication however is the C11 language standard is still based around IEEE Std 754-1985 that in turn does not define any fused operation at all. Question might be whether we want to go into the IEEE Std 754-2008 territory before (unless?) the C language standard has reached there. However GCC has already adopted FMA, so I gather that we do. I can't speak of other languages GCC supports and their correspondence to IEEE Std 754. I agree with your note about the sign of exact zero results BTW, but it has been taken into account with Steve's patch. The relevant operations use or omit a HONOR_SIGNED_ZEROS check as applicable. If I got anything wrong in the above consideration, then I'll be happy to be corrected. Maciej