This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Move folding of round -> lround from convert.c to fold_unary
- From: Richard Almquist <ralmquist at verizon dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 08 Dec 2005 20:15:18 -0500
- Subject: Re: [PATCH] Move folding of round -> lround from convert.c to fold_unary
- References: <Pine.LNX.4.63.0512071345100.6048@t148.fhfr.qr>
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;