Message ID | 4df302c6-5bc7-f6fb-916a-6dd9c0460268@linux.ibm.com |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 187223856DCC for <patchwork@sourceware.org>; Thu, 5 May 2022 08:07:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 187223856DCC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1651738057; bh=bSwCChZqED956mClu0XZQaet10/U5ux4iD46ISGj2bU=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Sga+aRQdYCNGIhJdCSjQ2iijXn3QwJbgWBPLmXfp3mSmV11vGtFNUxfONTcq7Pwpq hQTERVLJDUAVpAPp27PsFnHfcECKS615XoICcyDECBzxGUR2kZ8WaCHY1Z49Rd67rN miG/PcoKtY0BLX+6K3hOLg2++UhJoqMPlfHaSnpw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id F2EE13858D3C for <gcc-patches@gcc.gnu.org>; Thu, 5 May 2022 08:07:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F2EE13858D3C Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2457QOL2007124; Thu, 5 May 2022 08:07:02 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3fv7ydjsj8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 May 2022 08:07:02 +0000 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 24580DAc010611; Thu, 5 May 2022 08:07:02 GMT Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3fv7ydjshm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 May 2022 08:07:01 +0000 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 24582hhX013871; Thu, 5 May 2022 08:07:00 GMT Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by ppma04ams.nl.ibm.com with ESMTP id 3frvr8xumw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 May 2022 08:07:00 +0000 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 24586urB50921962 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 May 2022 08:06:57 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D19C752050; Thu, 5 May 2022 08:06:56 +0000 (GMT) Received: from [9.197.252.62] (unknown [9.197.252.62]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id 0379F52052; Thu, 5 May 2022 08:06:54 +0000 (GMT) Message-ID: <4df302c6-5bc7-f6fb-916a-6dd9c0460268@linux.ibm.com> Date: Thu, 5 May 2022 16:06:52 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1 Content-Language: en-US To: gcc-patches <gcc-patches@gcc.gnu.org> Subject: [PATCH] Skip constant folding for fmin/max when either argument is sNaN [PR105414] Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: K2Q3iO2XIdv_bVe-1jAmmlvs90LIsy2_ X-Proofpoint-GUID: n69VFA0lYLUvMLRQ8-941jETglPrWpOd X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.858,Hydra:6.0.486,FMLib:17.11.64.514 definitions=2022-05-05_02,2022-05-04_02,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 suspectscore=0 bulkscore=0 adultscore=0 clxscore=1015 lowpriorityscore=0 phishscore=0 spamscore=0 impostorscore=0 priorityscore=1501 mlxlogscore=997 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2202240000 definitions=main-2205050055 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: HAO CHEN GUI via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: HAO CHEN GUI <guihaoc@linux.ibm.com> Cc: Peter Bergner <bergner@linux.ibm.com>, David <dje.gcc@gmail.com>, Segher Boessenkool <segher@kernel.crashing.org> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
Skip constant folding for fmin/max when either argument is sNaN [PR105414]
|
|
Commit Message
HAO CHEN GUI
May 5, 2022, 8:06 a.m. UTC
Hi, This patch skips constant folding for fmin/max when either argument is sNaN. According to C standard, fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN So signaling NaN should be tested and skipped for fmin/max in match.pd. Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot. ChangeLog 2022-05-05 Haochen Gui <guihaoc@linux.ibm.com> gcc/ PR target/105414 * match.pd (minmax): Skip constant folding for fmin/fmax when both arguments are sNaN or one is sNaN and another is NaN. gcc/testsuite/ PR target/105414 * gcc.dg/pr105414.c: New. patch.diff
Comments
On Thu, May 5, 2022 at 10:07 AM HAO CHEN GUI via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Hi, > This patch skips constant folding for fmin/max when either argument > is sNaN. According to C standard, > fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN > So signaling NaN should be tested and skipped for fmin/max in match.pd. > > Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. > Is this okay for trunk? Any recommendations? Thanks a lot. OK. Thanks, Richard. > ChangeLog > > 2022-05-05 Haochen Gui <guihaoc@linux.ibm.com> > > gcc/ > PR target/105414 > * match.pd (minmax): Skip constant folding for fmin/fmax when both > arguments are sNaN or one is sNaN and another is NaN. > > gcc/testsuite/ > PR target/105414 > * gcc.dg/pr105414.c: New. > > patch.diff > > diff --git a/gcc/match.pd b/gcc/match.pd > index cad61848daa..f256bcbb483 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -3093,7 +3093,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (for minmax (min max FMIN_ALL FMAX_ALL) > (simplify > (minmax @0 @0) > - @0)) > + /* if both are sNaN, it should return qNaN. */ > + (if (!tree_expr_maybe_signaling_nan_p (@0)) > + @0))) > /* min(max(x,y),y) -> y. */ > (simplify > (min:c (max:c @0 @1) @1) > @@ -3193,12 +3195,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (minmax @1 (convert @2))))) > > (for minmax (FMIN_ALL FMAX_ALL) > - /* If either argument is NaN, return the other one. Avoid the > - transformation if we get (and honor) a signalling NaN. */ > + /* If either argument is NaN and other one is not sNaN, return the other > + one. Avoid the transformation if we get (and honor) a signalling NaN. */ > (simplify > (minmax:c @0 REAL_CST@1) > - (if (real_isnan (TREE_REAL_CST_PTR (@1)) > - && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling)) > + (if (real_isnan (TREE_REAL_CST_PTR (@1)) > + && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling) > + && !tree_expr_maybe_signaling_nan_p (@0)) > @0))) > /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these > functions to return the numeric arg if the other one is NaN. > diff --git a/gcc/testsuite/gcc.dg/pr105414.c b/gcc/testsuite/gcc.dg/pr105414.c > new file mode 100644 > index 00000000000..78772700acf > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr105414.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { *-*-linux* *-*-gnu* } } } */ > +/* { dg-options "-O1 -fsignaling-nans -lm" } */ > +/* { dg-add-options ieee } */ > +/* { dg-require-effective-target issignaling } */ > + > + > +#define _GNU_SOURCE > +#include <stdio.h> > +#include <math.h> > + > +int main() > +{ > + double a = __builtin_nans (""); > + > + if (issignaling (fmin (a, a))) > + __builtin_abort (); > + > + if (issignaling (fmax (a, a))) > + __builtin_abort (); > + > + double b = __builtin_nan (""); > + > + if (issignaling (fmin (a, b))) > + __builtin_abort (); > + > + if (issignaling (fmax (a, b))) > + __builtin_abort (); > + > + return 0; > +}
on 2022/5/5 16:09, Richard Biener via Gcc-patches wrote: > On Thu, May 5, 2022 at 10:07 AM HAO CHEN GUI via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: >> >> Hi, >> This patch skips constant folding for fmin/max when either argument >> is sNaN. According to C standard, >> fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN >> So signaling NaN should be tested and skipped for fmin/max in match.pd. >> >> Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. >> Is this okay for trunk? Any recommendations? Thanks a lot. > > OK. > > Thanks, > Richard. > >> ChangeLog >> >> 2022-05-05 Haochen Gui <guihaoc@linux.ibm.com> >> >> gcc/ >> PR target/105414 >> * match.pd (minmax): Skip constant folding for fmin/fmax when both >> arguments are sNaN or one is sNaN and another is NaN. >> >> gcc/testsuite/ >> PR target/105414 >> * gcc.dg/pr105414.c: New. >> >> patch.diff >> >> diff --git a/gcc/match.pd b/gcc/match.pd >> index cad61848daa..f256bcbb483 100644 >> --- a/gcc/match.pd >> +++ b/gcc/match.pd >> @@ -3093,7 +3093,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) >> (for minmax (min max FMIN_ALL FMAX_ALL) >> (simplify >> (minmax @0 @0) >> - @0)) >> + /* if both are sNaN, it should return qNaN. */ >> + (if (!tree_expr_maybe_signaling_nan_p (@0)) >> + @0))) Sorry for chiming in. IIUC this patch is mainly for libc function fmin/fmax and the iterator here covers min/max and fmin/fmax. I wonder if it's intent to make this change for min/max as well? As tree.def, "if either operand is NaN, then it is unspecified", the optimization for min/max seems still acceptable? BR, Kewen
On Thu, May 5, 2022 at 10:30 AM Kewen.Lin <linkw@linux.ibm.com> wrote: > > on 2022/5/5 16:09, Richard Biener via Gcc-patches wrote: > > On Thu, May 5, 2022 at 10:07 AM HAO CHEN GUI via Gcc-patches > > <gcc-patches@gcc.gnu.org> wrote: > >> > >> Hi, > >> This patch skips constant folding for fmin/max when either argument > >> is sNaN. According to C standard, > >> fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN > >> So signaling NaN should be tested and skipped for fmin/max in match.pd. > >> > >> Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. > >> Is this okay for trunk? Any recommendations? Thanks a lot. > > > > OK. > > > > Thanks, > > Richard. > > > >> ChangeLog > >> > >> 2022-05-05 Haochen Gui <guihaoc@linux.ibm.com> > >> > >> gcc/ > >> PR target/105414 > >> * match.pd (minmax): Skip constant folding for fmin/fmax when both > >> arguments are sNaN or one is sNaN and another is NaN. > >> > >> gcc/testsuite/ > >> PR target/105414 > >> * gcc.dg/pr105414.c: New. > >> > >> patch.diff > >> > >> diff --git a/gcc/match.pd b/gcc/match.pd > >> index cad61848daa..f256bcbb483 100644 > >> --- a/gcc/match.pd > >> +++ b/gcc/match.pd > >> @@ -3093,7 +3093,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > >> (for minmax (min max FMIN_ALL FMAX_ALL) > >> (simplify > >> (minmax @0 @0) > >> - @0)) > >> + /* if both are sNaN, it should return qNaN. */ > >> + (if (!tree_expr_maybe_signaling_nan_p (@0)) > >> + @0))) > > Sorry for chiming in. > > IIUC this patch is mainly for libc function fmin/fmax and the iterator here > covers min/max and fmin/fmax. I wonder if it's intent to make this change > for min/max as well? > > As tree.def, "if either operand is NaN, then it is unspecified", the optimization > for min/max seems still acceptable? MIN/MAX_EXPR shouldn't even appear with -fsignalling-nans for this reason, at least that's what I thought. But yes, you might have a point here (but maybe it's also not strictly enough specified). One option would be to do (minmax == MAX_EXPR || minmax == MIN_EXPR || !tree_expr ...) Joseph - are MIN_EXPR and MAX_EXPR supposed to turn sNaN into qNaN and the 'undefinedness' is merely as to which operand is chosen? Richard. > > BR, > Kewen
On 5/5/2022 下午 4:30, Kewen.Lin wrote: > on 2022/5/5 16:09, Richard Biener via Gcc-patches wrote: >> On Thu, May 5, 2022 at 10:07 AM HAO CHEN GUI via Gcc-patches >> <gcc-patches@gcc.gnu.org> wrote: >>> >>> Hi, >>> This patch skips constant folding for fmin/max when either argument >>> is sNaN. According to C standard, >>> fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN >>> So signaling NaN should be tested and skipped for fmin/max in match.pd. >>> >>> Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. >>> Is this okay for trunk? Any recommendations? Thanks a lot. >> >> OK. >> >> Thanks, >> Richard. >> >>> ChangeLog >>> >>> 2022-05-05 Haochen Gui <guihaoc@linux.ibm.com> >>> >>> gcc/ >>> PR target/105414 >>> * match.pd (minmax): Skip constant folding for fmin/fmax when both >>> arguments are sNaN or one is sNaN and another is NaN. >>> >>> gcc/testsuite/ >>> PR target/105414 >>> * gcc.dg/pr105414.c: New. >>> >>> patch.diff >>> >>> diff --git a/gcc/match.pd b/gcc/match.pd >>> index cad61848daa..f256bcbb483 100644 >>> --- a/gcc/match.pd >>> +++ b/gcc/match.pd >>> @@ -3093,7 +3093,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) >>> (for minmax (min max FMIN_ALL FMAX_ALL) >>> (simplify >>> (minmax @0 @0) >>> - @0)) >>> + /* if both are sNaN, it should return qNaN. */ >>> + (if (!tree_expr_maybe_signaling_nan_p (@0)) >>> + @0))) > > Sorry for chiming in. > > IIUC this patch is mainly for libc function fmin/fmax and the iterator here > covers min/max and fmin/fmax. I wonder if it's intent to make this change > for min/max as well? > > As tree.def, "if either operand is NaN, then it is unspecified", the optimization > for min/max seems still acceptable? For MIN/MAX_EXPR, the result is undefined with NaN. So I think we shouldn't do constant folding. We should let target decide how to deal with it. The "undefined" here means the result depends on targets as far as I understand. > > BR, > Kewen
Hi! On Thu, May 05, 2022 at 05:30:58PM +0800, HAO CHEN GUI wrote: > On 5/5/2022 下午 4:30, Kewen.Lin wrote: > > on 2022/5/5 16:09, Richard Biener via Gcc-patches wrote: > >> On Thu, May 5, 2022 at 10:07 AM HAO CHEN GUI via Gcc-patches > >> <gcc-patches@gcc.gnu.org> wrote: > >>> This patch skips constant folding for fmin/max when either argument > >>> is sNaN. According to C standard, > >>> fmin(sNaN, sNaN)= qNaN, fmin(sNaN, NaN) = qNaN > >>> So signaling NaN should be tested and skipped for fmin/max in match.pd. > >>> > >>> Bootstrapped and tested on ppc64 Linux BE and LE with no regressions. The C standard does not talk about sNaNs *at all*, in any released version of the standard. And the C2x drafts do not talk about signaling arguments for fmin/fmax specifically, so it should just raise an error like any other floating operation with an sNaN arg will. This means we have to make sure to not optimise away all operations if there may be an sNaN (and we have HONOR_SNANS for the mode in use). You never have to convert to a qNaN manually. Instead, any normal operation on the sNaN will raise the exception, and convert to the qNaN. There is no sane way you can raise the exception manually, so you should make sure we end up with a real operation in the RTL, and then generate proper machine code for it as well. See rs6000 extendsfdf2 for example, for that last part. And of course both the gimple min_expr and the RTL smin are not defined for NaN inputs at all anyway :-P Segher
On Thu, 5 May 2022, Richard Biener via Gcc-patches wrote: > MIN/MAX_EXPR shouldn't even appear with -fsignalling-nans for this > reason, at least that's what I thought. But yes, you might have a point > here (but maybe it's also not strictly enough specified). One option would > be to do (minmax == MAX_EXPR || minmax == MIN_EXPR || !tree_expr ...) > > Joseph - are MIN_EXPR and MAX_EXPR supposed to turn sNaN into qNaN > and the 'undefinedness' is merely as to which operand is chosen? I don't know what MIN_EXPR and MAX_EXPR are supposed to do with sNaN arguments. As noted, the fmax and fmin functions should produce a qNaN result with the "invalid" exception raised (so with an sNaN argument, it's definitely not valid to fold them in the absence of -fno-trapping-math; with -fsignaling-nans -fno-trapping-math, if an argument is known to be sNaN it would be valid to fold to qNaN, but I doubt there's much use of that option combination). C never attempts to define which qNaN result (choice of payload or sign bit) is produced by an operation and I don't think our optimizations should be trying to define that (with any command-line options currently supported) either (other than for non-computational operations such as fabs and copysign, but even there there is scope for implementation-defined handling of assignment as a convertFormat operation rather than a copy operation). Note that while some architectures propagate NaN payloads from a NaN operand to an instruction, others (e.g. RISC-V) do not, and when payloads are propagated there would still be the matter of which payload is chosen when there is more than one NaN operand (on x86, that is handled differently for SSE and x87 instructions).
On Thu, May 5, 2022 at 7:11 PM Joseph Myers <joseph@codesourcery.com> wrote: > > On Thu, 5 May 2022, Richard Biener via Gcc-patches wrote: > > > MIN/MAX_EXPR shouldn't even appear with -fsignalling-nans for this > > reason, at least that's what I thought. But yes, you might have a point > > here (but maybe it's also not strictly enough specified). One option would > > be to do (minmax == MAX_EXPR || minmax == MIN_EXPR || !tree_expr ...) > > > > Joseph - are MIN_EXPR and MAX_EXPR supposed to turn sNaN into qNaN > > and the 'undefinedness' is merely as to which operand is chosen? > > I don't know what MIN_EXPR and MAX_EXPR are supposed to do with sNaN > arguments. As noted, the fmax and fmin functions should produce a qNaN > result with the "invalid" exception raised (so with an sNaN argument, it's > definitely not valid to fold them in the absence of -fno-trapping-math; > with -fsignaling-nans -fno-trapping-math, if an argument is known to be > sNaN it would be valid to fold to qNaN, but I doubt there's much use of > that option combination). > > C never attempts to define which qNaN result (choice of payload or sign > bit) is produced by an operation and I don't think our optimizations > should be trying to define that (with any command-line options currently > supported) either (other than for non-computational operations such as > fabs and copysign, but even there there is scope for > implementation-defined handling of assignment as a convertFormat operation > rather than a copy operation). Note that while some architectures > propagate NaN payloads from a NaN operand to an instruction, others (e.g. > RISC-V) do not, and when payloads are propagated there would still be the > matter of which payload is chosen when there is more than one NaN operand > (on x86, that is handled differently for SSE and x87 instructions). Thanks. So I think the patch as posted is correct on the safe side in letting the CPU to decide what happens with sNaNs. As said, the chance seeing an sNaN and MAX/MIN_EXPR is low. So I'm defering to the poster if he wants to re-post with treating MIN/MAX_EXPR special in the optimistic sense. Richard. > -- > Joseph S. Myers > joseph@codesourcery.com
diff --git a/gcc/match.pd b/gcc/match.pd index cad61848daa..f256bcbb483 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3093,7 +3093,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for minmax (min max FMIN_ALL FMAX_ALL) (simplify (minmax @0 @0) - @0)) + /* if both are sNaN, it should return qNaN. */ + (if (!tree_expr_maybe_signaling_nan_p (@0)) + @0))) /* min(max(x,y),y) -> y. */ (simplify (min:c (max:c @0 @1) @1) @@ -3193,12 +3195,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (minmax @1 (convert @2))))) (for minmax (FMIN_ALL FMAX_ALL) - /* If either argument is NaN, return the other one. Avoid the - transformation if we get (and honor) a signalling NaN. */ + /* If either argument is NaN and other one is not sNaN, return the other + one. Avoid the transformation if we get (and honor) a signalling NaN. */ (simplify (minmax:c @0 REAL_CST@1) - (if (real_isnan (TREE_REAL_CST_PTR (@1)) - && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling)) + (if (real_isnan (TREE_REAL_CST_PTR (@1)) + && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling) + && !tree_expr_maybe_signaling_nan_p (@0)) @0))) /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these functions to return the numeric arg if the other one is NaN. diff --git a/gcc/testsuite/gcc.dg/pr105414.c b/gcc/testsuite/gcc.dg/pr105414.c new file mode 100644 index 00000000000..78772700acf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105414.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { *-*-linux* *-*-gnu* } } } */ +/* { dg-options "-O1 -fsignaling-nans -lm" } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target issignaling } */ + + +#define _GNU_SOURCE +#include <stdio.h> +#include <math.h> + +int main() +{ + double a = __builtin_nans (""); + + if (issignaling (fmin (a, a))) + __builtin_abort (); + + if (issignaling (fmax (a, a))) + __builtin_abort (); + + double b = __builtin_nan (""); + + if (issignaling (fmin (a, b))) + __builtin_abort (); + + if (issignaling (fmax (a, b))) + __builtin_abort (); + + return 0; +}