mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-24 07:30:31 +08:00
builtins.c (fold_builtin_classify): New.
gcc/ChangeLog: 2004-07-01 Paolo Bonzini <bonzini@gnu.org> * builtins.c (fold_builtin_classify): New. (fold_builtin_unordered_cmp): Fix commentary. (fold_builtin): Use it. * builtins.def: Define builtins for isnan, isnanf, isnanl, finite, finitef, finitel, isinf, isinff, isinfl. gcc/testsuite/ChangeLog: 2004-07-01 Paolo Bonzini <bonzini@gnu.org> * gcc.dg/builtins-43.c: New. * gcc.dg/builtins-44.c: New. * gcc.dg/builtins-45.c: New. From-SVN: r83960
This commit is contained in:
parent
1ea463a273
commit
64a9295a72
@ -1,3 +1,12 @@
|
||||
2004-07-01 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* builtins.c (fold_builtin_classify): New.
|
||||
(fold_builtin_unordered_cmp): Fix commentary.
|
||||
(fold_builtin): Use it.
|
||||
* builtins.def: Define builtins for isnan,
|
||||
isnanf, isnanl, finite, finitef, finitel,
|
||||
isinf, isinff, isinfl.
|
||||
|
||||
2004-07-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* function.h (struct function): Remove dont_emit_block_notes.
|
||||
|
111
gcc/builtins.c
111
gcc/builtins.c
@ -7611,12 +7611,98 @@ fold_builtin_abs (tree arglist, tree type)
|
||||
return fold (build1 (ABS_EXPR, type, arg));
|
||||
}
|
||||
|
||||
/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
|
||||
EXP is the CALL_EXPR for the call. */
|
||||
|
||||
static tree
|
||||
fold_builtin_classify (tree exp, int builtin_index)
|
||||
{
|
||||
tree fndecl = get_callee_fndecl (exp);
|
||||
tree arglist = TREE_OPERAND (exp, 1);
|
||||
tree type = TREE_TYPE (TREE_TYPE (fndecl));
|
||||
tree arg;
|
||||
REAL_VALUE_TYPE r;
|
||||
|
||||
if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
|
||||
{
|
||||
/* Check that we have exactly one argument. */
|
||||
if (arglist == 0)
|
||||
{
|
||||
error ("too few arguments to function `%s'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CHAIN (arglist) != 0)
|
||||
{
|
||||
error ("too many arguments to function `%s'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("non-floating-point argument to function `%s'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
arg = TREE_VALUE (arglist);
|
||||
switch (builtin_index)
|
||||
{
|
||||
case BUILT_IN_ISINF:
|
||||
if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
|
||||
return omit_one_operand (type, integer_zero_node, arg);
|
||||
|
||||
if (TREE_CODE (arg) == REAL_CST)
|
||||
{
|
||||
r = TREE_REAL_CST (arg);
|
||||
if (real_isinf (&r))
|
||||
return real_compare (GT_EXPR, &r, &dconst0)
|
||||
? integer_one_node : integer_minus_one_node;
|
||||
else
|
||||
return integer_zero_node;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
||||
case BUILT_IN_ISFINITE:
|
||||
if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
|
||||
&& !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
|
||||
return omit_one_operand (type, integer_zero_node, arg);
|
||||
|
||||
if (TREE_CODE (arg) == REAL_CST)
|
||||
{
|
||||
r = TREE_REAL_CST (arg);
|
||||
return real_isinf (&r) || real_isnan (&r)
|
||||
? integer_zero_node : integer_one_node;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
||||
case BUILT_IN_ISNAN:
|
||||
if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
|
||||
return omit_one_operand (type, integer_zero_node, arg);
|
||||
|
||||
if (TREE_CODE (arg) == REAL_CST)
|
||||
{
|
||||
r = TREE_REAL_CST (arg);
|
||||
return real_isnan (&r) ? integer_one_node : integer_zero_node;
|
||||
}
|
||||
|
||||
arg = builtin_save_expr (arg);
|
||||
return fold (build2 (UNORDERED_EXPR, type, arg, arg));
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Fold a call to an unordered comparison function such as
|
||||
__builtin_isgreater(). ARGLIST is the funtion's argument list
|
||||
and TYPE is the functions return type. UNORDERED_CODE and
|
||||
ORDERED_CODE are comparison codes that give the opposite of
|
||||
the desired result. UNORDERED_CODE is used for modes that can
|
||||
hold NaNs and ORDERED_CODE is used for the rest. */
|
||||
__builtin_isgreater(). EXP is the CALL_EXPR for the call.
|
||||
UNORDERED_CODE and ORDERED_CODE are comparison codes that give
|
||||
the opposite of the desired result. UNORDERED_CODE is used
|
||||
for modes that can hold NaNs and ORDERED_CODE is used for
|
||||
the rest. */
|
||||
|
||||
static tree
|
||||
fold_builtin_unordered_cmp (tree exp,
|
||||
@ -8247,6 +8333,21 @@ fold_builtin_1 (tree exp)
|
||||
case BUILT_IN_COPYSIGNL:
|
||||
return fold_builtin_copysign (arglist, type);
|
||||
|
||||
case BUILT_IN_FINITE:
|
||||
case BUILT_IN_FINITEF:
|
||||
case BUILT_IN_FINITEL:
|
||||
return fold_builtin_classify (exp, BUILT_IN_FINITE);
|
||||
|
||||
case BUILT_IN_ISINF:
|
||||
case BUILT_IN_ISINFF:
|
||||
case BUILT_IN_ISINFL:
|
||||
return fold_builtin_classify (exp, BUILT_IN_ISINF);
|
||||
|
||||
case BUILT_IN_ISNAN:
|
||||
case BUILT_IN_ISNANF:
|
||||
case BUILT_IN_ISNANL:
|
||||
return fold_builtin_classify (exp, BUILT_IN_ISNAN);
|
||||
|
||||
case BUILT_IN_ISGREATER:
|
||||
return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
|
||||
case BUILT_IN_ISGREATEREQUAL:
|
||||
|
@ -571,6 +571,15 @@ DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
|
||||
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
|
@ -1,3 +1,9 @@
|
||||
2004-07-01 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* gcc.dg/builtins-43.c: New.
|
||||
* gcc.dg/builtins-44.c: New.
|
||||
* gcc.dg/builtins-45.c: New.
|
||||
|
||||
2004-06-26 Geoffrey Keating <geoffk@apple.com>
|
||||
Andreas Tobler <a.tobler@schweiz.ch>
|
||||
|
||||
|
53
gcc/testsuite/gcc.dg/builtins-43.c
Normal file
53
gcc/testsuite/gcc.dg/builtins-43.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fno-trapping-math -fdump-tree-generic -fdump-tree-optimized" } */
|
||||
|
||||
extern void f(int);
|
||||
extern void link_error ();
|
||||
|
||||
extern float x;
|
||||
extern double y;
|
||||
extern long double z;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
double nan = __builtin_nan ("");
|
||||
float nanf = __builtin_nanf ("");
|
||||
long double nanl = __builtin_nanl ("");
|
||||
|
||||
if (!__builtin_isnan (nan))
|
||||
link_error ();
|
||||
if (!__builtin_isnan (nanf))
|
||||
link_error ();
|
||||
if (!__builtin_isnanf (nanf))
|
||||
link_error ();
|
||||
if (!__builtin_isnan (nanl))
|
||||
link_error ();
|
||||
if (!__builtin_isnanl (nanl))
|
||||
link_error ();
|
||||
|
||||
if (__builtin_isnan (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isnan (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isnanf (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isnan (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isnanl (4.0))
|
||||
link_error ();
|
||||
|
||||
f (__builtin_isnan (x));
|
||||
f (__builtin_isnan (y));
|
||||
f (__builtin_isnanf (y));
|
||||
f (__builtin_isnan (z));
|
||||
f (__builtin_isnanl (z));
|
||||
}
|
||||
|
||||
|
||||
/* Check that all instances of __builtin_isnan were folded. */
|
||||
/* { dg-final { scan-tree-dump-times "isnan" 0 "generic" } } */
|
||||
|
||||
/* Check that all instances of link_error were subject to DCE. */
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
|
||||
|
55
gcc/testsuite/gcc.dg/builtins-44.c
Normal file
55
gcc/testsuite/gcc.dg/builtins-44.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fno-trapping-math -fdump-tree-optimized" } */
|
||||
|
||||
extern void f(int);
|
||||
extern void link_error ();
|
||||
|
||||
extern float x;
|
||||
extern double y;
|
||||
extern long double z;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
double pinf = __builtin_inf ();
|
||||
float pinff = __builtin_inff ();
|
||||
long double pinfl = __builtin_infl ();
|
||||
|
||||
if (__builtin_isinf (pinf) != 1)
|
||||
link_error ();
|
||||
if (__builtin_isinf (pinff) != 1)
|
||||
link_error ();
|
||||
if (__builtin_isinff (pinff) != 1)
|
||||
link_error ();
|
||||
if (__builtin_isinf (pinfl) != 1)
|
||||
link_error ();
|
||||
if (__builtin_isinfl (pinfl) != 1)
|
||||
link_error ();
|
||||
|
||||
if (__builtin_isinf (-pinf) != -1)
|
||||
link_error ();
|
||||
if (__builtin_isinf (-pinff) != -1)
|
||||
link_error ();
|
||||
if (__builtin_isinff (-pinff) != -1)
|
||||
link_error ();
|
||||
if (__builtin_isinf (-pinfl) != -1)
|
||||
link_error ();
|
||||
if (__builtin_isinfl (-pinfl) != -1)
|
||||
link_error ();
|
||||
|
||||
if (__builtin_isinf (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isinf (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isinff (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isinf (4.0))
|
||||
link_error ();
|
||||
if (__builtin_isinfl (4.0))
|
||||
link_error ();
|
||||
}
|
||||
|
||||
|
||||
/* Check that all instances of link_error were subject to DCE. */
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
|
||||
|
47
gcc/testsuite/gcc.dg/builtins-45.c
Normal file
47
gcc/testsuite/gcc.dg/builtins-45.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fno-trapping-math -fdump-tree-optimized" } */
|
||||
|
||||
extern void f(int);
|
||||
extern void link_error ();
|
||||
|
||||
extern float x;
|
||||
extern double y;
|
||||
extern long double z;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
double nan = __builtin_nan ("");
|
||||
float nanf = __builtin_nanf ("");
|
||||
long double nanl = __builtin_nanl ("");
|
||||
|
||||
double pinf = __builtin_inf ();
|
||||
float pinff = __builtin_inff ();
|
||||
long double pinfl = __builtin_infl ();
|
||||
|
||||
if (__builtin_finite (pinf))
|
||||
link_error ();
|
||||
if (__builtin_finitef (pinff))
|
||||
link_error ();
|
||||
if (__builtin_finitel (pinfl))
|
||||
link_error ();
|
||||
|
||||
if (__builtin_finite (nan))
|
||||
link_error ();
|
||||
if (__builtin_finitef (nanf))
|
||||
link_error ();
|
||||
if (__builtin_finitel (nanl))
|
||||
link_error ();
|
||||
|
||||
if (!__builtin_finite (4.0))
|
||||
link_error ();
|
||||
if (!__builtin_finitef (4.0))
|
||||
link_error ();
|
||||
if (!__builtin_finitel (4.0))
|
||||
link_error ();
|
||||
}
|
||||
|
||||
|
||||
/* Check that all instances of link_error were subject to DCE. */
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
|
||||
|
Loading…
x
Reference in New Issue
Block a user