diff options
author | ghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-29 00:36:20 +0000 |
---|---|---|
committer | ghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-29 00:36:20 +0000 |
commit | f6777f80679ff756bfef1934221366c657163e65 (patch) | |
tree | 7a4324b7bab245653a24dcc00c9d851e6f024d22 /gcc/convert.c | |
parent | cdc3601b43ddf408aea02cb1e533190b7f097fdd (diff) | |
download | gcc-f6777f80679ff756bfef1934221366c657163e65.tar.gz |
* convert.c (convert_to_integer): Convert (long)round -> lround,
etc.
testsuite:
* gcc.dg/torture/builtin-convert-2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81269 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r-- | gcc/convert.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/convert.c b/gcc/convert.c index dcab84a9aa9..c7d12b50200 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -332,6 +332,52 @@ convert_to_integer (tree type, tree expr) return error_mark_node; } + /* Convert e.g. (long)round(d) -> lround(d). */ + /* If we're converting to char, we may encounter differing behavior + between converting from double->char vs double->long->char. + We're in "undefined" territory but we prefer to be conservative, + so only proceed in "unsafe" math mode. */ + if (optimize + && (flag_unsafe_math_optimizations + || outprec >= TYPE_PRECISION (long_integer_type_node))) + { + tree s_expr = strip_float_extensions (expr); + tree s_intype = TREE_TYPE (s_expr); + const enum built_in_function fcode = builtin_mathfn_code (s_expr); + tree fn = 0; + + switch (fcode) + { + case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL: + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node)) + fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND); + else + fn = mathfn_built_in (s_intype, BUILT_IN_LROUND); + break; + + case BUILT_IN_RINT: case BUILT_IN_RINTF: case BUILT_IN_RINTL: + /* Only convert rint* if we can ignore math exceptions. */ + if (flag_trapping_math) + break; + /* ... Fall through ... */ + case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL: + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node)) + fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT); + else + fn = mathfn_built_in (s_intype, BUILT_IN_LRINT); + break; + default: + break; + } + + if (fn) + { + tree arglist = TREE_OPERAND (s_expr, 1); + tree newexpr = build_function_call_expr (fn, arglist); + return convert_to_integer (type, newexpr); + } + } + switch (TREE_CODE (intype)) { case POINTER_TYPE: |