diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Warray-bounds-19.c | 17 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 21 |
4 files changed, 49 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d5b011..af1b6c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-03-30 Patrick Palka <ppalka@gcc.gnu.org> + + PR tree-optimization/59124 + * tree-vrp.c (register_edge_assert_for_2): For NAME != CST1 + where NAME = A +- CST2 add the assertion A != (CST1 -+ CST2). + 2016-03-29 Jeff Law <law@redhat.com> * tree-ssa-coalesce.c (struct ssa_conflicts): Fix typo in diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd0dc5d..2d0ecda 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-03-30 Patrick Palka <ppalka@gcc.gnu.org> + + PR tree-optimization/59124 + * gcc.dg/Warray-bounds-19.c: New test. + 2016-03-29 Zachary T Welch <zwelch@codesourcery.com> * lib/prune.exp (escape_regex_chars): New. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-19.c b/gcc/testsuite/gcc.dg/Warray-bounds-19.c new file mode 100644 index 0000000..e2f9661 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-19.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/59124 */ +/* { dg-options "-O3 -Warray-bounds" } */ + +unsigned baz[6]; + +void foo(unsigned *bar, unsigned n) +{ + unsigned i, j; + + if (n > 6) + n = 6; + + for (i = 1; i < n; i++) + for (j = i - 1; j > 0; j--) + bar[j - 1] = baz[j - 1]; +} + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b5654c5..bbdf9ce 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5310,6 +5310,27 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, if (is_gimple_assign (def_stmt)) rhs_code = gimple_assign_rhs_code (def_stmt); + /* In the case of NAME != CST1 where NAME = A +- CST2 we can + assert that A != CST1 -+ CST2. */ + if ((comp_code == EQ_EXPR || comp_code == NE_EXPR) + && (rhs_code == PLUS_EXPR || rhs_code == MINUS_EXPR)) + { + tree op0 = gimple_assign_rhs1 (def_stmt); + tree op1 = gimple_assign_rhs2 (def_stmt); + if (TREE_CODE (op0) == SSA_NAME + && TREE_CODE (op1) == INTEGER_CST + && live_on_edge (e, op0) + && !has_single_use (op0)) + { + enum tree_code reverse_op = (rhs_code == PLUS_EXPR + ? MINUS_EXPR : PLUS_EXPR); + op1 = int_const_binop (reverse_op, val, op1); + if (TREE_OVERFLOW (op1)) + op1 = drop_tree_overflow (op1); + register_new_assert_for (op0, op0, comp_code, op1, NULL, e, bsi); + } + } + /* Add asserts for NAME cmp CST and NAME being defined as NAME = (int) NAME2. */ if (!TYPE_UNSIGNED (TREE_TYPE (val)) |