OSDN Git Service

2005-10-28 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / convert.c
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))