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