This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Fix builtin lfloor/lceil attributes and add testcases


At the time the gcc extensions lceil/lfloor were added to GCC, we didn't
get the same level of testcase coverage that test the other rounding
functions.  I went through and added some and noticed two problems.

First, the declaration attributes for builtin lceil/lfloor are wrong IMHO.
The patch was posted with ATTR_MATHFN_ERRNO here:
http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00775.html

There was some discussion between Roger and Uros that since (int)floor
never errors, the transformed lfloor shouldn't either.  Therefore the
ERRNO bit could be taken out and we should match what floor does.
http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00814.html

But the suggestion was to change it to ATTR_MATHFN_FPROUNDING which
doesn't make sense to me.  I don't believe floor or our extension lfloor
cares about FPROUNDING like e.g. rint or nearbyint.  So I changed it to
the same attributes that floor has, namely ATTR_CONST_NOTHROW_LIST. This
problem exists across all active branches.

The second problem came about when updating the testcases.  GCC was
ultimately having trouble resolving that lfloor was nonnegative, although
it could handle lceil.  What happens is that if the argument of lfloor is
nonnegative, then GCC turns it into a FIX_TRUNC_EXPR which then it can't
handle any further. I.e.  signbit(lfloor(fabs)), this gets turned into
signbit((double)FIX_TRUNC_EXPR(ABS_EXPR)).  GCC gets stuck and can't
remove the signbit call.  Fixed by teaching GCC how to handle
FIX_TRUNC_EXPR.

Note: while this is new functionality in the nonnegative detection, it is
a regression because the conversion of lfloor to FIX_TRUNC_EXPR was added
only on mainline. The prior releases fold the testcase correctly.  So
backporting FIX_TRUNC_EXPR is optional.  But there is a minor
pessimization present in lfloor on mainline so it's definitely needed
there.

Another note: I had to update some of the testcases extensively because as
extension builtins lceil/lfloor only exist in the __builtin_foo style. We
already test __builtin_foo vs plain foo delcarations in another testcase,
so I changed some of these tests in my patch to check the __builtin_foo
style instead of plain foo, and we don't lose anything coverage-wise. It
allows me to avoid lots of prototype cruft, etc.

Tested on sparc-sun-solaris2.10, no regressions and the testcases all
pass.  Okay for mainline?

I'd like to also backport the builtins.def fix since that's outright wrong
(with or without the FIX_TRUNC_EXPR change, up to the reviewer) and all
the relevant testcases to 4.1/4.2. Okay to backport?

		Thanks,
		--Kaveh


2007-02-28  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* builtins.def (lceil, lceilf, lceill, lfloor, lfloorf, lfloorl,
	llceil, llceilf, llceill, llfloor, llfloorf, llfloorl): Mark with
	ATTR_CONST_NOTHROW_LIST.

	* fold-const.c (tree_expr_nonnegative_warnv_p): Handle
	FIX_TRUNC_EXPR.

testsuite:
	* gcc.dg/builtins-55.c: Test *lceil* and *lfloor*.
	* gcc.dg/torture/builtin-attr-1.c: Likewise.
	* gcc.dg/torture/builtin-convert-1.c: Likewise.  Also test *lrint* and *lround*.
	* gcc.dg/torture/builtin-convert-2.c: Test ceil->lceil and floor->lfloor.
	* gcc.dg/torture/builtin-convert-3.c: Test *lceil* and *lfloor*.
	* gcc.dg/torture/builtin-integral-1.c: Likewise.
	* gcc.dg/torture/builtin-minmax-1.c: Likewise.  Also test *lrint*
	and *lround*.  Correct macro names.
	* gcc.dg/torture/builtin-nonneg-1.c: Test *lceil* and *lfloor*.
	* gcc.dg/torture/builtin-rounding-1.c: Likewise.

