re PR middle-end/27116 (Incorrect integer division (wrong sign).)
authorRichard Guenther <rguenther@suse.de>
Thu, 8 Jun 2006 08:49:19 +0000 (08:49 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 8 Jun 2006 08:49:19 +0000 (08:49 +0000)
2006-06-08  Richard Guenther  <rguenther@suse.de>

PR middle-end/27116
* fold-const.c (negate_expr_p): We can negate BIT_NOT_EXPR
only, if overflow is defined and not trapping.
(negate_expr): Likewise.

* gcc.dg/torture/pr27116.c: New testcase.
* gcc.dg/pr15785-1.c: Remove test for invalid transformation.

From-SVN: r114483

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr15785-1.c
gcc/testsuite/gcc.dg/torture/pr27116.c [new file with mode: 0644]

index ea88049fbd1499cd37049f693a86d74e0446fa1f..12bd4194eb926a3956cf72653f2c469d1bf045f1 100644 (file)
@@ -1,3 +1,10 @@
+2006-06-08  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/27116
+       * fold-const.c (negate_expr_p): We can negate BIT_NOT_EXPR
+       only, if overflow is defined and not trapping.
+       (negate_expr): Likewise.
+
 2006-06-07  Zdenek Dvorak <dvorakz@suse.cz>
 
        PR tree-optimization/27872
index 6f19704a8f666233d99698d2a7137f4e4c860413..3e9ccbe4f66bc893699f63ecf9a260a5003c7647 100644 (file)
@@ -945,7 +945,9 @@ negate_expr_p (tree t)
       /* Check that -CST will not overflow type.  */
       return may_negate_without_overflow_p (t);
     case BIT_NOT_EXPR:
-       return INTEGRAL_TYPE_P (type);
+       return INTEGRAL_TYPE_P (type)
+                     && (TYPE_UNSIGNED (type)
+                 || (flag_wrapv && !flag_trapv));
 
     case REAL_CST:
     case NEGATE_EXPR:
@@ -1047,7 +1049,9 @@ negate_expr (tree t)
     {
     /* Convert - (~A) to A + 1.  */
     case BIT_NOT_EXPR:
-      if (INTEGRAL_TYPE_P (type))
+      if (INTEGRAL_TYPE_P (type)
+         && (TYPE_UNSIGNED (type)
+             || (flag_wrapv && !flag_trapv)))
         return fold_build2 (PLUS_EXPR, type, TREE_OPERAND (t, 0),
                             build_int_cst (type, 1));
       break;
index 78cbebc233f9887892226f66c690fec55cd5bfee..cfeeaeb83e2e5f3e9ee3569b00ef0ae09cd861a7 100644 (file)
@@ -1,3 +1,9 @@
+2006-06-08  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/27116
+       * gcc.dg/torture/pr27116.c: New testcase.
+       * gcc.dg/pr15785-1.c: Remove test for invalid transformation.
+
 2006-06-07  Zdenek Dvorak <dvorakz@suse.cz>
 
        PR rtl-optimization/26449
index 47cd3d7b01bc90f74169f5d5a1d201b3508f5882..5e79ec50bbb95c03d2be1e434c91074d719bf624 100644 (file)
@@ -11,11 +11,6 @@ void b (int x) {
                link_error ();
 }
 
-void c (int x) {
-       if (!(- (~x) - x))
-               link_error ();
-}
-
 void d (int x) {
        if (!(~ (-x) - x))
                link_error ();
@@ -34,7 +29,6 @@ void f (int x) {
 int main (int argc, char *argv[]) {
        a(argc);
        b(argc);
-       c(argc);
        d(argc);
        e(argc);
        f(argc);
diff --git a/gcc/testsuite/gcc.dg/torture/pr27116.c b/gcc/testsuite/gcc.dg/torture/pr27116.c
new file mode 100644 (file)
index 0000000..70eeb1a
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+extern void abort(void);
+
+int f(int a, int b)
+{
+  return (-1 - a) / (-b);
+}
+
+int main()
+{
+  if (f(__INT_MAX__, 2) != __INT_MAX__/2 + 1)
+    abort ();
+  return 0;
+}