diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-03-12 12:12:49 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-03-12 12:12:49 +0100 |
commit | 7b5c5139a96b384e2372b4bcd579a4f0b83201d2 (patch) | |
tree | 11c78b9836d0bb51eefa3cf90c77aa150a02f8bc /gcc/tree-vrp.c | |
parent | 3f5f659208192192b83af727ab2f0103c16c1c44 (diff) | |
download | gcc-7b5c5139a96b384e2372b4bcd579a4f0b83201d2.zip gcc-7b5c5139a96b384e2372b4bcd579a4f0b83201d2.tar.gz gcc-7b5c5139a96b384e2372b4bcd579a4f0b83201d2.tar.bz2 |
re PR tree-optimization/51721 (-Warray-bounds false positives and inconsistencies)
PR tree-optimization/51721
* tree-vrp.c (register_edge_assert_for_2): Add asserts for unsvar
if (int) unsvar cmp CST.
* gcc.dg/tree-ssa/vrp64.c: New test.
From-SVN: r185222
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index febe33f..5f89da9 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4462,8 +4462,6 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, } } - /* Similarly add asserts for NAME == CST and NAME being defined as - NAME = NAME2 >> CST2. */ if (TREE_CODE_CLASS (comp_code) == tcc_comparison && TREE_CODE (val) == INTEGER_CST) { @@ -4473,7 +4471,60 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, double_int mask = double_int_zero; unsigned int prec = TYPE_PRECISION (TREE_TYPE (val)); - /* Extract CST2 from the right shift. */ + /* Add asserts for NAME cmp CST and NAME being defined + as NAME = (int) NAME2. */ + if (!TYPE_UNSIGNED (TREE_TYPE (val)) + && (comp_code == LE_EXPR || comp_code == LT_EXPR + || comp_code == GT_EXPR || comp_code == GE_EXPR) + && gimple_assign_cast_p (def_stmt)) + { + name2 = gimple_assign_rhs1 (def_stmt); + if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)) + && INTEGRAL_TYPE_P (TREE_TYPE (name2)) + && TYPE_UNSIGNED (TREE_TYPE (name2)) + && prec == TYPE_PRECISION (TREE_TYPE (name2)) + && (comp_code == LE_EXPR || comp_code == GT_EXPR + || !tree_int_cst_equal (val, + TYPE_MIN_VALUE (TREE_TYPE (val)))) + && live_on_edge (e, name2) + && !has_single_use (name2)) + { + tree tmp, cst; + enum tree_code new_comp_code = comp_code; + + cst = fold_convert (TREE_TYPE (name2), + TYPE_MIN_VALUE (TREE_TYPE (val))); + /* Build an expression for the range test. */ + tmp = build2 (PLUS_EXPR, TREE_TYPE (name2), name2, cst); + cst = fold_build2 (PLUS_EXPR, TREE_TYPE (name2), cst, + fold_convert (TREE_TYPE (name2), val)); + if (comp_code == LT_EXPR || comp_code == GE_EXPR) + { + new_comp_code = comp_code == LT_EXPR ? LE_EXPR : GT_EXPR; + cst = fold_build2 (MINUS_EXPR, TREE_TYPE (name2), cst, + build_int_cst (TREE_TYPE (name2), 1)); + } + + if (dump_file) + { + fprintf (dump_file, "Adding assert for "); + print_generic_expr (dump_file, name2, 0); + fprintf (dump_file, " from "); + print_generic_expr (dump_file, tmp, 0); + fprintf (dump_file, "\n"); + } + + register_new_assert_for (name2, tmp, new_comp_code, cst, NULL, + e, bsi); + + retval = true; + } + } + + /* Add asserts for NAME cmp CST and NAME being defined as + NAME = NAME2 >> CST2. + + Extract CST2 from the right shift. */ if (is_gimple_assign (def_stmt) && gimple_assign_rhs_code (def_stmt) == RSHIFT_EXPR) { @@ -4491,7 +4542,6 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2); } } - if (val2 != NULL_TREE && TREE_CODE (val2) == INTEGER_CST && simple_cst_equal (fold_build2 (RSHIFT_EXPR, |