+2006-07-30 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/28473
+ Backport from mainline.
+ * convert.c (convert_to_integer): When transforming (T)foo(x) into
+ bar(x) check that bar's result type can represent all the values of T.
+ * 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-26 Richard Sandiford <richard@codesourcery.com>
PR middle-end/28403
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 BUILT_IN_LLROUND:
+ case BUILT_IN_LLROUNDF:
+ case BUILT_IN_LLROUNDL:
+ newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
+ break;
+
+ case BUILT_IN_LLRINT:
+ case BUILT_IN_LLRINTF:
+ case BUILT_IN_LLRINTL:
+ 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;
}
/* Utility routines for data type conversion for GCC.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
- 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
switch (fcode)
{
case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL:
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
- fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
- else
+ 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 BUILT_IN_RINT: case BUILT_IN_RINTF: case BUILT_IN_RINTL:
if (flag_trapping_math)
break;
/* ... Fall through ... */
- case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL:
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
- fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
- else
- fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ 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_LRINT);
+ else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
+ && !TYPE_UNSIGNED (type))
+ fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
break;
default:
break;
+2006-07-30 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/28473
+ * gcc.dg/fold-convround-1.c: New test case.
+ * gcc.dg/builtins-55.c: New test case.
+
2006-07-26 Richard Sandiford <richard@codesourcery.com>
PR middle-end/28403
--- /dev/null
+/* { 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;
+}
+
--- /dev/null
+/* PR middle-end/28473. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+extern double round(double);
+extern double floor(double);
+extern double ceil(double);
+
+unsigned long long test1(double x)
+{
+ return (unsigned long long) round(x);
+}
+
+unsigned long long test2(double x)
+{
+ return (unsigned long long) floor(x);
+}
+unsigned long long test3(double x)
+{
+ return (unsigned long long) ceil(x);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_lround" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_llround" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_lfloor" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_llfloor" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_lceil" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_llceil" 0 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
+