From 8a91c45bbfb3d5c99560ab89dc1dc55a1add8719 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Wed, 18 Jul 2007 17:51:13 +0000 Subject: 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 --- gcc/builtins.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'gcc/builtins.c') 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; -- cgit v1.1