PR middle-end/24263
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Oct 2005 18:14:57 +0000 (18:14 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Oct 2005 18:14:57 +0000 (18:14 +0000)
* 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

gcc/ChangeLog
gcc/convert.c

index c4c063b..1b1faaa 100644 (file)
@@ -1,3 +1,10 @@
+2005-10-11  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       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.
+
 2005-10-11  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR tree-opt/23946
index 471d93d..5680c39 100644 (file)
@@ -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))