diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2007-07-18 17:42:12 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2007-07-18 17:42:12 +0000 |
commit | 0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade (patch) | |
tree | 25f7979650149bcd55f9e00ab15c292b6ca66e36 /gcc/builtins.c | |
parent | 7faa1bbb5d0206cc83f20c1145f612f7754fdcf3 (diff) | |
download | gcc-0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade.zip gcc-0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade.tar.gz gcc-0c8d3c2b0852bf0eca1413c311fc3d2a9d3c1ade.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): Allow for missing
optabs infrastructure. Provide generic implementation for
FINITE/ISFINITE.
(expand_builtin): Handle FINITE/ISFINITE.
(fold_builtin_classify): Make ISFINITE canonical instead of FINITE.
(fold_builtin_1): Likewise.
* builtins.def (BUILT_IN_ISFINITE): New.
* doc/extend.texi: Document isfinite.
testsuite:
* gcc.dg/pr28796-1.c: Add more cases.
* gcc.dg/pr28796-2.c: Likewise.
From-SVN: r126725
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index e92e56f..b96cfb2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2211,8 +2211,8 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) static rtx expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget) { - optab builtin_optab; - enum insn_code icode; + optab builtin_optab = 0; + enum insn_code icode = CODE_FOR_nothing; rtx op0; tree fndecl = get_callee_fndecl (exp); enum machine_mode mode; @@ -2230,6 +2230,10 @@ 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_ISFINITE: + CASE_FLT_FN (BUILT_IN_FINITE): + /* These builtins have no optabs (yet). */ + break; default: gcc_unreachable (); } @@ -2241,7 +2245,8 @@ expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget) /* Optab mode depends on the mode of the input argument. */ mode = TYPE_MODE (TREE_TYPE (arg)); - icode = builtin_optab->handlers[(int) mode].insn_code; + if (builtin_optab) + icode = builtin_optab->handlers[(int) mode].insn_code; /* Before working hard, check whether the instruction is available. */ if (icode != CODE_FOR_nothing) @@ -2295,6 +2300,22 @@ expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget) build_real (type, r)); return expand_expr (result, target, VOIDmode, EXPAND_NORMAL); } + CASE_FLT_FN (BUILT_IN_FINITE): + case BUILT_IN_ISFINITE: + { + /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */ + tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL]; + tree const type = TREE_TYPE (arg); + REAL_VALUE_TYPE r; + char buf[128]; + + get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); + real_from_string (&r, buf); + result = build_call_expr (isle_fn, 2, + fold_build1 (ABS_EXPR, type, arg), + build_real (type, r)); + return expand_expr (result, target, VOIDmode, EXPAND_NORMAL); + } default: break; } @@ -6150,6 +6171,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, if (! flag_unsafe_math_optimizations) break; CASE_FLT_FN (BUILT_IN_ISINF): + CASE_FLT_FN (BUILT_IN_FINITE): + case BUILT_IN_ISFINITE: target = expand_builtin_interclass_mathfn (exp, target, subtarget); if (target) return target; @@ -9569,7 +9592,7 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index) return NULL_TREE; - case BUILT_IN_FINITE: + case BUILT_IN_ISFINITE: if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))) && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) return omit_one_operand (type, integer_one_node, arg); @@ -9972,7 +9995,8 @@ fold_builtin_1 (tree fndecl, tree arg0, bool ignore) case BUILT_IN_FINITED32: case BUILT_IN_FINITED64: case BUILT_IN_FINITED128: - return fold_builtin_classify (fndecl, arg0, BUILT_IN_FINITE); + case BUILT_IN_ISFINITE: + return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE); CASE_FLT_FN (BUILT_IN_ISINF): case BUILT_IN_ISINFD32: |