]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c/43007 (No longer folds (unsigned int) ((long long unsigned int) spi_bias...
authorRichard Guenther <rguenther@suse.de>
Wed, 10 Feb 2010 11:54:14 +0000 (11:54 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 10 Feb 2010 11:54:14 +0000 (11:54 +0000)
2010-02-10  Richard Guenther  <rguenther@suse.de>

PR c/43007
* tree.c (get_unwidened): Handle constants.
* convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.

* gcc.c-torture/execute/20100209-1.c: New testcase.
* gcc.dg/fold-div-3.c: Likewise.

From-SVN: r156653

gcc/ChangeLog
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20100209-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-div-3.c [new file with mode: 0644]
gcc/tree.c

index ecda788cf44dee19a6b117e5726274a90da64506..ce3d0868de0f3c9a6733a5a14e87a48e83ba2ad5 100644 (file)
@@ -1,3 +1,9 @@
+2010-02-10  Richard Guenther  <rguenther@suse.de>
+
+       PR c/43007
+       * tree.c (get_unwidened): Handle constants.
+       * convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.
+
 2010-02-10  Martin Jambor  <mjambor@suse.cz>
 
        PR lto/42985
index 4fe95ced915aae7aed263527177d3a8307772404..39fbd4d4fa5c34ff32f6f8c1e8a55e7aab806c49 100644 (file)
@@ -673,6 +673,31 @@ convert_to_integer (tree type, tree expr)
            }
          break;
 
+       case TRUNC_DIV_EXPR:
+         {
+           tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+           tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
+
+           /* Don't distribute unless the output precision is at least as big
+              as the actual inputs and it has the same signedness.  */
+           if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
+               && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
+               /* If signedness of arg0 and arg1 don't match,
+                  we can't necessarily find a type to compare them in.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+                   == TYPE_UNSIGNED (TREE_TYPE (arg1)))
+               /* Do not change the sign of the division.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (expr))
+                   == TYPE_UNSIGNED (TREE_TYPE (arg0)))
+               /* Either require unsigned division or a division by
+                  a constant that is not -1.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+                   || (TREE_CODE (arg1) == INTEGER_CST
+                       && !integer_all_onesp (arg1))))
+             goto trunc1;
+           break;
+         }
+
        case MAX_EXPR:
        case MIN_EXPR:
        case MULT_EXPR:
index 59181d7c97c6417af8f4ba1e9a7fbafed024a37a..273636cf297143dedbfd7f3aa8ea90aebaee2159 100644 (file)
@@ -1,3 +1,9 @@
+2010-02-10  Richard Guenther  <rguenther@suse.de>
+
+       PR c/43007
+       * gcc.c-torture/execute/20100209-1.c: New testcase.
+       * gcc.dg/fold-div-3.c: Likewise.
+
 2010-02-10  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.dg/builtin-ffs-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20100209-1.c b/gcc/testsuite/gcc.c-torture/execute/20100209-1.c
new file mode 100644 (file)
index 0000000..bf0597b
--- /dev/null
@@ -0,0 +1,12 @@
+int bar(int foo)
+{
+  return (int)(((unsigned long long)(long long)foo) / 8);
+}
+extern void abort (void);
+int main()
+{
+  if (sizeof (long long) > sizeof (int)
+      && bar(-1) != -1)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fold-div-3.c b/gcc/testsuite/gcc.dg/fold-div-3.c
new file mode 100644 (file)
index 0000000..2e78757
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-original" } */
+
+unsigned int
+apply_frontend_param (unsigned int spi_bias)
+{
+  static const int ppm = 8000;
+  spi_bias /= 1000ULL + ppm/1000;
+  return spi_bias;
+}
+
+/* Make sure we perform the division in the narrower type.  */
+
+/* { dg-final { scan-tree-dump "spi_bias = spi_bias / 1008;" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
index 5d44841769fd10b0089de0081ba2a2486ce23bac..c51cca7d6f76dcb0e7f08357838e4c006c716103 100644 (file)
@@ -7623,6 +7623,14 @@ get_unwidened (tree op, tree for_type)
        }
     }
 
+  /* If we finally reach a constant see if it fits in for_type and
+     in that case convert it.  */
+  if (for_type
+      && TREE_CODE (win) == INTEGER_CST
+      && TREE_TYPE (win) != for_type
+      && int_fits_type_p (win, for_type))
+    win = fold_convert (for_type, win);
+
   return win;
 }
 \f
This page took 0.0786 seconds and 5 git commands to generate.