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]: transform nearbyint->rint & rint/lrint->round/lround


This patch adds transformations of the form:

nearbyint -> rint (when -fno-trapping-math)
rint -> round (when -fno-rounding-math)
lrint -> lround (also when -fno-rounding-math)


Normally, I'd just do this once at the tree builtin level and be done with
it.  However the replacement functions are all C99 style and therefore the
transformations don't occur on c90 platforms.  Plus some of the
transformations were already implemented in other places so I just filled
them out or rearranged them so that I could take advantage of fall-through
in switches.  E.g.  nearbyint was already changed to rint in optab
selection.  Also nearbyint was already changed into lrint if the result
was cast to long and -fno-trapping-math was set. So this patch reconciles
everywhere we handle these builtins to do the same thing.

There are 3 main places where these opts gets done.

1.  Regular builtin folding.
2.  Optab selection.
3.  Converting to integer, i.e. nearbyint/rint/round into lrint/lround.

It's easy to think of a case where #1 won't trigger, but #2 will. E.g. a
non-c99 x86 platform calling nearbyint with the right -f flags will skip
the builtin transformation (#1), but will do the transformation when
selecting an optab (#2).  However I can't think of a case where #1 will
fail but #3 will succeed.  Unless a c99 target manually zaps builtin
rint/round when initializing, but let's lrint/lround exist.

Nevertheless having #3 do the same transformation doesn't add any code in
convert.c, it just moves a switch case around and let's fallthrough
happen.  I'd like to have it be consistent.

Patch bootstrapped on sparc-sun-solaris2.10, no regressions.
I added a bunch of new testcases, and they all pass.

Okay for mainline?

		Thanks,
		--Kaveh


2007-03-09  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* builtins.c (expand_builtin_mathfn): Convert rint->round optab
	when -fno-rounding-math.
	(expand_builtin_int_roundingfn_2): Likewise for lrint->lround.
	(fold_builtin_rint, fold_builtin_nearbyint, fold_builtin_lrint):
	New.
	(fold_builtin_int_roundingfn): Handle lrint when
	-fno-rounding-math.
	(fold_builtin_1): Use new folding functions.
	* convert.c (convert_to_integer): Have rint fall through to round
	case when -fno-rounding-math.

testsuite:
	* gcc.dg/torture/builtin-convert-2.c: Test nearbyint/rint->lround.
	* gcc.dg/torture/builtin-convert-4.c: Test more cases.
	* gcc.dg/torture/builtin-convert-5.c: New test.
	* gcc.dg/torture/builtin-convert-6.c: New test.
	* gcc.dg/torture/builtin-rounding-2.c: New test.

diff -rup orig/egcc-SVN20070308/gcc/builtins.c egcc-SVN20070308/gcc/builtins.c
--- orig/egcc-SVN20070308/gcc/builtins.c	2007-02-28 20:03:46.000000000 -0500
+++ egcc-SVN20070308/gcc/builtins.c	2007-03-10 14:16:21.386782696 -0500
@@ -1848,15 +1848,18 @@ expand_builtin_mathfn (tree exp, rtx tar
       builtin_optab = ceil_optab; break;
     CASE_FLT_FN (BUILT_IN_TRUNC):
       builtin_optab = btrunc_optab; break;
-    CASE_FLT_FN (BUILT_IN_ROUND):
-      builtin_optab = round_optab; break;
     CASE_FLT_FN (BUILT_IN_NEARBYINT):
       builtin_optab = nearbyint_optab;
       if (flag_trapping_math)
 	break;
       /* Else fallthrough and expand as rint.  */
     CASE_FLT_FN (BUILT_IN_RINT):
-      builtin_optab = rint_optab; break;
+      builtin_optab = rint_optab;
+      if (flag_rounding_math)
+	break;
+      /* Else fallthrough and expand as round.  */
+    CASE_FLT_FN (BUILT_IN_ROUND):
+      builtin_optab = round_optab; break;
     default:
       gcc_unreachable ();
     }
@@ -2524,7 +2527,10 @@ expand_builtin_int_roundingfn_2 (tree ex
     {
     CASE_FLT_FN (BUILT_IN_LRINT):
     CASE_FLT_FN (BUILT_IN_LLRINT):
-      builtin_optab = lrint_optab; break;
+      builtin_optab = lrint_optab;
+      if (flag_rounding_math)
+	break;
+      /* Else fall through.  */
     CASE_FLT_FN (BUILT_IN_LROUND):
     CASE_FLT_FN (BUILT_IN_LLROUND):
       builtin_optab = lround_optab; break;
@@ -7633,6 +7639,88 @@ fold_builtin_round (tree fndecl, tree ar
   return fold_trunc_transparent_mathfn (fndecl, arg);
 }

+/* Fold function call to builtin rint* with argument ARG.  Return
+   NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_rint (tree fndecl, tree arg)
+{
+  if (!validate_arg (arg, REAL_TYPE))
+    return NULL_TREE;
+
+  if (!flag_rounding_math)
+    {
+      /* If we don't care about rounding mode, then try to convert
+	 this call into round().  */
+      tree const fn = mathfn_built_in (TREE_TYPE (TREE_TYPE (fndecl)),
+				       BUILT_IN_ROUND);
+
+      /* In C90 mode, we won't have access to the replacement builtin,
+	 but we can still try to fold.  */
+      if (fn)
+	return build_call_expr (fn, 1, arg);
+      else
+	return fold_builtin_round (fndecl, arg);
+    }
+
+  return fold_trunc_transparent_mathfn (fndecl, arg);
+}
+
+/* Fold function call to builtin nearbyint* with argument ARG.  Return
+   NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_nearbyint (tree fndecl, tree arg)
+{
+  if (!validate_arg (arg, REAL_TYPE))
+    return NULL_TREE;
+
+  if (!flag_trapping_math)
+    {
+      /* If we don't care about exceptions, then try to convert this
+	 call into rint().  */
+      tree const fn = mathfn_built_in (TREE_TYPE (TREE_TYPE (fndecl)),
+				       BUILT_IN_RINT);
+
+      /* In C90 mode, we won't have access to the replacement builtin,
+	 but we can still try to fold.  */
+      if (fn)
+	return build_call_expr (fn, 1, arg);
+      else
+	return fold_builtin_rint (fndecl, arg);
+    }
+
+  return fold_trunc_transparent_mathfn (fndecl, arg);
+}
+
+/* Fold function call to builtin lrint* with argument ARG.  Return
+   NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_lrint (tree fndecl, tree arg)
+{
+  if (!validate_arg (arg, REAL_TYPE))
+    return NULL_TREE;
+
+  if (!flag_rounding_math)
+    {
+      tree const rettype = TREE_TYPE (TREE_TYPE (fndecl));
+      const enum built_in_function base_fn =
+	TYPE_MAIN_VARIANT (rettype) == long_integer_type_node
+	? BUILT_IN_LROUND : BUILT_IN_LLROUND;
+      /* If we don't care about rounding mode, then try to convert
+	 this call into lround().  */
+      tree const fn = mathfn_built_in (TREE_TYPE (arg), base_fn);
+
+      if (fn)
+	return build_call_expr (fn, 1, arg);
+    }
+
+  /* In C90 mode, we won't have access to the replacement builtin, but
+     we can still try to fold.  */
+  return fold_builtin_int_roundingfn (fndecl, arg);
+}
+
 /* Fold function call to builtin lround, lroundf or lroundl (or the
    corresponding long long versions) and other rounding functions.  ARG
    is the argument to the call.  Return NULL_TREE if no simplification
@@ -7669,6 +7757,11 @@ fold_builtin_int_roundingfn (tree fndecl
 	      real_ceil (&r, TYPE_MODE (ftype), &x);
 	      break;

+	    CASE_FLT_FN (BUILT_IN_LRINT):
+	    CASE_FLT_FN (BUILT_IN_LLRINT):
+	      if (flag_rounding_math)
+		return NULL_TREE;
+	    /* Else fall through... */
 	    CASE_FLT_FN (BUILT_IN_LROUND):
 	    CASE_FLT_FN (BUILT_IN_LLROUND):
 	      real_round (&r, TYPE_MODE (ftype), &x);
