summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr23604.c22
-rw-r--r--gcc/tree-vrp.c29
4 files changed, 58 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 34561df2e8b..95db709fc39 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-10-01 James A. Morrison <phython@gcc.gnu.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ PR 23604
+ * tree-vrp.c (extract_range_from_assert): For !=
+ assertions, only build an anti-range if LIMIT is a
+ single-valued range.
+
2005-09-30 Richard Earnshaw <richard.earnshaw@arm.com>
* arm.md (movqi): On thumb when optimizing, handle loading from
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 00b067a34a5..aff2b8d92cb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-10-01 James A. Morrison <phython@gcc.gnu.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ PR 23604
+ * gcc.c-torture/execute/pr23604.c: New test.
+
2005-10-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/16404
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr23604.c b/gcc/testsuite/gcc.c-torture/execute/pr23604.c
new file mode 100644
index 00000000000..4c2b80d56ca
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr23604.c
@@ -0,0 +1,22 @@
+extern void abort (void);
+
+int g(int i, int j)
+{
+ if (i>-1)
+ if (i<2)
+ {
+ if (i != j)
+ {
+ if (j != 0)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int main(void)
+{
+ if (!g(1, 0))
+ abort ();
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 4aec9fcc4dd..21e6cf6d100 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -774,17 +774,32 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
not imply that VAR's range is [0, 0]. So, in the case of
anti-ranges, we just assert the inequality using LIMIT and
- not its anti-range. */
- if (limit_vr == NULL
- || limit_vr->type == VR_ANTI_RANGE)
+ not its anti-range.
+
+ If LIMIT_VR is a range, we can only use it to build a new
+ anti-range if LIMIT_VR is a single-valued range. For
+ instance, if LIMIT_VR is [0, 1], the predicate
+ VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
+ Rather, it means that for value 0 VAR should be ~[0, 0]
+ and for value 1, VAR should be ~[1, 1]. We cannot
+ represent these ranges.
+
+ The only situation in which we can build a valid
+ anti-range is when LIMIT_VR is a single-valued range
+ (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case,
+ build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */
+ if (limit_vr
+ && limit_vr->type == VR_RANGE
+ && compare_values (limit_vr->min, limit_vr->max) == 0)
{
- min = limit;
- max = limit;
+ min = limit_vr->min;
+ max = limit_vr->max;
}
else
{
- min = limit_vr->min;
- max = limit_vr->max;
+ /* In any other case, we cannot use LIMIT's range to build a
+ valid anti-range. */
+ min = max = limit;
}
/* If MIN and MAX cover the whole range for their type, then
OpenPOWER on IntegriCloud