diff -rup orig/egcc-SVN20070227/gcc/builtins.def egcc-SVN20070227/gcc/builtins.def
--- orig/egcc-SVN20070227/gcc/builtins.def	2007-02-10 20:03:45.000000000 -0500
+++ egcc-SVN20070227/gcc/builtins.def	2007-02-28 10:18:11.558742386 -0500
@@ -282,24 +282,24 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_J1L, "j
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
-DEF_GCC_BUILTIN        (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_GCC_BUILTIN        (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_LIB_BUILTIN        (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
-DEF_GCC_BUILTIN        (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_GCC_BUILTIN        (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
 DEF_C99_BUILTIN        (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
 DEF_C99_BUILTIN        (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
-DEF_GCC_BUILTIN        (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_GCC_BUILTIN        (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_GCC_BUILTIN        (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
diff -rup orig/egcc-SVN20070227/gcc/fold-const.c egcc-SVN20070227/gcc/fold-const.c
--- orig/egcc-SVN20070227/gcc/fold-const.c	2007-02-24 20:02:16.000000000 -0500
+++ egcc-SVN20070227/gcc/fold-const.c	2007-02-28 12:00:40.402986714 -0500
@@ -13232,6 +13232,7 @@ tree_expr_nonnegative_warnv_p (tree t, b
     case SAVE_EXPR:
     case NON_LVALUE_EXPR:
     case FLOAT_EXPR:
+    case FIX_TRUNC_EXPR:
       return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
 					    strict_overflow_p);

diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/builtins-55.c egcc-SVN20070227/gcc/testsuite/gcc.dg/builtins-55.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/builtins-55.c	2006-07-27 20:00:55.000000000 -0400
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/builtins-55.c	2007-02-28 12:41:17.771739916 -0500
@@ -32,6 +32,10 @@ void test(double x)
   if (sizeof(long) != sizeof(long long))
     return;

+  if (__builtin_lceil(x) != __builtin_llceil(x))
+    link_error();
+  if (__builtin_lfloor(x) != __builtin_llfloor(x))
+    link_error();
   if (lround(x) != llround(x))
     link_error();
   if (lrint(x) != llrint(x))
@@ -45,6 +49,10 @@ void testf(float x)
   if (sizeof(long) != sizeof(long long))
     return;

+  if (__builtin_lceilf(x) != __builtin_llceilf(x))
+    link_error();
+  if (__builtin_lfloorf(x) != __builtin_llfloorf(x))
+    link_error();
   if (lroundf(x) != llroundf(x))
     link_error();
   if (lrintf(x) != llrintf(x))
@@ -58,6 +66,10 @@ void testl(long double x)
   if (sizeof(long) != sizeof(long long))
     return;

+  if (__builtin_lceill(x) != __builtin_llceill(x))
+    link_error();
+  if (__builtin_lfloorl(x) != __builtin_llfloorl(x))
+    link_error();
   if (lroundl(x) != llroundl(x))
     link_error();
   if (lrintl(x) != llrintl(x))
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c	2007-01-16 20:02:15.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c	2007-02-28 10:18:11.560727980 -0500
@@ -344,6 +344,8 @@ FPTEST1            (j0)
 FPTEST1            (j1)
 FPTEST2ARG1        (jn, int)
 FPTEST2ARG2        (ldexp, int)
+BUILTIN_FPTEST1    (llceil)
+BUILTIN_FPTEST1    (llfloor)
 FPTEST1T           (llrint, long long)
 FPTEST1T           (llround, long long)
 FPTEST1            (log)
@@ -351,6 +353,8 @@ FPTEST1            (log10)
 FPTEST1            (log1p)
 FPTEST1            (log2)
 FPTEST1            (logb)
+BUILTIN_FPTEST1    (lceil)
+BUILTIN_FPTEST1    (lfloor)
 FPTEST1T           (lrint, long)
 FPTEST1T           (lround, long)
 BUILTIN_FPTEST1ARG (nan, char *)
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c	2006-11-01 01:06:38.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c	2007-02-28 14:03:07.241724824 -0500
@@ -21,9 +21,6 @@
 #define MAYBEC99(CODE, C99) (!(C99) && (CODE))
 #endif

-#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \
-  extern long double FN##l(long double);
-
 void test(double d1, float f1, long double ld1)
 {
   /* Test converting math builtins to narrower FP types based on a
@@ -33,7 +30,6 @@ void test(double d1, float f1, long doub
      is only performed if the replacement function is actually
      narrower in width, so check that first.  */
 #define OUTER_CAST1(MATHFN, C99) \
- PROTOTYPE1 (MATHFN) \
  extern void link_failure_outer_##MATHFN##l_##MATHFN##_1(void); \
  extern void link_failure_outer_##MATHFN##l_##MATHFN##_2(void); \
  extern void link_failure_outer_##MATHFN##l_##MATHFN##f_1(void); \
@@ -41,52 +37,51 @@ void test(double d1, float f1, long doub
  extern void link_failure_outer_##MATHFN##_##MATHFN##f_1(void); \
  extern void link_failure_outer_##MATHFN##_##MATHFN##f_2(void); \
  if (sizeof (long double) > sizeof (double) \
-     && MAYBEC99 ((double) MATHFN##l((double)ld1) != MATHFN(ld1), C99)) \
+     && MAYBEC99 ((double) __builtin_##MATHFN##l((double)ld1) != __builtin_##MATHFN(ld1), C99)) \
     link_failure_outer_##MATHFN##l_##MATHFN##_1(); \
  if (sizeof (long double) > sizeof (double) \
-     && MAYBEC99 ((double) MATHFN##l(d1) != MATHFN(d1), C99)) \
+     && MAYBEC99 ((double) __builtin_##MATHFN##l(d1) != __builtin_##MATHFN(d1), C99)) \
     link_failure_outer_##MATHFN##l_##MATHFN##_1(); \
  if (sizeof (long double) > sizeof (double) \
-     && MAYBEC99 ((double) MATHFN##l(f1) != MATHFN(f1), C99)) \
+     && MAYBEC99 ((double) __builtin_##MATHFN##l(f1) != __builtin_##MATHFN(f1), C99)) \
     link_failure_outer_##MATHFN##l_##MATHFN##_2(); \
  if (sizeof (long double) > sizeof (float) \
-     && C99CODE ((float) MATHFN##l((float) ld1) != MATHFN##f(ld1))) \
+     && C99CODE ((float) __builtin_##MATHFN##l((float) ld1) != __builtin_##MATHFN##f(ld1))) \
     link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \
  if (sizeof (long double) > sizeof (float) \
-     && C99CODE ((float) MATHFN##l((float) d1) != MATHFN##f(d1))) \
+     && C99CODE ((float) __builtin_##MATHFN##l((float) d1) != __builtin_##MATHFN##f(d1))) \
     link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \
  if (sizeof (long double) > sizeof (float) \
-     && C99CODE ((float) MATHFN##l(f1) != MATHFN##f(f1))) \
+     && C99CODE ((float) __builtin_##MATHFN##l(f1) != __builtin_##MATHFN##f(f1))) \
     link_failure_outer_##MATHFN##l_##MATHFN##f_2(); \
  if (sizeof (double) > sizeof (float) \
-     && C99CODE ((float) MATHFN((float) ld1) != MATHFN##f(ld1))) \
+     && C99CODE ((float) __builtin_##MATHFN((float) ld1) != __builtin_##MATHFN##f(ld1))) \
     link_failure_outer_##MATHFN##_##MATHFN##f_1(); \
  if (sizeof (double) > sizeof (float) \
-     && C99CODE ((float) MATHFN((float) d1) != MATHFN##f(d1))) \
+     && C99CODE ((float) __builtin_##MATHFN((float) d1) != __builtin_##MATHFN##f(d1))) \
     link_failure_outer_##MATHFN##_##MATHFN##f_1(); \
  if (sizeof (double) > sizeof (float) \
-     && C99CODE ((float) MATHFN(f1) != MATHFN##f(f1))) \
+     && C99CODE ((float) __builtin_##MATHFN(f1) != __builtin_##MATHFN##f(f1))) \
     link_failure_outer_##MATHFN##_##MATHFN##f_2()

   /* Test converting math builtins to narrower FP types based on if
      the argument is a narrower type (perhaps implicitly) cast to a
      wider one.  */
 #define INNER_CAST1(MATHFN, C99) \
- PROTOTYPE1 (MATHFN) \
  extern void link_failure_inner_##MATHFN##l_##MATHFN(void); \
  extern void link_failure_inner_##MATHFN##l_##MATHFN##f(void); \
  extern void link_failure_inner_##MATHFN##_##MATHFN##f(void); \
  if (sizeof (long double) > sizeof (double) \
-     && MAYBEC99 (MATHFN##l(d1) != (long double) MATHFN(d1), C99)) \
+     && MAYBEC99 (__builtin_##MATHFN##l(d1) != (long double) __builtin_##MATHFN(d1), C99)) \
     link_failure_inner_##MATHFN##l_##MATHFN(); \
  if (sizeof (long double) > sizeof (float) \
-     && C99CODE (MATHFN##l(f1) != (long double) MATHFN##f(f1))) \
+     && C99CODE (__builtin_##MATHFN##l(f1) != (long double) __builtin_##MATHFN##f(f1))) \
     link_failure_inner_##MATHFN##l_##MATHFN##f(); \
  if (sizeof (long double) > sizeof (float) \
-     && C99CODE (MATHFN##l((double)f1) != (long double) MATHFN##f(f1))) \
+     && C99CODE (__builtin_##MATHFN##l((double)f1) != (long double) __builtin_##MATHFN##f(f1))) \
     link_failure_inner_##MATHFN##l_##MATHFN##f(); \
  if (sizeof (double) > sizeof (float) \
-     && C99CODE (MATHFN(f1) != (double) MATHFN##f(f1))) \
+     && C99CODE (__builtin_##MATHFN(f1) != (double) __builtin_##MATHFN##f(f1))) \
     link_failure_inner_##MATHFN##_##MATHFN##f()


@@ -122,6 +117,22 @@ void test(double d1, float f1, long doub
   OUTER_CAST1 (ceil, /*C99=*/ 0);
   INNER_CAST1 (floor, /*C99=*/ 0);
   OUTER_CAST1 (floor, /*C99=*/ 0);
+  INNER_CAST1 (lceil, /*C99=*/ 1);
+  OUTER_CAST1 (lceil, /*C99=*/ 1);
+  INNER_CAST1 (lfloor, /*C99=*/ 1);
+  OUTER_CAST1 (lfloor, /*C99=*/ 1);
+  INNER_CAST1 (lrint, /*C99=*/ 1);
+  OUTER_CAST1 (lrint, /*C99=*/ 1);
+  INNER_CAST1 (lround, /*C99=*/ 1);
+  OUTER_CAST1 (lround, /*C99=*/ 1);
+  INNER_CAST1 (llceil, /*C99=*/ 1);
+  OUTER_CAST1 (llceil, /*C99=*/ 1);
+  INNER_CAST1 (llfloor, /*C99=*/ 1);
+  OUTER_CAST1 (llfloor, /*C99=*/ 1);
+  INNER_CAST1 (llrint, /*C99=*/ 1);
+  OUTER_CAST1 (llrint, /*C99=*/ 1);
+  INNER_CAST1 (llround, /*C99=*/ 1);
+  OUTER_CAST1 (llround, /*C99=*/ 1);
   INNER_CAST1 (nearbyint, /*C99=*/ 1);
   OUTER_CAST1 (nearbyint, /*C99=*/ 1);
   INNER_CAST1 (rint, /*C99=*/ 1);
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c	2006-10-08 01:32:10.000000000 -0400
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c	2007-02-28 12:14:57.663915003 -0500
@@ -12,36 +12,26 @@

 #include "../builtins-config.h"

-#define PROTOTYPE(FN) extern double FN(double); \
-  extern float FN##f(float); \
-  extern long double FN##l(long double);
-#define PROTOTYPE_RET(FN, RET) extern RET FN(double); \
-  extern RET FN##f(float); \
-  extern RET FN##l(long double);
-
 /* Macro to do all FP type combinations.  The second half tests
    narrowing the FP type.  */
 #define TEST_FP2FIXED(FN1, FN2) \
-  PROTOTYPE(FN1) \
-  PROTOTYPE_RET(FN2, long) \
-  PROTOTYPE_RET(l##FN2, long long) \
   extern void link_error_##FN1##_##FN2(void); \
   extern void link_error_##FN1##f_##FN2##f(void); \
   extern void link_error_##FN1##l_##FN2##l(void); \
   extern void link_error_##FN1##_l##FN2(void); \
   extern void link_error_##FN1##f_l##FN2##f(void); \
   extern void link_error_##FN1##l_l##FN2##l(void); \
-  if ((long)FN1(d) != FN2(d)) \
+  if ((long)__builtin_##FN1(d) != __builtin_##FN2(d)) \
     link_error_##FN1##_##FN2(); \
-  if ((long)FN1##f(f) != FN2##f(f)) \
+  if ((long)__builtin_##FN1##f(f) != __builtin_##FN2##f(f)) \
     link_error_##FN1##f_##FN2##f(); \
-  if ((long)FN1##l(ld) != FN2##l(ld)) \
+  if ((long)__builtin_##FN1##l(ld) != __builtin_##FN2##l(ld)) \
     link_error_##FN1##l_##FN2##l(); \
-  if ((long long)FN1(d) != l##FN2(d)) \
+  if ((long long)__builtin_##FN1(d) != __builtin_l##FN2(d)) \
     link_error_##FN1##_l##FN2(); \
-  if ((long long)FN1##f(f) != l##FN2##f(f)) \
+  if ((long long)__builtin_##FN1##f(f) != __builtin_l##FN2##f(f)) \
     link_error_##FN1##f_l##FN2##f(); \
-  if ((long long)FN1##l(ld) != l##FN2##l(ld)) \
+  if ((long long)__builtin_##FN1##l(ld) != __builtin_l##FN2##l(ld)) \
     link_error_##FN1##l_l##FN2##l(); \
   extern void link_error_##FN1##_##FN2##f(void); \
   extern void link_error_##FN1##l_##FN2(void); \
@@ -49,17 +39,23 @@
   extern void link_error_##FN1##_l##FN2##f(void); \
   extern void link_error_##FN1##l_l##FN2(void); \
   extern void link_error_##FN1##l_l##FN2##f(void); \
-  if (sizeof(double) > sizeof(float) && (long)FN1(f) != FN2##f(f)) \
+  if (sizeof(double) > sizeof(float) \
+      && (long)__builtin_##FN1(f) != __builtin_##FN2##f(f)) \
     link_error_##FN1##_##FN2##f(); \
-  if (sizeof(long double) > sizeof(double) && (long)FN1##l(d) != FN2(d)) \
+  if (sizeof(long double) > sizeof(double) \
+      && (long)__builtin_##FN1##l(d) != __builtin_##FN2(d)) \
     link_error_##FN1##l_##FN2(); \
-  if (sizeof(long double) > sizeof(float) && (long)FN1##l(f) != FN2##f(f)) \
+  if (sizeof(long double) > sizeof(float) \
+      && (long)__builtin_##FN1##l(f) != __builtin_##FN2##f(f)) \
     link_error_##FN1##l_##FN2##f(); \
-  if (sizeof(double) > sizeof(float) && (long long)FN1(f) != l##FN2##f(f)) \
+  if (sizeof(double) > sizeof(float) \
+      && (long long)__builtin_##FN1(f) != __builtin_l##FN2##f(f)) \
     link_error_##FN1##_l##FN2##f(); \
-  if (sizeof(long double) > sizeof(double) && (long long)FN1##l(d) != l##FN2(d)) \
+  if (sizeof(long double) > sizeof(double) \
+      && (long long)__builtin_##FN1##l(d) != __builtin_l##FN2(d)) \
     link_error_##FN1##l_l##FN2(); \
-  if (sizeof(long double) > sizeof(float) && (long long)FN1##l(f) != l##FN2##f(f)) \
+  if (sizeof(long double) > sizeof(float) \
+      && (long long)__builtin_##FN1##l(f) != __builtin_l##FN2##f(f)) \
     link_error_##FN1##l_l##FN2##f()

 void __attribute__ ((__noinline__)) foo (double d, float f, long double ld)
@@ -67,6 +63,8 @@ void __attribute__ ((__noinline__)) foo
 #ifdef __OPTIMIZE__
 # ifdef HAVE_C99_RUNTIME
   /* The resulting transformation functions are all C99.  */
+  TEST_FP2FIXED (ceil, lceil);
+  TEST_FP2FIXED (floor, lfloor);
   TEST_FP2FIXED (round, lround);
   TEST_FP2FIXED (nearbyint, lrint);
   TEST_FP2FIXED (rint, lrint);
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c	2006-10-08 01:32:11.000000000 -0400
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c	2007-02-28 13:53:20.120095849 -0500
@@ -43,6 +43,10 @@ void __attribute__ ((__noinline__)) test
 #ifdef __OPTIMIZE__
 #ifdef HAVE_C99_RUNTIME
   /* We're converting to implicitly generated C99 functions.  */
+  INNER_CAST1 (__builtin_lceil, long);
+  INNER_CAST1 (__builtin_llceil, long long);
+  INNER_CAST1 (__builtin_lfloor, long);
+  INNER_CAST1 (__builtin_llfloor, long long);
   INNER_CAST1 (lround, long);
   INNER_CAST1 (llround, long long);
   INNER_CAST1 (lrint, long);
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c	2006-01-22 23:30:56.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c	2007-02-28 10:18:11.563438437 -0500
@@ -5,48 +5,30 @@
    Written by Kaveh Ghazi, 2004-03-16.  */

 /* { dg-do link } */
-/* { dg-options "-ffast-math" } */
+/* We need -ffinite-math-only so that we can fold "foo != foo", where
+   foo is a floating point expression.  We need -fno-math-errno so
+   that various math functions are marked const/pure and can be
+   folded.  */
+/* { dg-options "-ffinite-math-only -fno-math-errno" } */

-#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \
-  extern long double FN##l(long double);
-#define PROTOTYPE1_RET(FN, RET) extern RET FN(double); extern RET FN##f(float); \
-  extern RET FN##l(long double);
-#define PROTOTYPE_LINK_FAILURE(FN) extern void link_failure_##FN(void); \
- extern void link_failure_##FN##f(void); \
- extern void link_failure_##FN##l(void); \
-
-PROTOTYPE1(fabs)
-PROTOTYPE1(ceil)
-PROTOTYPE1(floor)
-PROTOTYPE1(nearbyint)
-PROTOTYPE1(rint)
-PROTOTYPE1(round)
-PROTOTYPE1(trunc)
-PROTOTYPE1_RET(lround, long)
-PROTOTYPE1_RET(llround, long long)
-PROTOTYPE1_RET(lrint, long)
-PROTOTYPE1_RET(llrint, long long)
+extern int link_failure (int);

 /* Test that the various FP truncation builtins detect integral
    arguments.  */
 #define CHECK_FN(MATHFN) \
- PROTOTYPE_LINK_FAILURE(MATHFN); \
- if (MATHFN(i1) != i1) link_failure_##MATHFN(); \
- if (MATHFN##f(i1) != i1) link_failure_##MATHFN##f(); \
- if (MATHFN##l(i1) != i1) link_failure_##MATHFN##l();
+ if (__builtin_##MATHFN(i1) != i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##f(i1) != i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##l(i1) != i1) link_failure (__LINE__);

 #define CHECK_FN_RET(MATHFN, RET) \
- PROTOTYPE_LINK_FAILURE(MATHFN); \
- if (MATHFN(i1) != (RET)(double)i1) link_failure_##MATHFN(); \
- if (MATHFN##f(i1) != (RET)(float)i1) link_failure_##MATHFN##f(); \
- if (MATHFN##l(i1) != (RET)(long double)i1) link_failure_##MATHFN##l();
+ if (__builtin_##MATHFN(i1) != (RET)(double)i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##f(i1) != (RET)(float)i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##l(i1) != (RET)(long double)i1) link_failure (__LINE__);

   /* Check that various other integral expressions are detected.  */
 #define CHECK_EXPR(EXPR,NAME) \
- extern void link_failure_FP_##NAME(void); \
- extern void link_failure_fixed_##NAME(void); \
- if (ceill(EXPR) != (EXPR)) link_failure_FP_##NAME(); \
- if (lroundl(EXPR) != (long)(long double)(EXPR)) link_failure_fixed_##NAME();
+ if (__builtin_ceill(EXPR) != (EXPR)) link_failure (__LINE__); \
+ if (__builtin_lroundl(EXPR) != (long)(long double)(EXPR)) link_failure (__LINE__);

 void __attribute__ ((__noinline__)) test (int i1, int i2)
 {
@@ -60,6 +42,10 @@ void __attribute__ ((__noinline__)) test
   CHECK_FN_RET(llround, long long);
   CHECK_FN_RET(lrint, long);
   CHECK_FN_RET(llrint, long long);
+  CHECK_FN_RET(lceil, long);
+  CHECK_FN_RET(llceil, long long);
+  CHECK_FN_RET(lfloor, long);
+  CHECK_FN_RET(llfloor, long long);

   CHECK_EXPR (5.0, REAL_CST);
   CHECK_EXPR (5.0F, REAL_CSTf);
@@ -67,9 +53,9 @@ void __attribute__ ((__noinline__)) test
   CHECK_EXPR ((double)i1, FLOAT_EXPR);
   CHECK_EXPR ((float)i1, FLOAT_EXPRf);
   CHECK_EXPR ((long double)i1, FLOAT_EXPRl);
-  CHECK_EXPR (fabs(i1), ABS_EXPR);
-  CHECK_EXPR (fabsf(i1), ABS_EXPRf);
-  CHECK_EXPR (fabsl(i1), ABS_EXPRl);
+  CHECK_EXPR (__builtin_fabs(i1), ABS_EXPR);
+  CHECK_EXPR (__builtin_fabsf(i1), ABS_EXPRf);
+  CHECK_EXPR (__builtin_fabsl(i1), ABS_EXPRl);
   CHECK_EXPR (((void)i1,(double)i2), COMPOUND_EXPR);
   CHECK_EXPR ((double)i1+i2, PLUS_EXPR);
   CHECK_EXPR ((double)i1-i2, MINUS_EXPR);
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c	2006-11-26 20:01:29.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c	2007-02-28 10:18:11.564627713 -0500
@@ -15,10 +15,6 @@ extern void link_error(int);
   extern float FUNC##f (float); \
   extern double FUNC (double); \
   extern long double FUNC##l (long double)
-#define DECLARE_L(FUNC) \
-  extern long FUNC##f (float); \
-  extern long FUNC (double); \
-  extern long FUNC##l (long double)
 #define DECLARE2(FUNC) \
   extern float FUNC##f (float, float); \
   extern double FUNC (double, double); \
@@ -26,9 +22,6 @@ extern void link_error(int);

 DECLARE2(fmin);
 DECLARE2(fmax);
-DECLARE_L(lround);
-DECLARE_L(lrint);
-DECLARE(sqrt);
 DECLARE(fabs);
 extern int pure(int) __attribute__ ((__pure__));

@@ -52,20 +45,32 @@ extern int pure(int) __attribute__ ((__p
     link_error(__LINE__); \
   } while (0)

-/* Test that lround(FUNC(int,int)) == lrint(FUNC(int,int)), i.e. both
-   lround() and lrint() should be folded away.  */
-#define TEST_NONNEG(FUNC) do { \
-  if (lroundf(FUNC##f(i,j)) != lrintf(FUNC##f(i,j))) \
+/* Test that FIXFUNC(FUNC(int1,int2)) == (TYPE)FUNC(int1,int2),
+   i.e. FIXFUNC should be folded away and replaced with a cast.  */
+#define TEST_FIXFUNC(FUNC,FIXFUNC,TYPE) do { \
+  if (FIXFUNC##f(FUNC##f(i,j)) != (TYPE)FUNC##f(i,j)) \
     link_error(__LINE__); \
-  if (lround(FUNC(i,j)) != lrint(FUNC(i,j))) \
+  if (FIXFUNC(FUNC(i,j)) != (TYPE)FUNC(i,j)) \
     link_error(__LINE__); \
-  if (lroundl(FUNC##l(i,j)) != lrintl(FUNC##l(i,j))) \
+  if (FIXFUNC##l(FUNC##l(i,j)) != (TYPE)FUNC##l(i,j)) \
     link_error(__LINE__); \
   } while (0)

+/* Test that FUNC(int1,int2) has an integer return type.  */
+#define TEST_INT(FUNC) do { \
+  TEST_FIXFUNC(FUNC,__builtin_lround,long); \
+  TEST_FIXFUNC(FUNC,__builtin_llround,long long); \
+  TEST_FIXFUNC(FUNC,__builtin_lrint,long); \
+  TEST_FIXFUNC(FUNC,__builtin_llrint,long long); \
+  TEST_FIXFUNC(FUNC,__builtin_lceil,long); \
+  TEST_FIXFUNC(FUNC,__builtin_llceil,long long); \
+  TEST_FIXFUNC(FUNC,__builtin_lfloor,long); \
+  TEST_FIXFUNC(FUNC,__builtin_llfloor,long long); \
+  } while (0)
+
 /* Test that (long)fabs(FUNC(fabs(x),fabs(y))) ==
    (long)FUNC(fabs(x),fabs(y)).  We cast to (long) so "!=" folds.  */
-#define TEST_INT(FUNC) do { \
+#define TEST_NONNEG(FUNC) do { \
   if ((long)fabsf(FUNC##f(fabsf(xf),fabsf(yf))) != (long)FUNC##f(fabsf(xf),fabsf(yf))) \
     link_error(__LINE__); \
   if ((long)fabs(FUNC(fabs(x),fabs(y))) != (long)FUNC(fabs(x),fabs(y))) \
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-nonneg-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-nonneg-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-nonneg-1.c	2007-02-23 09:49:41.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-nonneg-1.c	2007-02-28 11:31:12.828236396 -0500
@@ -144,8 +144,12 @@ void test(double d1, double d2, float f1
   ARG1TEST1 (floor);
   ARG1TEST2 (fmod);
   ARG1TEST2_A2INT (ldexp, int);
+  ARG1TEST1_RTYPE (__builtin_llceil, long long);
+  ARG1TEST1_RTYPE (__builtin_llfloor, long long);
   ARG1TEST1_RTYPE (llrint, long long);
   ARG1TEST1_RTYPE (llround, long long);
+  ARG1TEST1_RTYPE (__builtin_lceil, long);
+  ARG1TEST1_RTYPE (__builtin_lfloor, long);
   ARG1TEST1_RTYPE (lrint, long);
   ARG1TEST1_RTYPE (lround, long);
   /* The modf* functions aren't ever "const" or "pure" even with
diff -rup orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c
--- orig/egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c	2006-01-22 23:30:57.000000000 -0500
+++ egcc-SVN20070227/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c	2007-02-28 10:45:43.512274245 -0500
@@ -7,34 +7,12 @@

 /* { 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);
+extern int link_error (int);

 #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);
+  if (__builtin_##FN (VALUE) != RESULT) link_error (__LINE__); \
+  if (__builtin_##FN##f (VALUE) != RESULT) link_error (__LINE__); \
+  if (__builtin_##FN##l (VALUE) != RESULT) link_error (__LINE__); \

 int
 main (void)
@@ -45,6 +23,10 @@ main (void)
   TEST(round,   0, 0);
   TEST(lround,  0, 0);
   TEST(llround, 0, 0);
+  TEST(lfloor,  0, 0);
+  TEST(llfloor, 0, 0);
+  TEST(lceil,  0, 0);
+  TEST(llceil, 0, 0);

   TEST(trunc,   6, 6);
   TEST(floor,   6, 6);
@@ -52,6 +34,10 @@ main (void)
   TEST(round,   6, 6);
   TEST(lround,  6, 6);
   TEST(llround, 6, 6);
+  TEST(lfloor,  6, 6);
+  TEST(llfloor, 6, 6);
+  TEST(lceil,  6, 6);
+  TEST(llceil, 6, 6);

   TEST(trunc,   -8, -8);
   TEST(floor,   -8, -8);
@@ -59,6 +45,10 @@ main (void)
   TEST(round,   -8, -8);
   TEST(lround,  -8, -8);
   TEST(llround, -8, -8);
+  TEST(lfloor,  -8, -8);
+  TEST(llfloor, -8, -8);
+  TEST(lceil,  -8, -8);
+  TEST(llceil, -8, -8);

   TEST(trunc,   3.2, 3);
   TEST(floor,   3.2, 3);
@@ -66,6 +56,10 @@ main (void)
   TEST(round,   3.2, 3);
   TEST(lround,  3.2, 3);
   TEST(llround, 3.2, 3);
+  TEST(lfloor,  3.2, 3);
+  TEST(llfloor, 3.2, 3);
+  TEST(lceil,  3.2, 4);
+  TEST(llceil, 3.2, 4);

   TEST(trunc,   -2.8, -2);
   TEST(floor,   -2.8, -3);
@@ -73,6 +67,10 @@ main (void)
   TEST(round,   -2.8, -3);
   TEST(lround,  -2.8, -3);
   TEST(llround, -2.8, -3);
+  TEST(lfloor,  -2.8, -3);
+  TEST(llfloor, -2.8, -3);
+  TEST(lceil,  -2.8, -2);
+  TEST(llceil, -2.8, -2);

   TEST(trunc,   0.01, 0);
   TEST(floor,   0.01, 0);
@@ -80,6 +78,10 @@ main (void)
   TEST(round,   0.01, 0);
   TEST(lround,  0.01, 0);
   TEST(llround, 0.01, 0);
+  TEST(lfloor,  0.01, 0);
+  TEST(llfloor, 0.01, 0);
+  TEST(lceil,  0.01, 1);
+  TEST(llceil, 0.01, 1);

   TEST(trunc,   -0.7, 0);
   TEST(floor,   -0.7, -1);
@@ -87,6 +89,10 @@ main (void)
   TEST(round,   -0.7, -1);
   TEST(lround,  -0.7, -1);
   TEST(llround, -0.7, -1);
+  TEST(lfloor,  -0.7, -1);
+  TEST(llfloor, -0.7, -1);
+  TEST(lceil,  -0.7, 0);
+  TEST(llceil, -0.7, 0);

   TEST(trunc,   2.5, 2);
   TEST(floor,   2.5, 2);
@@ -94,6 +100,10 @@ main (void)
   TEST(round,   2.5, 3);
   TEST(lround,  2.5, 3);
   TEST(llround, 2.5, 3);
+  TEST(lfloor,  2.5, 2);
+  TEST(llfloor, 2.5, 2);
+  TEST(lceil,  2.5, 3);
+  TEST(llceil, 2.5, 3);

   TEST(trunc,   -1.5, -1);
   TEST(floor,   -1.5, -2);
@@ -101,6 +111,10 @@ main (void)
   TEST(round,   -1.5, -2);
   TEST(lround,  -1.5, -2);
   TEST(llround, -1.5, -2);
+  TEST(lfloor,  -1.5, -2);
+  TEST(llfloor, -1.5, -2);
+  TEST(lceil,  -1.5, -1);
+  TEST(llceil, -1.5, -1);

   return 0;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]