[PATCH] Move folding of round -> lround from convert.c to fold_unary
Richard Almquist
ralmquist@verizon.net
Sun Dec 11 16:02:00 GMT 2005
Richard Guenther wrote:
> This moves folding of the rounding functions to fold.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> Ok for mainline?
>
> Thanks,
> Richard.
>
> :ADDPATCH middle-end:
>
> 2005-12-07 Richard Guenther <rguenther@suse.de>
>
> * convert.c (convert_to_integer): Move folding of
> rounding functions ...
> * fold-const.c (fold_unary): ... here.
>
> Index: fold-const.c
> ===================================================================
> *** fold-const.c (revision 108153)
> --- fold-const.c (working copy)
> *************** fold_unary (enum tree_code code, tree ty
> *** 7009,7014 ****
> --- 7009,7080 ----
> TREE_OPERAND (arg0, 1));
> }
>
> + /* 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
> + && TREE_CODE (op0) == CALL_EXPR
> + && TREE_CODE (type) == INTEGER_TYPE
> + && (flag_unsafe_math_optimizations
> + || (long_integer_type_node
> + && (TYPE_PRECISION (type)
> + >= TYPE_PRECISION (long_integer_type_node)))))
> + {
> + tree s_intype = TREE_TYPE (op0);
> + const enum built_in_function fcode = builtin_mathfn_code (op0);
> + tree fn = 0;
> + bool ll = (TYPE_MAIN_VARIANT (type)
> + == TYPE_MAIN_VARIANT (long_long_integer_type_node));
> +
> + switch (fcode)
> + {
> + CASE_FLT_FN (BUILT_IN_CEIL):
> + /* Only convert in ISO C99 mode. */
> + if (!TARGET_C99_FUNCTIONS)
> + break;
> + fn = mathfn_built_in (s_intype,
> + ll ? BUILT_IN_LLCEIL : BUILT_IN_LCEIL);
> + break;
> +
> + CASE_FLT_FN (BUILT_IN_FLOOR):
> + /* Only convert in ISO C99 mode. */
> + fn = mathfn_built_in (s_intype,
> + ll ? BUILT_IN_LLFLOOR : BUILT_IN_LFLOOR);
> + break;
> +
> + CASE_FLT_FN (BUILT_IN_ROUND):
> + fn = mathfn_built_in (s_intype,
> + ll ? BUILT_IN_LLROUND : BUILT_IN_LROUND);
> + break;
> +
> + CASE_FLT_FN (BUILT_IN_RINT):
> + /* Only convert rint* if we can ignore math exceptions. */
> + if (flag_trapping_math)
> + break;
> + /* ... Fall through ... */
> + CASE_FLT_FN (BUILT_IN_NEARBYINT):
> + fn = mathfn_built_in (s_intype,
> + ll ? BUILT_IN_LLRINT : BUILT_IN_LRINT);
> + break;
> +
> + CASE_FLT_FN (BUILT_IN_TRUNC):
> + return fold_build1 (FIX_TRUNC_EXPR, type,
> + TREE_VALUE (TREE_OPERAND (op0, 1)));
> +
> + default:
> + break;
> + }
> +
> + if (fn)
> + {
> + tree arglist = TREE_OPERAND (op0, 1);
> + tree newexpr = build_function_call_expr (fn, arglist);
> + return fold_convert (type, newexpr);
> + }
> + }
> +
> tem = fold_convert_const (code, type, arg0);
> return tem ? tem : NULL_TREE;
>
> Index: convert.c
> ===================================================================
> *** convert.c (revision 108153)
> --- convert.c (working copy)
> *************** convert_to_integer (tree type, tree expr
> *** 334,413 ****
> 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
> - || (long_integer_type_node
> - && 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_FLT_FN (BUILT_IN_CEIL):
> - /* Only convert in ISO C99 mode. */
> - if (!TARGET_C99_FUNCTIONS)
> - break;
> - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
> - fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
> - else
> - fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
> - break;
> -
> - CASE_FLT_FN (BUILT_IN_FLOOR):
> - /* Only convert in ISO C99 mode. */
> - if (!TARGET_C99_FUNCTIONS)
> - break;
> - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
> - fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
> - else
> - fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
> - break;
> -
> - CASE_FLT_FN (BUILT_IN_ROUND):
> - 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_FLT_FN (BUILT_IN_RINT):
> - /* Only convert rint* if we can ignore math exceptions. */
> - if (flag_trapping_math)
> - break;
> - /* ... Fall through ... */
> - CASE_FLT_FN (BUILT_IN_NEARBYINT):
> - 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;
> -
> - CASE_FLT_FN (BUILT_IN_TRUNC):
> - {
> - tree arglist = TREE_OPERAND (s_expr, 1);
> - return convert_to_integer (type, TREE_VALUE (arglist));
> - }
> -
> - 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:
> --- 334,339 ----
>
Did you mean to remove the !TARGET_C99_FUNCTIONS test for BUILT_IN_FLOOR
in the following?
> - CASE_FLT_FN (BUILT_IN_FLOOR):
> - /* Only convert in ISO C99 mode. */
> - if (!TARGET_C99_FUNCTIONS)
> - break;
More information about the Gcc-patches
mailing list