summaryrefslogtreecommitdiff
path: root/gcc/convert.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-11 18:14:57 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-11 18:14:57 +0000
commit154f109a98c70bd195c4f8dd00fa74edd7d531ff (patch)
treeca8173c7024ef726758670595befc31e1b2edb0b /gcc/convert.c
parentd2a9c52d6091dac5ab21b55b81536dd0116ffb44 (diff)
downloadgcc-154f109a98c70bd195c4f8dd00fa74edd7d531ff.tar.gz
PR middle-end/24263
* convert.c (convert_to_real): Revert 2005-10-05 patch. Only apply the optimization for rounding builtins if the inner cast is also an extension. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105249 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r--gcc/convert.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/gcc/convert.c b/gcc/convert.c
index 471d93db562..5680c39df20 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -200,9 +200,41 @@ convert_to_real (tree type, tree expr)
break;
}
}
- /* This code formerly changed (float)floor(double d) to
- floorf((float)d). This is incorrect, because (float)d uses
- round-to-nearest and can round up to the next integer. */
+ if (optimize
+ && (((fcode == BUILT_IN_FLOORL
+ || fcode == BUILT_IN_CEILL
+ || fcode == BUILT_IN_ROUNDL
+ || fcode == BUILT_IN_RINTL
+ || fcode == BUILT_IN_TRUNCL
+ || fcode == BUILT_IN_NEARBYINTL)
+ && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+ || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+ || ((fcode == BUILT_IN_FLOOR
+ || fcode == BUILT_IN_CEIL
+ || fcode == BUILT_IN_ROUND
+ || fcode == BUILT_IN_RINT
+ || fcode == BUILT_IN_TRUNC
+ || fcode == BUILT_IN_NEARBYINT)
+ && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
+ {
+ tree fn = mathfn_built_in (type, fcode);
+
+ if (fn)
+ {
+ tree arg
+ = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
+
+ /* Make sure (type)arg0 is an extension, otherwise we could end up
+ changing (float)floor(double d) into floorf((float)d), which is
+ incorrect because (float)d uses round-to-nearest and can round
+ up to the next integer. */
+ if (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (arg)))
+ return
+ build_function_call_expr (fn,
+ build_tree_list (NULL_TREE,
+ fold (convert_to_real (type, arg))));
+ }
+ }
/* Propagate the cast into the operation. */
if (itype != type && FLOAT_TYPE_P (type))