diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2007-07-18 17:51:13 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2007-07-18 17:51:13 +0000 |
commit | 8a91c45bbfb3d5c99560ab89dc1dc55a1add8719 (patch) | |
tree | 9ffecaf26eda365c1b062b84581aba0966791c13 /gcc/builtins.c | |
parent | 0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade (diff) | |
download | gcc-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.c | 24 |
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; |