aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c46
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/builtins-25.c188
-rw-r--r--gcc/testsuite/gcc.dg/builtins-29.c96
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c106
6 files changed, 163 insertions, 285 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 658a282..f4e6cb7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3130f3b..0d04f03 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6b13596..e8f8eed 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 4950566..0000000
--- a/gcc/testsuite/gcc.dg/builtins-25.c
+++ /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
index 30f9bad..0000000
--- a/gcc/testsuite/gcc.dg/builtins-29.c
+++ /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
index 0000000..4101f91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c
@@ -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;
+}