aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2005-07-28 04:35:01 +0000
committerJames A. Morrison <phython@gcc.gnu.org>2005-07-28 04:35:01 +0000
commitff08cbee5d5465c88852dbb3cff344c45d98c95e (patch)
treef1a698467d1c1cf4ac02bddd1b2e54447cb91aaf
parentb089e33adcdb287020bbc1294df6bebf6701025b (diff)
downloadgcc-ff08cbee5d5465c88852dbb3cff344c45d98c95e.zip
gcc-ff08cbee5d5465c88852dbb3cff344c45d98c95e.tar.gz
gcc-ff08cbee5d5465c88852dbb3cff344c45d98c95e.tar.bz2
re PR tree-optimization/22493 (with -fwrapv -INT_MIN is still not positive)
2005-07-27 James A. Morrison <phython@gcc.gnu.org> PR tree-optimization/22493 * tree-vrp.c (extract_range_from_unary_expr): Deal with -fwrapv and VR_ANTI_RANGEs properly for NEGATE_EXPRs and ABS_EXPRs. From-SVN: r102458
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr22493-1.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr22493-1.x2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vrp-1.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vrp-2.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vrp-3.c21
-rw-r--r--gcc/tree-vrp.c90
8 files changed, 165 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 299d206..b0d7bff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-27 James A. Morrison <phython@gcc.gnu.org>
+
+ PR tree-optimization/22493
+ * tree-vrp.c (extract_range_from_unary_expr): Deal with -fwrapv and
+ VR_ANTI_RANGEs properly for NEGATE_EXPRs and ABS_EXPRs.
+
2005-07-27 Aldy Hernandez <aldyh@redhat.com>
* config/frv/frv.opt (moptimize-membar): New.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a98dd06..d2861aa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-27 James A. Morrison <phython@gcc.gnu.org>
+
+ PR rtl-optimization/22493
+ * gcc.c-torture/execute/pr22493-1.c: New test.
+ * gcc.c-torture/execute/pr22493-1.x: New.
+ * gcc.c-torture/execute/vrp-1.c: New test.
+ * gcc.c-torture/execute/vrp-2.c: New test.
+ * gcc.c-torture/execute/vrp-2.c: New test.
+
2005-07-27 Aldy Hernandez <aldyh@redhat.com>
* gcc.target/frv/all-builtin-read8.c: Delete.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22493-1.c b/gcc/testsuite/gcc.c-torture/execute/pr22493-1.c
new file mode 100644
index 0000000..bc0ff78
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr22493-1.c
@@ -0,0 +1,18 @@
+#include <limits.h>
+extern void abort ();
+extern void exit (int);
+void f(int i)
+{
+ if (i>0)
+ abort();
+ i = -i;
+ if (i<0)
+ return;
+ abort ();
+}
+
+int main(int argc, char *argv[])
+{
+ f(INT_MIN);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22493-1.x b/gcc/testsuite/gcc.c-torture/execute/pr22493-1.x
new file mode 100644
index 0000000..36a5839
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr22493-1.x
@@ -0,0 +1,2 @@
+set additional_flags "-fwrapv"
+return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/vrp-1.c b/gcc/testsuite/gcc.c-torture/execute/vrp-1.c
new file mode 100644
index 0000000..ac42e6c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/vrp-1.c
@@ -0,0 +1,20 @@
+
+extern void abort ();
+extern void exit (int);
+
+int f (int a) {
+ if (a != 2) {
+ a = -a;
+ if (a == 2)
+ return 0;
+ return 1;
+ }
+ return 1;
+}
+
+int main (int argc, char *argv[]) {
+ if (f (-2))
+ abort ();
+ exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/vrp-2.c b/gcc/testsuite/gcc.c-torture/execute/vrp-2.c
new file mode 100644
index 0000000..69ed3e7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/vrp-2.c
@@ -0,0 +1,19 @@
+extern void abort ();
+extern void exit (int);
+
+int f (int a) {
+ if (a != 2) {
+ a = a > 0 ? a : -a;
+ if (a == 2)
+ return 0;
+ return 1;
+ }
+ return 1;
+}
+
+int main (int argc, char *argv[]) {
+ if (f (-2))
+ abort ();
+ exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/vrp-3.c b/gcc/testsuite/gcc.c-torture/execute/vrp-3.c
new file mode 100644
index 0000000..bc0e490
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/vrp-3.c
@@ -0,0 +1,21 @@
+extern void abort ();
+extern void exit (int);
+
+int f (int a) {
+ if (a < 12) {
+ if (a > -15) {
+ a = a > 0 ? a : -a;
+ if (a == 2)
+ return 0;
+ return 1;
+ }
+ }
+ return 1;
+}
+
+int main (int argc, char *argv[]) {
+ if (f (-2))
+ abort ();
+ exit (0);
+}
+
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 58fb7ef..af79ba4 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1353,27 +1353,31 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
if (code == NEGATE_EXPR
&& !TYPE_UNSIGNED (TREE_TYPE (expr)))
{
- /* Negating an anti-range doesn't really do anything to it. The
- new range will also not take on the same range of values
- excluded by the original anti-range. */
- if (vr0.type == VR_ANTI_RANGE)
- {
- copy_value_range (vr, &vr0);
- return;
- }
-
/* NEGATE_EXPR flips the range around. */
- min = (vr0.max == TYPE_MAX_VALUE (TREE_TYPE (expr)))
- ? TYPE_MIN_VALUE (TREE_TYPE (expr))
- : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+ 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)))
- ? TYPE_MAX_VALUE (TREE_TYPE (expr))
- : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+ 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);
}
else if (code == ABS_EXPR
&& !TYPE_UNSIGNED (TREE_TYPE (expr)))
{
+ /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
+ useful range. */
+ if (flag_wrapv
+ && ((vr0.type == VR_RANGE
+ && vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
+ || (vr0.type == VR_ANTI_RANGE
+ && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))
+ && !range_includes_zero_p (&vr0))))
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
/* ABS_EXPR may flip the range around, if the original range
included negative values. */
min = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
@@ -1382,12 +1386,58 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
- /* If the range was reversed, swap MIN and MAX. */
- if (compare_values (min, max) == 1)
+ cmp = compare_values (min, max);
+
+ /* If a VR_ANTI_RANGEs contains zero, then we have
+ ~[-INF, min(MIN, MAX)]. */
+ if (vr0.type == VR_ANTI_RANGE)
+ {
+ if (range_includes_zero_p (&vr0))
+ {
+ tree type_min_value = TYPE_MIN_VALUE (TREE_TYPE (expr));
+
+ /* Take the lower of the two values. */
+ if (cmp != 1)
+ max = min;
+
+ /* Create ~[-INF, min (abs(MIN), abs(MAX))]
+ or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
+ flag_wrapv is set and the original anti-range doesn't include
+ TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE. */
+ min = (flag_wrapv && vr0.min != type_min_value
+ ? int_const_binop (PLUS_EXPR,
+ type_min_value,
+ integer_one_node, 0)
+ : type_min_value);
+ }
+ else
+ {
+ /* All else has failed, so create the range [0, INF], even for
+ flag_wrapv since TYPE_MIN_VALUE is in the original
+ anti-range. */
+ vr0.type = VR_RANGE;
+ min = build_int_cst (TREE_TYPE (expr), 0);
+ max = TYPE_MAX_VALUE (TREE_TYPE (expr));
+ }
+ }
+
+ /* If the range contains zero then we know that the minimum value in the
+ range will be zero. */
+ else if (range_includes_zero_p (&vr0))
+ {
+ if (cmp == 1)
+ max = min;
+ min = build_int_cst (TREE_TYPE (expr), 0);
+ }
+ else
{
- tree t = min;
- min = max;
- max = t;
+ /* If the range was reversed, swap MIN and MAX. */
+ if (cmp == 1)
+ {
+ tree t = min;
+ min = max;
+ max = t;
+ }
}
}
else