OSDN Git Service

* real.c (real_floor, real_ceil): Tweak to allow input and output
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jan 2004 16:16:33 +0000 (16:16 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jan 2004 16:16:33 +0000 (16:16 +0000)
arguments to overlap.
(real_round): New function to implement round(3m) semantics.
* real.h (real_round): Prototype here.
* builtins.c (fold_builtin_round): New function to constant fold
round, roundf and roundl.
(fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}.

* gcc.dg/builtins-29.c: New test case.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76428 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/real.c
gcc/real.h

index 413c01c..e70f2e8 100644 (file)
@@ -1,3 +1,15 @@
+2004-01-23  Roger Sayle  <roger@eyesopen.com>
+
+       * real.c (real_floor, real_ceil): Tweak to allow input and output
+       arguments to overlap.
+       (real_round): New function to implement round(3m) semantics.
+       * real.h (real_round): Prototype here.
+       * builtins.c (fold_builtin_round): New function to constant fold
+       round, roundf and roundl.
+       (fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}.
+
+       * gcc.dg/builtins-29.c: New test case.
+
 2004-01-23  Alexandre Oliva  <aoliva@redhat.com>
 
        PR optimization/13819
index 3174e75..2dfc0e8 100644 (file)
@@ -156,6 +156,7 @@ static tree fold_builtin_cabs (tree, tree, tree);
 static tree fold_builtin_trunc (tree);
 static tree fold_builtin_floor (tree);
 static tree fold_builtin_ceil (tree);
+static tree fold_builtin_round (tree);
 static tree fold_builtin_bitop (tree);
 static tree fold_builtin_memcpy (tree);
 static tree fold_builtin_mempcpy (tree);
@@ -5923,6 +5924,38 @@ fold_builtin_ceil (tree exp)
   return fold_trunc_transparent_mathfn (exp);
 }
 
+/* Fold function call to builtin round, roundf or roundl.  Return
+   NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_round (tree exp)
+{
+  tree arglist = TREE_OPERAND (exp, 1);
+  tree arg;
+
+  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+    return 0;
+
+  /* Optimize ceil of constant value.  */
+  arg = TREE_VALUE (arglist);
+  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+    {
+      REAL_VALUE_TYPE x;
+
+      x = TREE_REAL_CST (arg);
+      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
+       {
+         tree type = TREE_TYPE (exp);
+         REAL_VALUE_TYPE r;
+
+         real_round (&r, TYPE_MODE (type), &x);
+         return build_real (type, r);
+       }
+    }
+
+  return fold_trunc_transparent_mathfn (exp);
+}
+
 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
    and their long and long long variants (i.e. ffsl and ffsll).
    Return NULL_TREE if no simplification can be made.  */
@@ -6868,6 +6901,8 @@ fold_builtin (tree exp)
     case BUILT_IN_ROUND:
     case BUILT_IN_ROUNDF:
     case BUILT_IN_ROUNDL:
+      return fold_builtin_round (exp);
+
     case BUILT_IN_NEARBYINT:
     case BUILT_IN_NEARBYINTF:
     case BUILT_IN_NEARBYINTL:
index 5d9bc41..cd27d3e 100644 (file)
@@ -4539,11 +4539,13 @@ void
 real_floor (REAL_VALUE_TYPE *r, enum machine_mode mode,
            const REAL_VALUE_TYPE *x)
 {
-  do_fix_trunc (r, x);
-  if (! real_identical (r, x) && r->sign)
-    do_add (r, r, &dconstm1, 0);
+  REAL_VALUE_TYPE t;
+
+  do_fix_trunc (&t, x);
+  if (! real_identical (&t, x) && x->sign)
+    do_add (&t, &t, &dconstm1, 0);
   if (mode != VOIDmode)
-    real_convert (r, mode, r);
+    real_convert (r, mode, &t);
 }
 
 /* Round X to the smallest integer not less then argument, i.e. round
@@ -4553,9 +4555,25 @@ void
 real_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode,
           const REAL_VALUE_TYPE *x)
 {
-  do_fix_trunc (r, x);
-  if (! real_identical (r, x) && ! r->sign)
-    do_add (r, r, &dconst1, 0);
+  REAL_VALUE_TYPE t;
+
+  do_fix_trunc (&t, x);
+  if (! real_identical (&t, x) && ! x->sign)
+    do_add (&t, &t, &dconst1, 0);
+  if (mode != VOIDmode)
+    real_convert (r, mode, &t);
+}
+
+/* Round X to the nearest integer, but round halfway cases away from
+   zero.  */
+
+void
+real_round (REAL_VALUE_TYPE *r, enum machine_mode mode,
+           const REAL_VALUE_TYPE *x)
+{
+  do_add (r, x, &dconsthalf, x->sign);
+  do_fix_trunc (r, r);
   if (mode != VOIDmode)
     real_convert (r, mode, r);
 }
+
index 3620d50..3ff0356 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of floating-point access for GNU compiler.
    Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998, 1999,
-   2000, 2002, 2003 Free Software Foundation, Inc.
+   2000, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -372,5 +372,7 @@ extern void real_floor (REAL_VALUE_TYPE *, enum machine_mode,
                        const REAL_VALUE_TYPE *);
 extern void real_ceil (REAL_VALUE_TYPE *, enum machine_mode,
                       const REAL_VALUE_TYPE *);
+extern void real_round (REAL_VALUE_TYPE *, enum machine_mode,
+                       const REAL_VALUE_TYPE *);
 
 #endif /* ! GCC_REAL_H */