The following fixes the remaining ICEs I see when testing all
languages (but ada and go).

The tree-cfg.c hunk highlights one change in the behavior
of fold_stmt, namely that it now follows SSA edges by default.
Maybe that's undesired?  On a related note, fold_stmt_inplace
preserves the actual statement object gsi_stmt points to,
but in reality callers use it to avoid creating new SSA names
thus would it be ok if fold_stmt_inplace made sure to
preserve the number of statements (and only change what
gsi points to) only?

Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.

Richard.

2014-08-16  Richard Biener  <rguent...@suse.de>

        * tree-cfg.c (no_follow_ssa_edges): New function.
        (replace_uses_by): Do not follow SSA edges when folding the
        stmt.
        * gimple-match-head.c (maybe_push_res_to_seq): Disallow
        stmts that mention SSA names occuring in abnormal PHIs.
        (gimple_simplify): Likewise.

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 213651)
+++ gcc/tree-cfg.c      (working copy)
@@ -1681,6 +1681,14 @@ gimple_can_merge_blocks_p (basic_block a
   return true;
 }
 
+/* ???  Maybe this should be a generic overload of fold_stmt.  */
+
+static tree
+no_follow_ssa_edges (tree)
+{
+  return NULL_TREE;
+}
+
 /* Replaces all uses of NAME by VAL.  */
 
 void
@@ -1737,7 +1745,16 @@ replace_uses_by (tree name, tree val)
                  recompute_tree_invariant_for_addr_expr (op);
              }
 
-         if (fold_stmt (&gsi))
+         /* If we have sth like
+              neighbor_29 = <name> + -1;
+              _33 = <name> + neighbor_29;
+            and end up visiting _33 first then folding will
+            simplify the stmt to _33 = <name>; and the new
+            immediate use will be inserted before the stmt
+            iterator marker and thus we fail to visit it
+            again, ICEing within the has_zero_uses assert.
+            Avoid that by never following SSA edges.  */
+         if (fold_stmt (&gsi, no_follow_ssa_edges))
            stmt = gsi_stmt (gsi);
 
          if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
Index: gcc/gimple-match-head.c
===================================================================
--- gcc/gimple-match-head.c     (revision 213651)
+++ gcc/gimple-match-head.c     (working copy)
@@ -305,6 +305,17 @@ maybe_push_res_to_seq (code_helper rcode
        return NULL_TREE;
       if (!res)
        res = make_ssa_name (type, NULL);
+      /* Play safe and do not allow abnormals to be mentioned in
+         newly created statements.  */
+      if ((TREE_CODE (ops[0]) == SSA_NAME
+          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+         || (ops[1]
+             && TREE_CODE (ops[1]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+         || (ops[2]
+             && TREE_CODE (ops[2]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+       return NULL_TREE;
       gimple new_stmt = gimple_build_assign_with_ops (rcode, res,
                                                      ops[0], ops[1], ops[2]);
       gimple_seq_add_stmt_without_update (seq, new_stmt);
@@ -321,6 +332,17 @@ maybe_push_res_to_seq (code_helper rcode
        res = make_ssa_name (type, NULL);
       unsigned nargs = type_num_arguments (TREE_TYPE (decl));
       gcc_assert (nargs <= 3);
+      /* Play safe and do not allow abnormals to be mentioned in
+         newly created statements.  */
+      if ((TREE_CODE (ops[0]) == SSA_NAME
+          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+         || (nargs >= 2
+             && TREE_CODE (ops[1]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+         || (nargs == 3
+             && TREE_CODE (ops[2]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+       return NULL_TREE;
       gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], 
ops[2]);
       gimple_call_set_lhs (new_stmt, res);
       gimple_seq_add_stmt_without_update (seq, new_stmt);
@@ -414,8 +436,8 @@ gimple_simplify (enum tree_code code, tr
 
 tree
 gimple_simplify (enum built_in_function fn, tree type,
-                          tree arg0,
-                          gimple_seq *seq, tree (*valueize)(tree))
+                tree arg0,
+                gimple_seq *seq, tree (*valueize)(tree))
 {
   if (constant_for_folding (arg0))
     {
@@ -683,6 +705,17 @@ gimple_simplify (gimple_stmt_iterator *g
   if (is_gimple_assign (stmt)
       && rcode.is_tree_code ())
     {
+      /* Play safe and do not allow abnormals to be mentioned in
+         newly created statements.  */
+      if ((TREE_CODE (ops[0]) == SSA_NAME
+          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+         || (ops[1]
+             && TREE_CODE (ops[1]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+         || (ops[2]
+             && TREE_CODE (ops[2]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+       return false;
       gimple_assign_set_rhs_with_ops_1 (gsi, rcode, ops[0], ops[1], ops[2]);
       update_stmt (gsi_stmt (*gsi));
     }

Reply via email to