From: James A. Morrison Date: Sat, 1 Oct 2005 13:57:29 +0000 (+0000) Subject: re PR tree-optimization/23604 (wrong code due to VRP) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fde5c44c5c8c5ea33da3cef11ad742309733dfb8;p=gcc.git re PR tree-optimization/23604 (wrong code due to VRP) PR 23604 * tree-vrp.c (extract_range_from_assert): For != assertions, only build an anti-range if LIMIT is a single-valued range. testsuite/ PR 23604 * gcc.c-torture/execute/pr23604.c: New test. Co-Authored-By: Diego Novillo From-SVN: r104858 --- 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 + Diego Novillo + + 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 * 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 + Diego Novillo + + PR 23604 + * gcc.c-torture/execute/pr23604.c: New test. + 2005-10-01 Paul Thomas 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