re PR middle-end/28473 (with -O, casting result of round(x) to uint64_t produces...
authorRoger Sayle <roger@eyesopen.com>
Tue, 25 Jul 2006 23:21:56 +0000 (23:21 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 25 Jul 2006 23:21:56 +0000 (23:21 +0000)
PR middle-end/28473
* 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.

* gcc.dg/fold-convround-1.c: New test case.

From-SVN: r115742

gcc/ChangeLog
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-convround-1.c [new file with mode: 0644]

index 80caad9eddedf2d3dcfb9ad51e453f2a7b824e31..0ec948f9b2a8127becdd897a934bf036e127a69f 100644 (file)
@@ -1,3 +1,9 @@
+2006-07-25  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/28473
+       * 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.
+
 2006-07-25  Zdenek Dvorak <dvorakz@suse.cz>
 
        * tree-chrec.c (chrec_convert_aggressive): Return NULL on failure.
index ab780d8ebd37cc61ea49849b5980c3aa5618d19c..27571956a1ead9aa7b93b2d6c95e00a118323e66 100644 (file)
@@ -388,27 +388,36 @@ convert_to_integer (tree type, tree expr)
          /* Only convert in ISO C99 mode.  */
          if (!TARGET_C99_FUNCTIONS)
            break;
-         if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
-           fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
-         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_LCEIL);
+         else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
+                  && !TYPE_UNSIGNED (type))
+           fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
          break;
 
        CASE_FLT_FN (BUILT_IN_FLOOR):
          /* Only convert in ISO C99 mode.  */
          if (!TARGET_C99_FUNCTIONS)
            break;
-         if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
-           fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
-         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_LFLOOR);
+         else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
+                  && !TYPE_UNSIGNED (type))
+           fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
          break;
 
        CASE_FLT_FN (BUILT_IN_ROUND):
-         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_FLT_FN (BUILT_IN_RINT):
@@ -417,10 +426,13 @@ convert_to_integer (tree type, tree expr)
            break;
          /* ... Fall through ...  */
        CASE_FLT_FN (BUILT_IN_NEARBYINT):
-         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);
+         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;
 
        CASE_FLT_FN (BUILT_IN_TRUNC):
index 00fd5b8e53bed0f47da4cb1fc5872038b7ce1816..63aadaf8e28d0b6bd5938608a8f5bc5d92d3d17e 100644 (file)
@@ -1,3 +1,8 @@
+2006-07-25  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/28473
+       * gcc.dg/fold-convround-1.c: New test case.
+
 2006-07-24  Steven G. Kargl  <kargls@comcast.net>
 
        * gfortran.dg/arithmetic_if.f90:  Fix comments.
diff --git a/gcc/testsuite/gcc.dg/fold-convround-1.c b/gcc/testsuite/gcc.dg/fold-convround-1.c
new file mode 100644 (file)
index 0000000..86612aa
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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" } } */
+