diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2004-04-29 00:36:20 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2004-04-29 00:36:20 +0000 |
commit | 332d782c3d9ed810c76f2e3088545d61e0f3c37c (patch) | |
tree | 7a4324b7bab245653a24dcc00c9d851e6f024d22 /gcc/convert.c | |
parent | b5bfe584032474c30356b7f570f14f25c299788b (diff) | |
download | gcc-332d782c3d9ed810c76f2e3088545d61e0f3c37c.zip gcc-332d782c3d9ed810c76f2e3088545d61e0f3c37c.tar.gz gcc-332d782c3d9ed810c76f2e3088545d61e0f3c37c.tar.bz2 |
convert.c (convert_to_integer): Convert (long)round -> lround, etc.
* convert.c (convert_to_integer): Convert (long)round -> lround,
etc.
testsuite:
* gcc.dg/torture/builtin-convert-2.c: New test.
From-SVN: r81269
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 dcab84a..c7d12b5 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: |