aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.cc
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2022-09-01 22:49:49 +0200
committerFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2023-07-20 10:48:17 +0200
commit34cf27a64e7af949538e65bc266963c24f8da458 (patch)
tree2b6a08c8d6cd5973424ec90803599a20e8286423 /gcc/builtins.cc
parentbb42f05d0738bddc721e838ebe9993df39ff2e0f (diff)
downloadgcc-34cf27a64e7af949538e65bc266963c24f8da458.zip
gcc-34cf27a64e7af949538e65bc266963c24f8da458.tar.gz
gcc-34cf27a64e7af949538e65bc266963c24f8da458.tar.bz2
Add __builtin_iseqsig()
iseqsig() is a C2x library function, for signaling floating-point equality checks. Provide a GCC-builtin for it, which is folded to a series of comparisons. 2022-09-01 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR middle-end/77928 gcc/ * doc/extend.texi: Document iseqsig builtin. * builtins.cc (fold_builtin_iseqsig): New function. (fold_builtin_2): Handle BUILT_IN_ISEQSIG. (is_inexpensive_builtin): Handle BUILT_IN_ISEQSIG. * builtins.def (BUILT_IN_ISEQSIG): New built-in. gcc/c-family/ * c-common.cc (check_builtin_function_arguments): Handle BUILT_IN_ISEQSIG. gcc/testsuite/ * gcc.dg/torture/builtin-iseqsig-1.c: New test. * gcc.dg/torture/builtin-iseqsig-2.c: New test. * gcc.dg/torture/builtin-iseqsig-3.c: New test.
Diffstat (limited to 'gcc/builtins.cc')
-rw-r--r--gcc/builtins.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 6dff521..e2e99d6 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);
@@ -9445,6 +9446,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
@@ -9878,6 +9915,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;
@@ -11396,6 +11436,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: