builtins.c (fold_fixed_mathfn): When long and long long are the same size...
authorRoger Sayle <roger@eyesopen.com>
Thu, 27 Jul 2006 14:02:27 +0000 (14:02 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 27 Jul 2006 14:02:27 +0000 (14:02 +0000)
* builtins.c (fold_fixed_mathfn): When long and long long are the
same size, canonicalize llceil*, llfloor*, llround* and llrint*
functions to their lceil*, lfloor*, lround* and lrint* forms.

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

From-SVN: r115775

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-55.c [new file with mode: 0644]

index 31261ce..aedce72 100644 (file)
@@ -1,3 +1,9 @@
+2006-07-27  Roger Sayle  <roger@eyesopen.com>
+
+       * builtins.c (fold_fixed_mathfn): When long and long long are the
+       same size, canonicalize llceil*, llfloor*, llround* and llrint*
+       functions to their lceil*, lfloor*, lround* and lrint* forms.
+
 2006-07-27  Kazuhiro Inaoka  <inaoka.kazuhiro@renesas.com>
 
        PR gcc/28508
index 80f2fbb..47c61cd 100644 (file)
@@ -6772,6 +6772,42 @@ fold_fixed_mathfn (tree fndecl, tree arglist)
          return build_function_call_expr (decl, arglist);
        }
     }
+
+  /* Canonicalize llround (x) to lround (x) on LP64 targets where
+     sizeof (long long) == sizeof (long).  */
+  if (TYPE_PRECISION (long_long_integer_type_node)
+      == TYPE_PRECISION (long_integer_type_node))
+    {
+      tree newfn = NULL_TREE;
+      switch (fcode)
+       {
+       CASE_FLT_FN (BUILT_IN_LLCEIL):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLFLOOR):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLROUND):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLRINT):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
+         break;
+
+       default:
+         break;
+       }
+
+      if (newfn)
+       {
+         tree newcall = build_function_call_expr (newfn, arglist);
+         return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
+       }
+    }
+
   return 0;
 }
 
index 6f504ce..cc0bc14 100644 (file)
@@ -1,3 +1,7 @@
+2006-07-27  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.dg/builtins-55.c: New test case.
+
 2006-07-26  Zdenek Dvorak <dvorakz@suse.cz>
 
        PR rtl-optimization/27907
diff --git a/gcc/testsuite/gcc.dg/builtins-55.c b/gcc/testsuite/gcc.dg/builtins-55.c
new file mode 100644 (file)
index 0000000..d804f29
--- /dev/null
@@ -0,0 +1,75 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -ffast-math" } */
+/* { dg-options "-ffast-math -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
+/* { dg-options "-O2 -ffast-math -std=c99" { target *-*-solaris2* } } */
+
+#include "builtins-config.h"
+
+void link_error (void);
+
+extern long lround(double);
+extern long lrint(double);
+
+extern long long llround(double);
+extern long long llrint(double);
+
+extern long lroundf(float);
+extern long lrintf(float);
+
+extern long long llroundf(float);
+extern long long llrintf(float);
+
+extern long lroundl(long double);
+extern long lrintl(long double);
+
+extern long long llroundl(long double);
+extern long long llrintl(long double);
+
+
+void test(double x)
+{
+#ifdef HAVE_C99_RUNTIME
+  if (sizeof(long) != sizeof(long long))
+    return;
+
+  if (lround(x) != llround(x))
+    link_error();
+  if (lrint(x) != llrint(x))
+    link_error();
+#endif
+}
+
+void testf(float x)
+{
+#ifdef HAVE_C99_RUNTIME
+  if (sizeof(long) != sizeof(long long))
+    return;
+
+  if (lroundf(x) != llroundf(x))
+    link_error();
+  if (lrintf(x) != llrintf(x))
+    link_error();
+#endif
+}
+
+void testl(long double x)
+{
+#ifdef HAVE_C99_RUNTIME
+  if (sizeof(long) != sizeof(long long))
+    return;
+
+  if (lroundl(x) != llroundl(x))
+    link_error();
+  if (lrintl(x) != llrintl(x))
+    link_error();
+#endif
+}
+
+int main()
+{
+  test(0.0);
+  testf(0.0);
+  testl(0.0);
+  return 0;
+}
+