* builtins.c (fold_builtin_round): Fix comment typo.
authorghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 May 2004 01:51:33 +0000 (01:51 +0000)
committerghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 May 2004 01:51:33 +0000 (01:51 +0000)
(fold_builtin_lround): New function.
(fold_builtin): Use it.

testsuite:
* gcc.dg/torture/builtin-rounding-1.c: New test.
* gcc.dg/builtins-25.c: Delete.
* gcc.dg/builtins-29.c: Delete.

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

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-25.c [deleted file]
gcc/testsuite/gcc.dg/builtins-29.c [deleted file]
gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c [new file with mode: 0644]

index 658a282..f4e6cb7 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-30  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * builtins.c (fold_builtin_round): Fix comment typo.
+       (fold_builtin_lround): New function.
+       (fold_builtin): Use it.
+
 2004-04-20  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR target/11608
index 3130f3b..0d04f03 100644 (file)
@@ -6254,7 +6254,7 @@ fold_builtin_round (tree exp)
   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
     return 0;
 
-  /* Optimize ceil of constant value.  */
+  /* Optimize round of constant value.  */
   arg = TREE_VALUE (arglist);
   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
     {
@@ -6274,6 +6274,42 @@ fold_builtin_round (tree exp)
   return fold_trunc_transparent_mathfn (exp);
 }
 
+/* Fold function call to builtin lround, lroundf or lroundl (or the
+   corresponding long long versions).  Return NULL_TREE if no
+   simplification can be made.  */
+
+static tree
+fold_builtin_lround (tree exp)
+{
+  tree arglist = TREE_OPERAND (exp, 1);
+  tree arg;
+
+  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+    return 0;
+
+  /* Optimize lround of constant value.  */
+  arg = TREE_VALUE (arglist);
+  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+    {
+      const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
+
+      if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
+       {
+         tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
+         HOST_WIDE_INT hi, lo;
+         REAL_VALUE_TYPE r;
+
+         real_round (&r, TYPE_MODE (ftype), &x);
+         REAL_VALUE_TO_INT (&lo, &hi, r);
+         result = build_int_2 (lo, hi);
+         if (int_fits_type_p (result, itype))
+           return fold_convert (itype, result);
+       }
+    }
+
+  return 0;
+}
+
 /* 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.  */
@@ -7376,6 +7412,14 @@ fold_builtin (tree exp)
     case BUILT_IN_RINTL:
       return fold_trunc_transparent_mathfn (exp);
 
+    case BUILT_IN_LROUND:
+    case BUILT_IN_LROUNDF:
+    case BUILT_IN_LROUNDL:
+    case BUILT_IN_LLROUND:
+    case BUILT_IN_LLROUNDF:
+    case BUILT_IN_LLROUNDL:
+      return fold_builtin_lround (exp);
+
     case BUILT_IN_FFS:
     case BUILT_IN_FFSL:
     case BUILT_IN_FFSLL:
index 6b13596..e8f8eed 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-30  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * gcc.dg/torture/builtin-rounding-1.c: New test.
+       * gcc.dg/builtins-25.c: Delete.
+       * gcc.dg/builtins-29.c: Delete.
+
 2004-04-29  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * gcc.dg/sibcall-3.c: Delete s390 from expected fail list.