@@ -9633,8 +9726,14 @@ fold_builtin_1 (tree fndecl, tree arg0,
       return fold_builtin_round (fndecl, arg0);

     CASE_FLT_FN (BUILT_IN_NEARBYINT):
+      return fold_builtin_nearbyint (fndecl, arg0);
+
     CASE_FLT_FN (BUILT_IN_RINT):
-      return fold_trunc_transparent_mathfn (fndecl, arg0);
+      return fold_builtin_rint (fndecl, arg0);
+
+    CASE_FLT_FN (BUILT_IN_LRINT):
+    CASE_FLT_FN (BUILT_IN_LLRINT):
+      return fold_builtin_lrint (fndecl, arg0);

     CASE_FLT_FN (BUILT_IN_LCEIL):
     CASE_FLT_FN (BUILT_IN_LLCEIL):
@@ -9644,10 +9743,6 @@ fold_builtin_1 (tree fndecl, tree arg0,
     CASE_FLT_FN (BUILT_IN_LLROUND):
       return fold_builtin_int_roundingfn (fndecl, arg0);

-    CASE_FLT_FN (BUILT_IN_LRINT):
-    CASE_FLT_FN (BUILT_IN_LLRINT):
-      return fold_fixed_mathfn (fndecl, arg0);
-
     case BUILT_IN_BSWAP32:
     case BUILT_IN_BSWAP64:
       return fold_builtin_bswap (fndecl, arg0);
diff -rup orig/egcc-SVN20070308/gcc/convert.c egcc-SVN20070308/gcc/convert.c
--- orig/egcc-SVN20070308/gcc/convert.c	2007-03-05 20:02:25.000000000 -0500
+++ egcc-SVN20070308/gcc/convert.c	2007-03-10 14:38:21.707134253 -0500
@@ -403,16 +403,6 @@ convert_to_integer (tree type, tree expr
 	    fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
 	  break;

-	CASE_FLT_FN (BUILT_IN_ROUND):
-	  if (outprec < TYPE_PRECISION (long_integer_type_node)
-	      || (outprec == TYPE_PRECISION (long_integer_type_node)
-		  && !TYPE_UNSIGNED (type)))
-	    fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
-	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
-		   && !TYPE_UNSIGNED (type))
-	    fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
-	  break;
-
 	CASE_FLT_FN (BUILT_IN_NEARBYINT):
 	  /* Only convert nearbyint* if we can ignore math exceptions.  */
 	  if (flag_trapping_math)
@@ -426,6 +416,18 @@ convert_to_integer (tree type, tree expr
 	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
 		   && !TYPE_UNSIGNED (type))
 	    fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
+	  /* If we have rounding math, then stop here.  */
+	  if (flag_rounding_math)
+	    break;
+	  /* ... Fall through ...  */
+	CASE_FLT_FN (BUILT_IN_ROUND):
+	  if (outprec < TYPE_PRECISION (long_integer_type_node)
+	      || (outprec == TYPE_PRECISION (long_integer_type_node)
+		  && !TYPE_UNSIGNED (type)))
+	    fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
+	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
+		   && !TYPE_UNSIGNED (type))
+	    fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
 	  break;

 	CASE_FLT_FN (BUILT_IN_TRUNC):
diff -rup orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c
--- orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c	2007-03-08 20:02:47.000000000 -0500
+++ egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c	2007-03-10 14:16:21.390264987 -0500
@@ -68,6 +68,8 @@ void __attribute__ ((__noinline__)) foo
   TEST_FP2FIXED (round, lround);
   TEST_FP2FIXED (nearbyint, lrint);
   TEST_FP2FIXED (rint, lrint);
+  TEST_FP2FIXED (nearbyint, lround);
+  TEST_FP2FIXED (rint, lround);
 # endif
 #endif
 }
