OSDN Git Service

2006-06-09 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jun 2006 12:39:11 +0000 (12:39 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jun 2006 12:39:11 +0000 (12:39 +0000)
PR tree-optimization/26998
* tree-vrp.c (extract_range_from_unary_expr): For NEGATE_EXPR
of signed types, only TYPE_MIN_VALUE is special, but for both,
minimum and maximum value.  Likewise VR_ANTI_RANGE is special
in this case, as is -fwrapv.

* gcc.dg/torture/pr26998.c: New testcase.
* gcc.dg/tree-ssa/vrp29.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114507 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr26998.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/vrp29.c [new file with mode: 0644]
gcc/tree-vrp.c

index ce53bb2..79f68e9 100644 (file)
@@ -1,3 +1,11 @@
+2006-06-09  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/26998
+       * tree-vrp.c (extract_range_from_unary_expr): For NEGATE_EXPR
+       of signed types, only TYPE_MIN_VALUE is special, but for both,
+       minimum and maximum value.  Likewise VR_ANTI_RANGE is special
+       in this case, as is -fwrapv.
+
 2006-06-08  Mike Stump  <mrs@apple.com>
 
        PR target/26427
index 267c08c..f187c31 100644 (file)
@@ -1,3 +1,9 @@
+2006-06-09  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/26998
+       * gcc.dg/torture/pr26998.c: New testcase.
+       * gcc.dg/tree-ssa/vrp29.c: New testcase.
+
 2006-06-08  Mike Stump  <mrs@apple.com>
 
        * gcc.dg/pr27095.c: Account for stubs.
diff --git a/gcc/testsuite/gcc.dg/torture/pr26998.c b/gcc/testsuite/gcc.dg/torture/pr26998.c
new file mode 100644 (file)
index 0000000..d50c344
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int decCompareOp (int result)
+{
+    if (result != (int)0x80000000)
+    {
+        result = -result;
+        return (result > 0);
+    }
+    return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp29.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp29.c
new file mode 100644 (file)
index 0000000..bace4ff
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort(void);
+
+void decCompareOp (int result)
+{
+  if (result != (int)0x80000000)
+    {
+      result = -result;
+      if (result != (int)0x80000001)
+        abort ();
+    }
+}
+
+int main()
+{
+  decCompareOp (0x7fffffff);
+  return 0;
+}
index 3ac01fb..9eac7e9 100644 (file)
@@ -1795,14 +1795,21 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
   if (code == NEGATE_EXPR
       && !TYPE_UNSIGNED (TREE_TYPE (expr)))
     {
-      /* NEGATE_EXPR flips the range around.  */
-      min = (vr0.max == TYPE_MAX_VALUE (TREE_TYPE (expr)) && !flag_wrapv)
-            ? TYPE_MIN_VALUE (TREE_TYPE (expr))
-            : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
-
-      max = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)) && !flag_wrapv)
-            ? TYPE_MAX_VALUE (TREE_TYPE (expr))
-            : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+      /* NEGATE_EXPR flips the range around.  We need to treat
+        TYPE_MIN_VALUE specially dependent on wrapping, range type
+        and if it was used as minimum or maximum value:  
+         -~[MIN, MIN] == ~[MIN, MIN]
+         -[MIN, 0] == [0, MAX]  for -fno-wrapv
+         -[MIN, 0] == [0, MIN]  for -fwrapv (will be set to varying later)  */
+      min = vr0.max == TYPE_MIN_VALUE (TREE_TYPE (expr))
+           ? TYPE_MIN_VALUE (TREE_TYPE (expr))
+           : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+
+      max = vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr))
+           ? (vr0.type == VR_ANTI_RANGE || flag_wrapv
+              ? TYPE_MIN_VALUE (TREE_TYPE (expr))
+              : TYPE_MAX_VALUE (TREE_TYPE (expr)))
+           : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
 
     }
   else if (code == NEGATE_EXPR