public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] match.pd: Don't fold nan < x etc. for -ftrapping-math [PR106805]
Date: Mon, 5 Dec 2022 11:50:27 +0100	[thread overview]
Message-ID: <B2C1EC19-0282-455D-8752-4111D9AAC9C7@suse.de> (raw)
In-Reply-To: <Y43H+LkdiDQjILIU@tucnak>



> Am 05.12.2022 um 11:30 schrieb Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org>:
> 
> Hi!
> 
> As reported in the PR, the following pr106805.c testcase is miscompiled
> with the default -ftrapping-math, because we fold all the comparisons into
> constants and don't raise any exceptions.
> 
> The match.pd pattern handles just simple comparisons, from those
> EQ/NE are quiet and don't raise exceptions on anything but sNaN, while
> GT/GE/LT/LE are signaling and do raise exceptions even on qNaN.
> 
> fold_relational_const handles this IMHO correctly:
>      /* Handle the cases where either operand is a NaN.  */
>      if (real_isnan (c0) || real_isnan (c1))
>        {
>          switch (code)
>            {
>            case EQ_EXPR:
>            case ORDERED_EXPR:
>              result = 0;
>              break;
> 
>            case NE_EXPR:
>            case UNORDERED_EXPR:
>            case UNLT_EXPR:
>            case UNLE_EXPR:
>            case UNGT_EXPR:
>            case UNGE_EXPR:
>            case UNEQ_EXPR:
>              result = 1;
>              break;
> 
>            case LT_EXPR:
>            case LE_EXPR:
>            case GT_EXPR:
>            case GE_EXPR:
>            case LTGT_EXPR:
>              if (flag_trapping_math)
>                return NULL_TREE;
>              result = 0;
>              break;
> 
>            default:
>              gcc_unreachable ();
>            }
> 
>          return constant_boolean_node (result, type);
>        }
> by folding the signaling comparisons only if -fno-trapping-math.
> The following patch does the same in match.pd.
> 
> Unfortunately the pr106805.c testcase still fails, but no longer because of
> match.pd, but on the trunk because of the still unresolved ranger problems
> (same issue as for fold-overflow-1.c etc.) and on 12 branch (and presumably
> trunk too) somewhere during expansion the comparisons are also expanded
> into constants (which is ok for -fno-trapping-math, but not ok with that).
> 
> Though, I think the patch is a small step in the direction, so I'd like
> to commit this patch without the gcc.dg/pr106805.c testcase for now.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, appart from the
> +FAIL: gcc.dg/pr106805.c execution test
> nothing else appears.  Ok for trunk without the last testcase?

Ok.

Richard 