diff -rup orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-4.c egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-4.c
--- orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-4.c	2007-03-05 20:02:17.000000000 -0500
+++ egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-4.c	2007-03-10 14:21:06.865233927 -0500
@@ -1,28 +1,59 @@
 /* Copyright (C) 2007  Free Software Foundation.

    Verify that nearbyint isn't transformed into e.g. rint or lrint
-   when -ftrapping-math is set.
+   when -ftrapping-math is set.  Likewise for rint into round/lround,
+   or lrint into lround when -frounding-math is set.

    Written by Kaveh ghazi, 2007-03-04.  */

 /* { dg-do compile } */
-/* { dg-options "-ftrapping-math -fdump-tree-original" } */
-/* { dg-options "-ftrapping-math -fdump-tree-original -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
-/* { dg-options "-ftrapping-math -fdump-tree-original -std=c99" { target *-*-solaris2* } } */
+/* { dg-options "-ftrapping-math -frounding-math -fdump-tree-original" } */
+/* { dg-options "-ftrapping-math -frounding-math -fdump-tree-original -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
+/* { dg-options "-ftrapping-math -frounding-math -fdump-tree-original -std=c99" { target *-*-solaris2* } } */

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

 extern void bar (long);
+extern void baz (long long);
+extern void blechf (float);
+extern void blech (double);
+extern void blechl (long double);

 #define TESTIT(FUNC) do { \
   bar (__builtin_##FUNC(d)); \
   bar (__builtin_##FUNC##f(f)); \
   bar (__builtin_##FUNC##l(ld)); \
+  baz (__builtin_##FUNC(d)); \
+  baz (__builtin_##FUNC##f(f)); \
+  baz (__builtin_##FUNC##l(ld)); \
+} while (0)
+
+#define TESTIT_LONG(FUNC) do { \
+  bar (__builtin_##FUNC(d)); \
+  bar (__builtin_##FUNC##f(f)); \
+  bar (__builtin_##FUNC##l(ld)); \
+} while (0)
+
+#define TESTIT_LONGLONG(FUNC) do { \
+  baz (__builtin_##FUNC(d)); \
+  baz (__builtin_##FUNC##f(f)); \
+  baz (__builtin_##FUNC##l(ld)); \
+} while (0)
+
+#define TESTIT_FP(FUNC) do { \
+  blech (__builtin_##FUNC(d)); \
+  blechf (__builtin_##FUNC##f(f)); \
+  blechl (__builtin_##FUNC##l(ld)); \
 } while (0)

 void __attribute__ ((__noinline__)) foo (double d, float f, long double ld)
 {
+  /* In the !C99 case, these should all remain unchanged anyway.  */
   TESTIT(nearbyint);
+  TESTIT_FP(nearbyint);
+  TESTIT_FP(rint);
+  TESTIT_LONG(lrint);
+  TESTIT_LONGLONG(llrint);
 }

 int main()
@@ -31,7 +62,16 @@ int main()
   return 0;
 }

-/* { dg-final { scan-tree-dump-times "nearbyint " 1 "original" } } */
-/* { dg-final { scan-tree-dump-times "nearbyintf" 1 "original" } } */
-/* { dg-final { scan-tree-dump-times "nearbyintl" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_nearbyint " 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "_nearbyintf" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "_nearbyintl" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "_rint " 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_rintf" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_rintl" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_lrint " 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_lrintf" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_lrintl" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_llrint " 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_llrintf" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "_llrintl" 1 "original" } } */
 /* { dg-final { cleanup-tree-dump "original" } } */
diff -rup orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-5.c egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-5.c
--- orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-5.c	2007-03-10 14:24:20.965122427 -0500
+++ egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-5.c	2007-03-10 14:16:21.392251461 -0500
@@ -0,0 +1,42 @@
+/* Copyright (C) 2007  Free Software Foundation.
+
+   Verify that nearbyint turns into rint, and that rint/lrint turns
+   into round/lround when -ffast-math is set.  This assumes that
+   -fno-rounding-math is the default.
+
+   Written by Kaveh ghazi, 2007-03-09.  */
+
+/* { dg-do compile } */
+/* { dg-options "-ffast-math" } */
+/* { dg-options "-ffast-math -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
+/* { dg-options "-ffast-math -std=c99" { target *-*-solaris2* } } */
+
+#include "../builtins-config.h"
+
+extern void link_error (int);
+
+#define TESTIT(FUNC1,FUNC2) do { \
+  if (__builtin_##FUNC1(d) != __builtin_##FUNC2(d)) \
+    link_error (__LINE__); \
+  if (__builtin_##FUNC1##f(f) != __builtin_##FUNC2##f(f)) \
+    link_error (__LINE__); \
+  if (__builtin_##FUNC1##l(ld) != __builtin_##FUNC2##l(ld)) \
+    link_error (__LINE__); \
+} while (0)
+
+void __attribute__ ((__noinline__)) foo (double d, float f, long double ld)
+{
+#ifdef HAVE_C99_RUNTIME
+  TESTIT(nearbyint,rint);
+  TESTIT(nearbyint,round);
+  TESTIT(rint,round);
+  TESTIT(lrint,lround);
+  TESTIT(llrint,llround);
+#endif
+}
+
+int main()
+{
+  foo (1.0, 2.0, 3.0);
+  return 0;
+}
diff -rup orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-6.c egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-6.c
--- orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-6.c	2007-03-10 14:24:26.092317660 -0500
+++ egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-convert-6.c	2007-03-10 14:16:21.393104430 -0500
@@ -0,0 +1,42 @@
+/* Copyright (C) 2007  Free Software Foundation.
+
+   Verify that rint/lrint are transformed into round/lround iff
+   -fno-rounding-math (the default).  We need -ffinite-math-only so
+   that the '!=' folds and we need -fno-math-errno so that the
+   functions are const.  we don't use -ffast-math because we don't
+   want -fno-trapping-math set.
+
+   Written by Kaveh ghazi, 2007-03-09.  */
+
+/* { dg-do compile } */
+/* { dg-options "-ffinite-math-only -fno-math-errno" } */
+/* { dg-options "-ffinite-math-only -fno-math-errno -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
+/* { dg-options "-ffinite-math-only -fno-math-errno -std=c99" { target *-*-solaris2* } } */
+
+#include "../builtins-config.h"
+
+extern void link_error (int);
+
+#define TESTIT(FUNC1,FUNC2) do { \
+  if (__builtin_##FUNC1(d) != __builtin_##FUNC2(d)) \
+    link_error (__LINE__); \
+  if (__builtin_##FUNC1##f(f) != __builtin_##FUNC2##f(f)) \
+    link_error (__LINE__); \
+  if (__builtin_##FUNC1##l(ld) != __builtin_##FUNC2##l(ld)) \
+    link_error (__LINE__); \
+} while (0)
+
+void __attribute__ ((__noinline__)) foo (double d, float f, long double ld)
+{
+#ifdef HAVE_C99_RUNTIME
+  TESTIT(rint,round);
+  TESTIT(lrint,lround);
+  TESTIT(llrint,llround);
+#endif
+}
+
+int main()
+{
+  foo (1.0, 2.0, 3.0);
+  return 0;
+}
diff -rup orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c
--- orig/egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c	2007-03-10 14:25:08.050131504 -0500
+++ egcc-SVN20070308/gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c	2007-03-10 14:16:21.393972842 -0500
@@ -0,0 +1,67 @@
+/* Copyright (C) 2007 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, 2007-03-09.  */
+
+/* { dg-do link } */
+/* { dg-options "-fno-trapping-math -fno-rounding-math" } */
+
+extern int link_error (int);
+
+#define TEST(FN, VALUE, RESULT) \
+  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)
+{
+  TEST(lrint,     0, 0);
+  TEST(llrint,    0, 0);
+  TEST(rint,      0, 0);
+  TEST(nearbyint, 0, 0);
+
+  TEST(lrint,     6, 6);
+  TEST(llrint,    6, 6);
+  TEST(rint,      6, 6);
+  TEST(nearbyint, 6, 6);
+
+  TEST(lrint,     -8, -8);
+  TEST(llrint,    -8, -8);
+  TEST(rint,      -8, -8);
+  TEST(nearbyint, -8, -8);
+
+  TEST(lrint,     3.2, 3);
+  TEST(llrint,    3.2, 3);
+  TEST(rint,      3.2, 3);
+  TEST(nearbyint, 3.2, 3);
+
+  TEST(lrint,     -2.8, -3);
+  TEST(llrint,    -2.8, -3);
+  TEST(rint,      -2.8, -3);
+  TEST(nearbyint, -2.8, -3);
+
+  TEST(lrint,     0.01, 0);
+  TEST(llrint,    0.01, 0);
+  TEST(rint,      0.01, 0);
+  TEST(nearbyint, 0.01, 0);
+
+  TEST(lrint,     -0.7, -1);
+  TEST(llrint,    -0.7, -1);
+  TEST(rint,      -0.7, -1);
+  TEST(nearbyint, -0.7, -1);
+
+  TEST(lrint,     2.5, 3);
+  TEST(llrint,    2.5, 3);
+  TEST(rint,      2.5, 3);
+  TEST(nearbyint, 2.5, 3);
+
+  TEST(lrint,     -1.5, -2);
+  TEST(llrint,    -1.5, -2);
+  TEST(rint,      -1.5, -2);
+  TEST(nearbyint, -1.5, -2);
+
+  return 0;
+}


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