public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: FX <fxcoudert@gmail.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc@gcc.gnu.org, "Joseph S. Myers" <joseph@codesourcery.com>,
	FX via Fortran <fortran@gcc.gnu.org>
Subject: Re: Floating-point comparisons in the middle-end
Date: Thu, 1 Sep 2022 12:06:14 +0200	[thread overview]
Message-ID: <E72E260E-69AC-4A3E-9349-F0A037DDCAC9@gmail.com> (raw)
In-Reply-To: <YxB6GGjkTdUFY+iz@tucnak>

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

Hi,

> Dunno if we really need a builtin for this, especially if it is lowered
> to that x >= y && x <= y early, will defer to Joseph.

I think it’d be nice to have one for consistency, as the other standard floating-point functions are there. It would also make things slightly easier for our Fortran implementation, although admittedly we can do without.

A tentative patch is attached, it seems to work well on simple examples, but for test coverage the hard part is going to be that the comparisons seem to be optimised away very easily into their non-signaling versions. Basically, if I do:

  float x = __builtin_nanf("");
  printf("%d\n", __builtin_iseqsig(__builtin_nanf(""), __builtin_inff()));
  printf("%d\n", __builtin_iseqsig(x, __builtin_inff()));

With -O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans: first one does not raise invalid, second one does.
With -O2 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans: no invalid raised at all.

FX


[-- Attachment #2: iseqsig.diff --]
[-- Type: application/octet-stream, Size: 4360 bytes --]

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index f1f7c0ce337..bf6bf2809d8 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -171,6 +171,7 @@ static tree fold_builtin_fabs (location_t, tree, tree);
 static tree fold_builtin_abs (location_t, tree, tree);
 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
 					enum tree_code);
+static tree fold_builtin_iseqsig (location_t, tree, tree);
 static tree fold_builtin_varargs (location_t, tree, tree*, int);
 
 static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree);
@@ -9404,6 +9405,42 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
 		      fold_build2_loc (loc, code, type, arg0, arg1));
 }
 
+/* Fold a call to __builtin_iseqsig().  ARG0 and ARG1 are the arguments.
+   After choosing the wider floating-point type for the comparison,
+   the code is folded to:
+     SAVE_EXPR<ARG0> >= SAVE_EXPR<ARG1> && SAVE_EXPR<ARG0> <= SAVE_EXPR<ARG1>  */
+
+static tree
+fold_builtin_iseqsig (location_t loc, tree arg0, tree arg1)
+{
+  tree type0, type1;
+  enum tree_code code0, code1;
+  tree cmp1, cmp2, cmp_type = NULL_TREE;
+
+  type0 = TREE_TYPE (arg0);
+  type1 = TREE_TYPE (arg1);
+
+  code0 = TREE_CODE (type0);
+  code1 = TREE_CODE (type1);
+
+  if (code0 == REAL_TYPE && code1 == REAL_TYPE)
+    /* Choose the wider of two real types.  */
+    cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
+      ? type0 : type1;
+  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
+    cmp_type = type0;
+  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
+    cmp_type = type1;
+
+  arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0));
+  arg1 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg1));
+
+  cmp1 = fold_build2_loc (loc, GE_EXPR, integer_type_node, arg0, arg1);
+  cmp2 = fold_build2_loc (loc, LE_EXPR, integer_type_node, arg0, arg1);
+
+  return fold_build2_loc (loc, TRUTH_AND_EXPR, integer_type_node, cmp1, cmp2);
+}
+
 /* Fold __builtin_{,s,u}{add,sub,mul}{,l,ll}_overflow, either into normal
    arithmetics if it can never overflow, or into internal functions that
    return both result of arithmetics and overflowed boolean flag in
@@ -9791,6 +9828,9 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1)
 					 arg0, arg1, UNORDERED_EXPR,
 					 NOP_EXPR);
 
+    case BUILT_IN_ISEQSIG:
+      return fold_builtin_iseqsig (loc, arg0, arg1);
+
       /* We do the folding for va_start in the expander.  */
     case BUILT_IN_VA_START:
       break;
@@ -11303,6 +11343,7 @@ is_inexpensive_builtin (tree decl)
       case BUILT_IN_ISLESSEQUAL:
       case BUILT_IN_ISLESSGREATER:
       case BUILT_IN_ISUNORDERED:
+      case BUILT_IN_ISEQSIG:
       case BUILT_IN_VA_ARG_PACK:
       case BUILT_IN_VA_ARG_PACK_LEN:
       case BUILT_IN_VA_COPY:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index f0236316850..8fab9dc3f1b 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -908,6 +908,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOT
 DEF_GCC_BUILTIN        (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
 DEF_GCC_BUILTIN        (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
 DEF_GCC_BUILTIN        (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
+DEF_GCC_BUILTIN        (BUILT_IN_ISEQSIG, "iseqsig", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
 DEF_GCC_BUILTIN        (BUILT_IN_ISSIGNALING, "issignaling", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 1eb842e1c7b..44d30436e47 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -6330,6 +6330,7 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
     case BUILT_IN_ISLESSEQUAL:
     case BUILT_IN_ISLESSGREATER:
     case BUILT_IN_ISUNORDERED:
+    case BUILT_IN_ISEQSIG:
       if (builtin_function_validate_nargs (loc, fndecl, nargs, 2))
 	{
 	  enum tree_code code0, code1;

  reply	other threads:[~2022-09-01 10:06 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-01  8:04 FX
2022-09-01  8:19 ` Jakub Jelinek
2022-09-01  9:04   ` FX
2022-09-01  9:23     ` Jakub Jelinek
2022-09-01 10:06       ` FX [this message]
2022-09-01 15:21         ` Joseph Myers
2022-09-01 15:57           ` Marc Glisse
2022-09-01 16:22             ` Joseph Myers
2022-09-01 16:24           ` FX
2022-09-01 16:44             ` Joseph Myers
2022-09-01 18:15               ` FX
2022-09-01 14:32   ` Segher Boessenkool
2022-09-01 15:19 ` Joseph Myers
2022-09-01 18:38   ` FX
2022-09-01 19:13     ` Joseph Myers
2022-09-01 18:47   ` FX
2022-09-01 19:16     ` Joseph Myers

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=E72E260E-69AC-4A3E-9349-F0A037DDCAC9@gmail.com \
    --to=fxcoudert@gmail.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.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).