> 2022-12-05  Jakub Jelinek  <jakub@redhat.com>
> 
>    PR middle-end/106805
>    * match.pd (cmp @0 REAL_CST@1): Don't optimize x cmp NaN
>    or NaN cmp x to false/true for cmp >/>=/</<= if -ftrapping-math.
> 
>    * c-c++-common/pr57371-4.c: Revert 2021-09-19 changes.
>    * c-c++-common/pr57371-5.c: New test.
>    * gcc.c-torture/execute/ieee/fp-cmp-6.x: Add -fno-trapping-math.
>    * gcc.c-torture/execute/ieee/fp-cmp-9.c: New test. 
>    * gcc.c-torture/execute/ieee/fp-cmp-9.x: New file.
>    * gcc.dg/pr106805.c: New test.
> 
> --- gcc/match.pd.jj    2022-12-02 10:28:30.000000000 +0100
> +++ gcc/match.pd    2022-12-02 12:50:28.701735269 +0100
> @@ -5146,12 +5146,14 @@ (define_operator_list SYNC_FETCH_AND_AND
>     (cmp { build_real (TREE_TYPE (@0), dconst0); } @1))
>    /* x != NaN is always true, other ops are always false.  */
>    (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
> +    && (cmp == EQ_EXPR || cmp == NE_EXPR || !flag_trapping_math)
>    && !tree_expr_signaling_nan_p (@1)
>    && !tree_expr_maybe_signaling_nan_p (@0))
>     { constant_boolean_node (cmp == NE_EXPR, type); })
>    /* NaN != y is always true, other ops are always false.  */
>    (if (TREE_CODE (@0) == REAL_CST
>    && REAL_VALUE_ISNAN (TREE_REAL_CST (@0))
> +    && (cmp == EQ_EXPR || cmp == NE_EXPR || !flag_trapping_math)
>         && !tree_expr_signaling_nan_p (@0)
>         && !tree_expr_signaling_nan_p (@1))
>     { constant_boolean_node (cmp == NE_EXPR, type); })
> --- gcc/testsuite/c-c++-common/pr57371-4.c.jj    2022-04-28 15:56:07.137787247 +0200
> +++ gcc/testsuite/c-c++-common/pr57371-4.c    2022-12-02 13:34:03.076882811 +0100
> @@ -13,25 +13,25 @@ void nonfinite(unsigned short x) {
>   {
>     volatile int nonfinite_1;
>     nonfinite_1 = (float) x > QNAN;
> -    /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */
> +    /* { dg-final { scan-tree-dump "nonfinite_1 = \\(float\\)" "original" } } */
>   }
> 
>   {
>     volatile int nonfinite_2;
>     nonfinite_2 = (float) x >= QNAN;
> -    /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */
> +    /* { dg-final { scan-tree-dump "nonfinite_2 = \\(float\\)" "original" } } */
>   }
> 
>   {
>     volatile int nonfinite_3;
>     nonfinite_3 = (float) x < QNAN;
> -    /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */
> +    /* { dg-final { scan-tree-dump "nonfinite_3 = \\(float\\)" "original" } } */
>   }
> 
>   {
>     volatile int nonfinite_4;
>     nonfinite_4 = (float) x <= QNAN;
> -    /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */
> +    /* { dg-final { scan-tree-dump "nonfinite_4 = \\(float\\)" "original" } } */
>   }
> 
>   {
> --- gcc/testsuite/c-c++-common/pr57371-5.c.jj    2022-12-02 13:34:14.397714696 +0100
> +++ gcc/testsuite/c-c++-common/pr57371-5.c    2022-12-02 13:35:05.915949599 +0100
> @@ -0,0 +1,47 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fno-signaling-nans -fno-trapping-math -fdump-tree-original" } */
> +
> +/* We can not get rid of comparison in tests below because of
> +   pending NaN exceptions.
> +
> +   TODO: avoid under -fno-trapping-math.  */
> +
> +#define QNAN __builtin_nanf ("0")
> +
> +void nonfinite(unsigned short x) {
> +  {
> +    volatile int nonfinite_1;
> +    nonfinite_1 = (float) x > QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */
> +  }
> +
> +  {
> +    volatile int nonfinite_2;
> +    nonfinite_2 = (float) x >= QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */
> +  }
> +
> +  {
> +    volatile int nonfinite_3;
> +    nonfinite_3 = (float) x < QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */
> +  }
> +
> +  {
> +    volatile int nonfinite_4;
> +    nonfinite_4 = (float) x <= QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */
> +  }
> +
> +  {
> +    volatile int nonfinite_11;
> +    nonfinite_11 = (float) x == QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_11 = 0" "original" } } */
> +  }
> +
> +  {
> +    volatile int nonfinite_12;
> +    nonfinite_12 = (float) x != QNAN;
> +    /* { dg-final { scan-tree-dump "nonfinite_12 = 1" "original" } } */
> +  }
> +}
> --- gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x.jj    2020-01-14 20:02:47.175603962 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x    2022-12-05 10:44:10.037871848 +0100
> @@ -1,3 +1,4 @@
> +lappend additional_flags "-fno-trapping-math"
> # The ARM VxWorks kernel uses an external floating-point library in
> # which routines like __ledf2 are just aliases for __cmpdf2.  These
> # routines therefore don't handle NaNs correctly.
> --- gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c.jj    2022-12-05 10:44:21.406705781 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c    2022-12-05 10:44:57.237182398 +0100
> @@ -0,0 +1,31 @@
> +
> +const double dnan = 1.0/0.0 - 1.0/0.0;
> +double x = 1.0;
> +
> +extern void link_error (void);
> +extern void abort (void);
> +
> +main ()
> +{
> +#if ! defined (__vax__) && ! defined (_CRAY)
> +  /* NaN is an IEEE unordered operand.  All these test should be false.  */
> +  if (dnan == dnan)
> +    link_error ();
> +  if (dnan != x)
> +    x = 1.0;
> +  else
> +    link_error ();
> +
> +  if (dnan == x)
> +    link_error ();
> +#endif
> +  exit (0);
> +}
> +
> +#ifndef __OPTIMIZE__
> +void link_error (void)
> +{
> +  abort ();
> +}
> +#endif
> +
> --- gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x.jj    2022-12-05 10:44:30.338575309 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x    2022-12-05 10:44:32.991536565 +0100
> @@ -0,0 +1,16 @@
> +# The ARM VxWorks kernel uses an external floating-point library in
> +# which routines like __ledf2 are just aliases for __cmpdf2.  These
> +# routines therefore don't handle NaNs correctly.
> +if [istarget "arm*-*-vxworks*"] {
> +    set torture_eval_before_execute {
> +    global compiler_conditional_xfail_data
> +    set compiler_conditional_xfail_data {
> +        "The ARM kernel uses a flawed floating-point library."
> +        { "*-*-*" }
> +        { "-O0" }
> +        { "-mrtp" }
> +    }
> +    }
> +}
> +
> +return 0
> --- gcc/testsuite/gcc.dg/pr106805.c.jj    2022-12-02 13:02:06.813354371 +0100
> +++ gcc/testsuite/gcc.dg/pr106805.c    2022-12-02 13:11:42.844792390 +0100
> @@ -0,0 +1,29 @@
> +/* PR middle-end/106805 */
> +/* { dg-do run } */
> +/* { dg-options "-O2 -ftrapping-math" } */
> +/* { dg-add-options ieee } */
> +/* { dg-require-effective-target fenv_exceptions_double } */
> +
> +#include <fenv.h>
> +#include <stdlib.h>
> +
> +static inline int
> +foo (double x, double y)
> +{
> +  return x >= y && x <= y;
> +}
> +
> +int
> +main ()
> +{
> +  double x = __builtin_nan ("");
> +  volatile int r;
> +  r = foo (__builtin_nan (""), 1.0);
> +  if (!fetestexcept (FE_INVALID))
> +    abort ();
> +  feclearexcept (FE_ALL_EXCEPT);
> +  r = foo (x, __builtin_inf ());
> +  if (!fetestexcept (FE_INVALID))
> +    abort ();
> +  return 0;
> +}
> 
>    Jakub
> 

      reply	other threads:[~2022-12-05 10:50 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-05 10:29 Jakub Jelinek
2022-12-05 10:50 ` Richard Biener [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=B2C1EC19-0282-455D-8752-4111D9AAC9C7@suse.de \
    --to=rguenther@suse.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).