From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mengyan1223.wang (mengyan1223.wang [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 794F7385843B for ; Mon, 31 Jan 2022 10:07:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 794F7385843B Received: from [IPv6:240e:358:11f7:4800:dc73:854d:832e:3] (unknown [IPv6:240e:358:11f7:4800:dc73:854d:832e:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@mengyan1223.wang) by mengyan1223.wang (Postfix) with ESMTPSA id B480165985; Mon, 31 Jan 2022 05:07:07 -0500 (EST) Message-ID: Subject: Re: [PATCH] fold-const: do not fold 'inf/inf' with -ftrapping-math [PR95115] From: Xi Ruoyao To: Richard Biener , "Joseph S. Myers" Cc: GCC Patches Date: Mon, 31 Jan 2022 18:07:01 +0800 In-Reply-To: References: <8b49a9906a0d1019bd877bf526f71ab5321550fe.camel@mengyan1223.wang> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.42.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3037.7 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, SPF_HELO_PASS, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Jan 2022 10:07:13 -0000 On Mon, 2022-01-31 at 10:35 +0100, Richard Biener wrote: > On Sun, Jan 30, 2022 at 7:39 PM Xi Ruoyao via Gcc-patches > wrote: > > > > 'inf/inf' should raise an invalid operation exception at runtime.  > > So it > > should not be folded during compilation unless -fno-trapping-math is > > used. > > I wonder if it would make sense to handle it similar to > >       inexact = real_arithmetic (&value, code, &d1, &d2); >       real_convert (&result, mode, &value); > >       /* Don't constant fold this floating point operation if >          the result has overflowed and flag_trapping_math.  */ >       if (flag_trapping_math >           && MODE_HAS_INFINITIES (mode) >           && REAL_VALUE_ISINF (result) >           && !REAL_VALUE_ISINF (d1) >           && !REAL_VALUE_ISINF (d2)) >         return NULL_TREE; > thus whenever we fold to NaN but flag_trapping_math is set, > do not fold? Like this? inexact = real_arithmetic (&value, code, &d1, &d2); real_convert (&result, mode, &value); + /* Don't constant fold this floating point operation if + both operands are not NaN but the result is NaN, and + flag_trapping_math. Such operations should raise an + invalid operation exception. */ + if (flag_trapping_math + && MODE_HAS_NANS (mode) + && REAL_VALUE_ISNAN (result) + && !REAL_VALUE_ISNAN (d1) + && !REAL_VALUE_ISNAN (d2)) + return NULL_TREE; + /* Don't constant fold this floating point operation if the result has overflowed and flag_trapping_math. */ if (flag_trapping_math > We already exclude NaN operands earlier > (but unconditionally return NaN even for NaN + 1. though > that should raise invalid as well, no?) qNaN + 1 (or even qNaN + qNaN) should produce a qNaN but should not raise any exception. OTOH sNaN + 1 should produce a qNaN and raise an invalid operation exception. For sNaN operands we already ruled out the const folding earlier: > /* Don't perform operation if we honor signaling NaNs and > either operand is a signaling NaN. */ > if (HONOR_SNANS (mode) > && (REAL_VALUE_ISSIGNALING_NAN (d1) > || REAL_VALUE_ISSIGNALING_NAN (d2))) > return NULL_TREE; > I suppose Joseph should know best what the correct semantics > are here. > > Thanks, > Richard. > > > gcc/ > >         PR middle-end/95115 > >         * fold-const.cc (const_binop): Do not fold "inf/inf". > > > > gcc/testsuite > >         * gcc.dg/pr95115.c: New test. > > --- > >  gcc/fold-const.cc              |  8 ++++++++ > >  gcc/testsuite/gcc.dg/pr95115.c | 25 +++++++++++++++++++++++++ > >  2 files changed, 33 insertions(+) > >  create mode 100644 gcc/testsuite/gcc.dg/pr95115.c > > > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > > index fd9c6352d4f..0e99d5a2e3d 100644 > > --- a/gcc/fold-const.cc > > +++ b/gcc/fold-const.cc > > @@ -1283,6 +1283,14 @@ const_binop (enum tree_code code, tree arg1, > > tree arg2) > >           && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode))) > >         return NULL_TREE; > > > > +      /* Don't perform "inf/inf", because it would raise an invalid > > +        operation exception (IEEE 754 section 7.2 clause d).  */ > > +      if (code == RDIV_EXPR > > +         && flag_trapping_math > > +         && REAL_VALUE_ISINF (d1) > > +         && REAL_VALUE_ISINF (d2)) > > +       return NULL_TREE; > > + > >        /* If either operand is a NaN, just return it.  Otherwise, > > set up > >          for floating-point trap; we return an overflow.  */ > >        if (REAL_VALUE_ISNAN (d1)) > > diff --git a/gcc/testsuite/gcc.dg/pr95115.c > > b/gcc/testsuite/gcc.dg/pr95115.c > > new file mode 100644 > > index 00000000000..46a95dfb698 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/pr95115.c > > @@ -0,0 +1,25 @@ > > +/* { dg-do run } */ > > +/* { dg-options "-O2 -ftrapping-math" } */ > > +/* { dg-add-options ieee } */ > > +/* { dg-require-effective-target fenv_exceptions } */ > > + > > +#include > > +#include > > + > > +double > > +x (void) > > +{ > > +  double d = __builtin_inf (); > > +  return d / d; > > +} > > + > > +int > > +main (void) > > +{ > > +  double r = x (); > > +  if (!__builtin_isnan (r)) > > +       abort (); > > +  if (!fetestexcept (FE_INVALID)) > > +       abort (); > > +  exit (0); > > +} > > -- > > 2.35.1 > > > > -- Xi Ruoyao School of Aerospace Science and Technology, Xidian University