aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-19.c17
-rw-r--r--gcc/tree-vrp.c21
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))