Patchwork Fix PR54647

login
register
mail settings
Submitter Richard Guenther
Date Sept. 21, 2012, 11:03 a.m.
Message ID <alpine.LNX.2.00.1209211300160.4063@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/185690/
State New
Headers show

Comments

Richard Guenther - Sept. 21, 2012, 11:03 a.m.
The introduction of vn_get_stmt_kind brought COND_EXPR and
VEC_COND_EXPR into the PRE machinery - both are not really suited
for SCCVN or PRE in NARY form as they contain an embedded
expression.

The following patch restores previous behavior.  Eventually
we could experiment with moving them to REFERENCE instead.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Btw, this also means they are presenting a VN barrier and do
not get simplified if the condition would simplify.

Richard.

2012-09-21  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/54647
	* tree-ssa-pre.c (compute_avail): Do not put COND_EXPR
	or VEC_COND_EXPR into EXP_GEN again.

	* g++.dg/torture/pr54647.C: New testcase.

Patch

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 191603)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -3981,9 +3838,18 @@  compute_avail (void)
 		  {
 		  case VN_NARY:
 		    {
+		      enum tree_code code = gimple_assign_rhs_code (stmt);
 		      vn_nary_op_t nary;
+
+		      /* COND_EXPR and VEC_COND_EXPR are awkward in
+			 that they contain an embedded complex expression.
+			 Don't even try to shove those through PRE.  */
+		      if (code == COND_EXPR
+			  || code == VEC_COND_EXPR)
+			continue;
+
 		      vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
-						gimple_assign_rhs_code (stmt),
+						code,
 						gimple_expr_type (stmt),
 						gimple_assign_rhs1_ptr (stmt),
 						&nary);
Index: gcc/testsuite/g++.dg/torture/pr54647.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr54647.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr54647.C	(working copy)
@@ -0,0 +1,25 @@ 
+// { dg-do compile }
+
+class A
+{
+};
+template <class type> struct D:A
+{
+  type & operator[](int);
+};
+struct B
+{
+  typedef D <int *>Row;
+  struct C
+    {
+      Row *row;
+    };
+};
+B::C a;
+B::Row & b = *a.row;
+void
+fn1 ()
+{
+  while (1)
+    b[0] = b[0] ? (int *) -1 : 0;
+}