diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2004-05-02 02:53:05 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2004-05-02 02:53:05 +0000 |
commit | ca3df643698b0f67b6376a88aa9b4f586d4b9a00 (patch) | |
tree | a34c7202f1576f9f79461bbdb36fc625107a225c /gcc/builtins.c | |
parent | 3c2d6797727df4540c7b5b3f5ca826d14370b17c (diff) | |
download | gcc-ca3df643698b0f67b6376a88aa9b4f586d4b9a00.tar.gz |
builtins.c (fold_fixed_mathfn): New function.
* builtins.c (fold_fixed_mathfn): New function.
(fold_builtin_lround, fold_builtin): Use it.
testsuite:
* gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases.
* gcc.dg/torture/builtin-convert-3.c: New test.
From-SVN: r81403
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 0d04f0311a9..96d365ababb 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -6075,6 +6075,45 @@ fold_trunc_transparent_mathfn (tree exp) return 0; } +/* EXP is assumed to be builtin call which can narrow the FP type of + the argument, for instance lround((double)f) -> lroundf (f). */ + +static tree +fold_fixed_mathfn (tree exp) +{ + tree fndecl = get_callee_fndecl (exp); + tree arglist = TREE_OPERAND (exp, 1); + enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); + tree arg; + + if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return 0; + + arg = TREE_VALUE (arglist); + + /* If argument is already integer valued, and we don't need to worry + about setting errno, there's no need to perform rounding. */ + if (! flag_errno_math && integer_valued_real_p (arg)) + return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg)); + + if (optimize) + { + tree ftype = TREE_TYPE (arg); + tree arg0 = strip_float_extensions (arg); + tree newtype = TREE_TYPE (arg0); + tree decl; + + if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) + && (decl = mathfn_built_in (newtype, fcode))) + { + arglist = + build_tree_list (NULL_TREE, fold_convert (newtype, arg0)); + return build_function_call_expr (decl, arglist); + } + } + return 0; +} + /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST is the argument list and TYPE is the return type. Return NULL_TREE if no if no simplification can be made. */ @@ -6307,7 +6346,7 @@ fold_builtin_lround (tree exp) } } - return 0; + return fold_fixed_mathfn (exp); } /* Fold function call to builtin ffs, clz, ctz, popcount and parity @@ -7420,6 +7459,14 @@ fold_builtin (tree exp) case BUILT_IN_LLROUNDL: return fold_builtin_lround (exp); + case BUILT_IN_LRINT: + case BUILT_IN_LRINTF: + case BUILT_IN_LRINTL: + case BUILT_IN_LLRINT: + case BUILT_IN_LLRINTF: + case BUILT_IN_LLRINTL: + return fold_fixed_mathfn (exp); + case BUILT_IN_FFS: case BUILT_IN_FFSL: case BUILT_IN_FFSLL: |