aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2007-07-18 17:51:13 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2007-07-18 17:51:13 +0000
commit8a91c45bbfb3d5c99560ab89dc1dc55a1add8719 (patch)
tree9ffecaf26eda365c1b062b84581aba0966791c13 /gcc/builtins.c
parent0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade (diff)
downloadgcc-8a91c45bbfb3d5c99560ab89dc1dc55a1add8719.zip
gcc-8a91c45bbfb3d5c99560ab89dc1dc55a1add8719.tar.gz
gcc-8a91c45bbfb3d5c99560ab89dc1dc55a1add8719.tar.bz2
re PR target/30652 (SSE expansion is missing for isinf() and other fpclassify functions)
PR target/30652 * builtins.c (expand_builtin_interclass_mathfn): Provide a generic transformation for builtin ISNORMAL. (expand_builtin): Handle BUILT_IN_ISNORMAL. * builtins.def (BUILT_IN_ISNORMAL): New. * doc/extend.texi: Document isnormal. testsuite: * gcc.dg/pr28796-2.c: Add more cases. From-SVN: r126726
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index b96cfb2..d0e5db9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2230,6 +2230,7 @@ expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
errno_set = true; builtin_optab = ilogb_optab; break;
CASE_FLT_FN (BUILT_IN_ISINF):
builtin_optab = isinf_optab; break;
+ case BUILT_IN_ISNORMAL:
case BUILT_IN_ISFINITE:
CASE_FLT_FN (BUILT_IN_FINITE):
/* These builtins have no optabs (yet). */
@@ -2316,6 +2317,28 @@ expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
build_real (type, r));
return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
}
+ case BUILT_IN_ISNORMAL:
+ {
+ /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
+ islessequal(fabs(x),DBL_MAX). */
+ tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
+ tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
+ tree const type = TREE_TYPE (arg);
+ REAL_VALUE_TYPE rmax, rmin;
+ char buf[128];
+
+ get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
+ real_from_string (&rmax, buf);
+ sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
+ real_from_string (&rmin, buf);
+ arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
+ result = build_call_expr (isle_fn, 2, arg,
+ build_real (type, rmax));
+ result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
+ build_call_expr (isge_fn, 2, arg,
+ build_real (type, rmin)));
+ return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
+ }
default:
break;
}
@@ -6173,6 +6196,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
CASE_FLT_FN (BUILT_IN_ISINF):
CASE_FLT_FN (BUILT_IN_FINITE):
case BUILT_IN_ISFINITE:
+ case BUILT_IN_ISNORMAL:
target = expand_builtin_interclass_mathfn (exp, target, subtarget);
if (target)
return target;