diff --git a/gcc/testsuite/gcc.dg/builtins-25.c b/gcc/testsuite/gcc.dg/builtins-25.c
deleted file mode 100644 (file)
index 4950566..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation.
-
-   Check that constant folding of built-in math functions doesn't
-   break anything and produces the expected results.
-
-   Written by Roger Sayle, 28th June 2003.  */
-
-/* { dg-do link } */
-/* { dg-options "-O2" } */
-
-extern void link_error(void);
-
-extern double trunc(double);
-extern double floor(double);
-extern double ceil(double);
-
-extern float truncf(float);
-extern float floorf(float);
-extern float ceilf(float);
-
-extern long double truncl(long double);
-extern long double floorl(long double);
-extern long double ceill(long double);
-
-void test()
-{
-  if (trunc (0.0) != 0.0)
-    link_error ();
-  if (floor (0.0) != 0.0)
-    link_error ();
-  if (ceil (0.0) != 0.0)
-    link_error ();
-
-  if (trunc (6.0) != 6.0)
-    link_error ();
-  if (floor (6.0) != 6.0)
-    link_error ();
-  if (ceil (6.0) != 6.0)
-    link_error ();
-
-  if (trunc (-8.0) != -8.0)
-    link_error ();
-  if (floor (-8.0) != -8.0)
-    link_error ();
-  if (ceil (-8.0) != -8.0)
-    link_error ();
-
-  if (trunc (3.2) != 3.0)
-    link_error ();
-  if (floor (3.2) != 3.0)
-    link_error ();
-  if (ceil (3.2) != 4.0)
-    link_error ();
-
-  if (trunc (-2.8) != -2.0)
-    link_error ();
-  if (floor (-2.8) != -3.0)
-    link_error ();
-  if (ceil (-2.8) != -2.0)
-    link_error ();
-
-  if (trunc (0.01) != 0.0)
-    link_error ();
-  if (floor (0.01) != 0.0)
-    link_error ();
-  if (ceil (0.01) != 1.0)
-    link_error ();
-
-  if (trunc (-0.7) != 0.0)
-    link_error ();
-  if (floor (-0.7) != -1.0)
-    link_error ();
-  if (ceil (-0.7) != 0.0)
-    link_error ();
-}
-
-void testf()
-{
-  if (truncf (0.0f) != 0.0f)
-    link_error ();
-  if (floorf (0.0f) != 0.0f)
-    link_error ();
-  if (ceilf (0.0f) != 0.0f)
-    link_error ();
-
-  if (truncf (6.0f) != 6.0f)
-    link_error ();
-  if (floorf (6.0f) != 6.0f)
-    link_error ();
-  if (ceilf (6.0f) != 6.0f)
-    link_error ();
-
-  if (truncf (-8.0f) != -8.0f)
-    link_error ();
-  if (floorf (-8.0f) != -8.0f)
-    link_error ();
-  if (ceilf (-8.0f) != -8.0f)
-    link_error ();
-
-  if (truncf (3.2f) != 3.0f)
-    link_error ();
-  if (floorf (3.2f) != 3.0f)
-    link_error ();
-  if (ceilf (3.2f) != 4.0f)
-    link_error ();
-
-  if (truncf (-2.8f) != -2.0f)
-    link_error ();
-  if (floorf (-2.8f) != -3.0f)
-    link_error ();
-  if (ceilf (-2.8f) != -2.0f)
-    link_error ();
-
-  if (truncf (0.01f) != 0.0f)
-    link_error ();
-  if (floorf (0.01f) != 0.0f)
-    link_error ();
-  if (ceilf (0.01f) != 1.0f)
-    link_error ();
-
-  if (truncf (-0.7f) != 0.0f)
-    link_error ();
-  if (floorf (-0.7f) != -1.0f)
-    link_error ();
-  if (ceilf (-0.7f) != 0.0f)
-    link_error ();
-}
-
-void testl()
-{
-  if (truncl (0.0l) != 0.0l)
-    link_error ();
-  if (floorl (0.0l) != 0.0l)
-    link_error ();
-  if (ceill (0.0l) != 0.0l)
-    link_error ();
-
-  if (truncl (6.0l) != 6.0l)
-    link_error ();
-  if (floorl (6.0l) != 6.0l)
-    link_error ();
-  if (ceill (6.0l) != 6.0l)
-    link_error ();
-
-  if (truncl (-8.0l) != -8.0l)
-    link_error ();
-  if (floorl (-8.0l) != -8.0l)
-    link_error ();
-  if (ceill (-8.0l) != -8.0l)
-    link_error ();
-
-  if (truncl (3.2l) != 3.0l)
-    link_error ();
-  if (floorl (3.2l) != 3.0l)
-    link_error ();
-  if (ceill (3.2l) != 4.0l)
-    link_error ();
-
-  if (truncl (-2.8l) != -2.0l)
-    link_error ();
-  if (floorl (-2.8l) != -3.0l)
-    link_error ();
-  if (ceill (-2.8l) != -2.0l)
-    link_error ();
-
-  if (truncl (0.01l) != 0.0l)
-    link_error ();
-  if (floorl (0.01l) != 0.0l)
-    link_error ();
-  if (ceill (0.01l) != 1.0l)
-    link_error ();
-
-  if (truncl (-0.7l) != 0.0l)
-    link_error ();
-  if (floorl (-0.7l) != -1.0l)
-    link_error ();
-  if (ceill (-0.7l) != 0.0l)
-    link_error ();
-}
-
-int main()
-{
-  test ();
-  testf ();
-  testl ();
-  return 0;
-}
-
diff --git a/gcc/testsuite/gcc.dg/builtins-29.c b/gcc/testsuite/gcc.dg/builtins-29.c
deleted file mode 100644 (file)
index 30f9bad..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (C) 2004 Free Software Foundation.
-
-   Check that constant folding of round, roundf and roundl math functions
-   doesn't break anything and produces the expected results.
-
-   Written by Roger Sayle, 22nd January 2004.  */
-
-/* { dg-do link } */
-/* { dg-options "-O2" } */
-
-extern void link_error(void);
-
-extern double round(double);
-extern float roundf(float);
-extern long double roundl(long double);
-
-void test()
-{
-  if (round (0.0) != 0.0)
-    link_error ();
-  if (round (6.0) != 6.0)
-    link_error ();
-  if (round (-8.0) != -8.0)
-    link_error ();
-
-  if (round (3.2) != 3.0)
-    link_error ();
-  if (round (-2.8) != -3.0)
-    link_error ();
-  if (round (0.01) != 0.0)
-    link_error ();
-  if (round (-0.7) != -1.0)
-    link_error ();
-
-  if (round (2.5) != 3.0)
-    link_error ();
-  if (round (-1.5) != -2.0)
-    link_error ();
-}
-
-void testf()
-{
-  if (roundf (0.0f) != 0.0f)
-    link_error ();
-  if (roundf (6.0f) != 6.0f)
-    link_error ();
-  if (roundf (-8.0f) != -8.0f)
-    link_error ();
-
-  if (roundf (3.2f) != 3.0f)
-    link_error ();
-  if (roundf (-2.8f) != -3.0f)
-    link_error ();
-  if (roundf (0.01f) != 0.0f)
-    link_error ();
-  if (roundf (-0.7f) != -1.0f)
-    link_error ();
-
-  if (roundf (2.5f) != 3.0f)
-    link_error ();
-  if (roundf (-1.5f) != -2.0f)
-    link_error ();
-}
-
-void testl()
-{
-  if (roundl (0.0l) != 0.0l)
-    link_error ();
-  if (roundl (6.0l) != 6.0l)
-    link_error ();
-  if (roundl (-8.0l) != -8.0l)
-    link_error ();
-
-  if (roundl (3.2l) != 3.0l)
-    link_error ();
-  if (roundl (-2.8l) != -3.0l)
-    link_error ();
-  if (roundl (0.01l) != 0.0l)
-    link_error ();
-  if (roundl (-0.7l) != -1.0l)
-    link_error ();
-
-  if (roundl (2.5l) != 3.0l)
-    link_error ();
-  if (roundl (-1.5l) != -2.0l)
-    link_error ();
-}
-
-int main()
-{
-  test ();
-  testf ();
-  testl ();
-  return 0;
-}
-
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c b/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c
new file mode 100644 (file)
index 0000000..4101f91
--- /dev/null
@@ -0,0 +1,106 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+   Check that constant folding of the rounding math functions doesn't
+   break anything and produces the expected results.
+
+   Written by Kaveh Ghazi, 2004-04-29.  */
+
+/* { dg-do link } */
+
+#define PROTOTYPE(FN) \
+  PROTOTYPE_LINK_ERROR(FN) \
+  extern double FN (double); \
+  extern float FN##f (float); \
+  extern long double FN##l (long double);
+
+#define PROTOTYPE_RET(FN, RET) \
+  PROTOTYPE_LINK_ERROR(FN) \
+  extern RET FN (double); \
+  extern RET FN##f (float); \
+  extern RET FN##l (long double);
+
+#define PROTOTYPE_LINK_ERROR(FN) \
+  extern void link_error_##FN(void); \
+  extern void link_error_##FN##f(void); \
+  extern void link_error_##FN##l(void);
+
+#define TEST(FN, VALUE, RESULT) \
+  if (FN (VALUE) != RESULT) link_error_##FN(); \
+  if (FN##f (VALUE) != RESULT) link_error_##FN##f(); \
+  if (FN##l (VALUE) != RESULT) link_error_##FN##l(); \
+
+PROTOTYPE (trunc);
+PROTOTYPE (floor);
+PROTOTYPE (ceil);
+PROTOTYPE (round);
+PROTOTYPE_RET (lround, long);
+PROTOTYPE_RET (llround, long long);
+
+int
+main (void)
+{
+  TEST(trunc,   0, 0);
+  TEST(floor,   0, 0);
+  TEST(ceil,    0, 0);
+  TEST(round,   0, 0);
+  TEST(lround,  0, 0);
+  TEST(llround, 0, 0);
+  
+  TEST(trunc,   6, 6);
+  TEST(floor,   6, 6);
+  TEST(ceil,    6, 6);
+  TEST(round,   6, 6);
+  TEST(lround,  6, 6);
+  TEST(llround, 6, 6);
+  
+  TEST(trunc,   -8, -8);
+  TEST(floor,   -8, -8);
+  TEST(ceil,    -8, -8);
+  TEST(round,   -8, -8);
+  TEST(lround,  -8, -8);
+  TEST(llround, -8, -8);
+  
+  TEST(trunc,   3.2, 3);
+  TEST(floor,   3.2, 3);
+  TEST(ceil,    3.2, 4);
+  TEST(round,   3.2, 3);
+  TEST(lround,  3.2, 3);
+  TEST(llround, 3.2, 3);
+
+  TEST(trunc,   -2.8, -2);
+  TEST(floor,   -2.8, -3);
+  TEST(ceil,    -2.8, -2);
+  TEST(round,   -2.8, -3);
+  TEST(lround,  -2.8, -3);
+  TEST(llround, -2.8, -3);
+
+  TEST(trunc,   0.01, 0);
+  TEST(floor,   0.01, 0);
+  TEST(ceil,    0.01, 1);
+  TEST(round,   0.01, 0);
+  TEST(lround,  0.01, 0);
+  TEST(llround, 0.01, 0);
+
+  TEST(trunc,   -0.7, 0);
+  TEST(floor,   -0.7, -1);
+  TEST(ceil,    -0.7, 0);
+  TEST(round,   -0.7, -1);
+  TEST(lround,  -0.7, -1);
+  TEST(llround, -0.7, -1);
+
+  TEST(trunc,   2.5, 2);
+  TEST(floor,   2.5, 2);
+  TEST(ceil,    2.5, 3);
+  TEST(round,   2.5, 3);
+  TEST(lround,  2.5, 3);
+  TEST(llround, 2.5, 3);
+
+  TEST(trunc,   -1.5, -1);
+  TEST(floor,   -1.5, -2);
+  TEST(ceil,    -1.5, -1);
+  TEST(round,   -1.5, -2);
+  TEST(lround,  -1.5, -2);
+  TEST(llround, -1.5, -2);
+
+  return 0;
+}