From 22676c8f0f124684ef5bd081fed86d9b9e312f76 Mon Sep 17 00:00:00 2001 From: jakub Date: Mon, 12 Mar 2012 11:12:49 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185222 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++ gcc/testsuite/ChangeLog | 3 + gcc/testsuite/gcc.dg/tree-ssa/vrp64.c | 152 ++++++++++++++++++++++++++++++++++ gcc/tree-vrp.c | 58 ++++++++++++- 4 files changed, 215 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp64.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b35706a..a408ce7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-03-12 Jakub Jelinek + + PR tree-optimization/51721 + * tree-vrp.c (register_edge_assert_for_2): Add asserts for unsvar + if (int) unsvar cmp CST. + 2012-03-12 Richard Guenther * tree-sra.c (create_access_replacement): Only rename the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4721de4..29981ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2012-03-12 Jakub Jelinek + PR tree-optimization/51721 + * gcc.dg/tree-ssa/vrp64.c: New test. + PR tree-optimization/52533 * gcc.c-torture/compile/pr52533.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp64.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp64.c new file mode 100644 index 0000000..2ab328f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp64.c @@ -0,0 +1,152 @@ +/* PR tree-optimization/51721 */ +/* { dg-do link } */ +/* { dg-options "-O2" } */ + +extern void link_error (void); + +#define BITSM1 (sizeof (int) * __CHAR_BIT__ - 1) + +void +f1 (unsigned int s) +{ + if (s >> BITSM1 != 0) + { + if (s == 0 || s == 5 || s == __INT_MAX__) + link_error (); + } + else + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U) + link_error (); + } +} + +void +f2 (int s) +{ + if (s >> BITSM1 == 0) + { + if (s == -1 || s == -5 || s == -__INT_MAX__ - 1) + link_error (); + } + else + { + if (s == 0 || s == 5 || s == __INT_MAX__) + link_error (); + } +} + +void +f3 (unsigned int s) +{ + if ((s & (1U << BITSM1)) != 0) + { + if (s == 0 || s == 5 || s == __INT_MAX__) + link_error (); + } + else + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U) + link_error (); + } +} + +void +f4 (int s) +{ + if ((s & (1U << BITSM1)) == 0) + { + if (s == -1 || s == -5 || s == -__INT_MAX__ - 1) + link_error (); + } + else + { + if (s == 0 || s == 5 || s == __INT_MAX__) + link_error (); + } +} + +void +f5 (unsigned int s) +{ + if ((int) s < 0) + { + if (s == 0 || s == 5 || s == __INT_MAX__) + link_error (); + } + else + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U) + link_error (); + } +} + +void +f6 (unsigned int s) +{ + if ((int) s < 4) + { + if (s == 4 || s == 6 || s == __INT_MAX__) + link_error (); + } + else + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U + || s == 3 || s == 0) + link_error (); + } +} + +void +f7 (unsigned int s) +{ + if ((int) s <= -7) + { + if (s == -6U || s == -1U || s == 0 || s == 4 || s == 6 || s == __INT_MAX__) + link_error (); + } + else + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -9U + || s == -7U) + link_error (); + } +} + +void +f8 (unsigned int s) +{ + if ((int) s >= 4) + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U + || s == 3 || s == 0) + link_error (); + } + else + { + if (s == 4 || s == 6 || s == __INT_MAX__) + link_error (); + } +} + +void +f9 (unsigned int s) +{ + if ((int) s > -7) + { + if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -9U + || s == -7U) + link_error (); + } + else + { + if (s == -6U || s == -1U || s == 0 || s == 4 || s == 6 || s == __INT_MAX__) + link_error (); + } +} + +int +main () +{ + return 0; +} 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, -- 2.7.4