This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Look through widening type conversions for possible edge assertions
- From: Patrick Palka <patrick at parcs dot ath dot cx>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Patrick Palka <patrick at parcs dot ath dot cx>
- Date: Tue, 11 Nov 2014 07:10:31 -0500
- Subject: [PATCH] Look through widening type conversions for possible edge assertions
- Authentication-results: sourceware.org; auth=none
- References: <CA+C-WL-fbKDbNmMr0ah-72QQmYw7O_eY3uKpf5Z7UtMw8-7D4g at mail dot gmail dot com>
This patch is a replacement for the 2nd VRP refactoring patch. It
simply teaches VRP to look through widening type conversions when
finding suitable edge assertions, e.g.
bool p = x != y;
int q = (int) p;
if (q == 0) // new edge assert: p == 0 and therefore x == y
The new testcase requires that such an edge assertion be inserted.
Full bootstrap + regtest on x86_64-unknown-linux-gnu in progress. Does
the patch look OK for trunk if no new regressions?
2014-11-11 Patrick Palka <ppalka@gcc.gnu.org>
gcc/
* tree-vrp.c (register_edge_assert_for): Look through
widening type conversions for posible edge assertions.
gcc/testsuite/
* gcc.dg/vrp-1.c: New testcase.
---
gcc/testsuite/gcc.dg/vrp-1.c | 31 +++++++++++++++++++++++++++++++
gcc/tree-vrp.c | 22 ++++++++++++++++++++++
2 files changed, 53 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/vrp-1.c
diff --git a/gcc/testsuite/gcc.dg/vrp-1.c b/gcc/testsuite/gcc.dg/vrp-1.c
new file mode 100644
index 0000000..df5334e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vrp-1.c
@@ -0,0 +1,31 @@
+/* { dg-options "-O2" } */
+
+void runtime_error (void) __attribute__ ((noreturn));
+void compiletime_error (void) __attribute__ ((noreturn, error ("")));
+
+static void
+compiletime_check_equals_1 (int *x, int y)
+{
+ int __p = *x != y;
+ if (__builtin_constant_p (__p) && __p)
+ compiletime_error ();
+ if (__p)
+ runtime_error ();
+}
+
+static void
+compiletime_check_equals_2 (int *x, int y)
+{
+ int __p = *x != y;
+ if (__builtin_constant_p (__p) && __p)
+ compiletime_error (); /* { dg-error "call to" } */
+ if (__p)
+ runtime_error ();
+}
+
+void
+foo (int *x)
+{
+ compiletime_check_equals_1 (x, 5);
+ compiletime_check_equals_2 (x, 10);
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index f0a4382..979ab44 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5634,6 +5634,7 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
the value zero or one, then we may be able to assert values
for SSA_NAMEs which flow into COND. */
+
/* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
statement of NAME we can assert both operands of the BIT_AND_EXPR
have nonzero value. */
@@ -5673,6 +5674,27 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
}
}
+
+ /* In the case of NAME != 0 or NAME == 0, if NAME's defining statement
+ is a widening type conversion then we can assert that NAME's
+ RHS is accordingly nonzero or zero. */
+ if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
+ && integer_zerop (val))
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
+ if (is_gimple_assign (def_stmt))
+ {
+ enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
+ if (CONVERT_EXPR_CODE_P (def_code))
+ {
+ tree lhs = gimple_assign_lhs (def_stmt);
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TYPE_PRECISION (TREE_TYPE (lhs))
+ >= TYPE_PRECISION (TREE_TYPE (rhs)))
+ register_edge_assert_for_1 (rhs, comp_code, e, si);
+ }
+ }
+ }
}
--
2.2.0.rc1.16.g6066a7e