This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Look through widening type conversions for possible edge assertions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]