summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-12 11:12:49 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-12 11:12:49 +0000
commit22676c8f0f124684ef5bd081fed86d9b9e312f76 (patch)
tree11c78b9836d0bb51eefa3cf90c77aa150a02f8bc /gcc
parent7f23b9c077526d41c0f29fb9f0515d86dcefc400 (diff)
downloadgcc-22676c8f0f124684ef5bd081fed86d9b9e312f76.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp64.c152
-rw-r--r--gcc/tree-vrp.c58
4 files changed, 215 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b35706a8fac..a408ce7aef5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-12 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <rguenther@suse.de>
* tree-sra.c (create_access_replacement): Only rename the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4721de45ce1..29981edae1f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2012-03-12 Jakub Jelinek <jakub@redhat.com>
+ 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 00000000000..2ab328f1d8b
--- /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 febe33f93c0..5f89da9297a 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,