Fix PR54647

Submitted by Richard Guenther on Sept. 21, 2012, 11:03 a.m.

Details

Message ID alpine.LNX.2.00.1209211300160.4063@zhemvz.fhfr.qr
State New
Headers show

Commit Message

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 hide | download patch | download mbox

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;
+}