[Bug tree-optimization/68625] [6 Regression] Segmentation fault in useless_type_conversion_p

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Dec 1 13:09:00 GMT 2015


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68625

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the copyprop iteration figures out half of the function is unreachable
and thus registers a copy from a value defined in a region that is also
dead (but we figure that out only during substitution and folding via
a match.pd pattern looking at defs).  Then cfgcleanup comes along and
processes BBs in random order, removing the wrong unreachable region
(with the def we propagated) first and then another unreachable region
part where a basic-block merging opportunity then causes the propagated
but removed def being a source for propagating out a PHI ...

One fix is to _not_ do remove_edge_and_dominated_blocks in CFG cleanup
but only remove edges and remove unreachable blocks later (which causes
more work of course).  Or trying to paper over the issue by checking
for released SSA names (propagating them out anyway) or delaying SSA
name release via registering them for SSA update.

CFG cleanup ordering patch:

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c       (revision 231101)
+++ gcc/tree-cfgcleanup.c       (working copy)
@@ -67,7 +67,7 @@ remove_fallthru_edge (vec<edge, va_gc> *
        if (e->flags & EDGE_COMPLEX)
          e->flags &= ~EDGE_FALLTHRU;
        else
-         remove_edge_and_dominated_blocks (e);
+         remove_edge (e);
        return true;
       }
   return false;
@@ -134,7 +134,7 @@ cleanup_control_expr_graph (basic_block

              taken_edge->probability += e->probability;
              taken_edge->count += e->count;
-             remove_edge_and_dominated_blocks (e);
+             remove_edge (e);
              retval = true;
            }
          else
@@ -218,7 +218,7 @@ cleanup_control_flow_bb (basic_block bb)
       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
        {
          if (e->dest != target_block)
-           remove_edge_and_dominated_blocks (e);
+           remove_edge (e);
          else
            {
              /* Turn off the EDGE_ABNORMAL flag.  */
@@ -717,7 +717,13 @@ cleanup_tree_cfg_noloop (void)
       changed = false;
     }

-  changed |= cleanup_tree_cfg_1 ();
+  if (cleanup_tree_cfg_1 ())
+    {
+      changed = true;
+      delete_unreachable_blocks ();
+      free_dominance_info (CDI_DOMINATORS);
+      calculate_dominance_info (CDI_DOMINATORS);
+    }

   gcc_assert (dom_info_available_p (CDI_DOMINATORS));
   compact_blocks ();


"Hack" to detect the situation and not ICE (could also be applied to
may_propagate_copy)

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 231101)
+++ gcc/tree-cfg.c      (working copy)
@@ -1865,6 +1865,8 @@ gimple_merge_blocks (basic_block a, basi
       tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
       gimple *copy;
       bool may_replace_uses = (virtual_operand_p (def)
+                              || (TREE_CODE (use) == SSA_NAME
+                                  && SSA_NAME_IN_FREE_LIST (use))
                               || may_propagate_copy (def, use));

       /* In case we maintain loop closed ssa form, do not propagate arguments


More information about the Gcc-bugs mailing list