[Bug middle-end/65233] [5 Regression] ICE (segfault) on arm-linux-gnueabihf and aarch64-linux-gnu

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Mar 4 13:25:00 GMT 2015


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

--- Comment #22 from Richard Biener <rguenth at gcc dot gnu.org> ---
The error is to do anything that possibly relies on an up-to-date SSA web when
need_ssa_update () is true.

In fact the polymorphic call code walks to the PHI which is already dead
(it's block is gone).  So while we don't ICE we certainly look at released
stuff still.  I remember we had name_registered_for_update_p guards in
tree-cfgcleaup.c code, like on the 4.5 branch in cleanup_control_expr_graph:

        case GIMPLE_COND:
          {
            tree lhs = gimple_cond_lhs (stmt);
            tree rhs = gimple_cond_rhs (stmt);
            /* For conditions try harder and lookup single-argument
               PHI nodes.  Only do so from the same basic-block though
               as other basic-blocks may be dead already.  */
            if (TREE_CODE (lhs) == SSA_NAME
                && !name_registered_for_update_p (lhs))
              {
                gimple def_stmt = SSA_NAME_DEF_STMT (lhs);

the issue with needing cfg-cleanup before update-ssa is unreachable blocks
don't play well with computing dominators which update-ssa needs.  But
we also obviously cannot fix SSA form in this case without removing unreachable
blocks first.  And if we do that, and then fixup SSA form that will still fail
because threading _did_ fail to update the PHI node in BB 13 - where's the
definition of SR33_23 supposed to be?  I see that it is later updated to
be SR.33_45.

It's also odd that it chose to duplicate bb 30 at all (to bb 48).  I see
no good reason to do that.

I think a better workaround for the bug is

Index: ipa-polymorphic-call.c
===================================================================
--- ipa-polymorphic-call.c      (revision 221149)
+++ ipa-polymorphic-call.c      (working copy)
@@ -81,6 +81,8 @@ along with GCC; see the file COPYING3.
 #include "data-streamer.h"
 #include "lto-streamer.h"
 #include "streamer-hooks.h"
+#include "tree-ssa-operands.h"
+#include "tree-into-ssa.h"

 /* Return true when TYPE contains an polymorphic type and thus is interesting
    for devirtualization machinery.  */
@@ -804,7 +806,7 @@ walk_ssa_copies (tree op, hash_set<tree>
   STRIP_NOPS (op);
   while (TREE_CODE (op) == SSA_NAME
         && !SSA_NAME_IS_DEFAULT_DEF (op)
-        && SSA_NAME_DEF_STMT (op)
+        && !name_registered_for_update_p (op) 
         && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
             || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
     {
@@ -835,10 +837,7 @@ walk_ssa_copies (tree op, hash_set<tree>
        {
          gimple phi = SSA_NAME_DEF_STMT (op);

-         if (gimple_phi_num_args (phi) > 2
-             /* We can be called while cleaning up the CFG and can
-                have empty PHIs about to be removed.  */
-             || gimple_phi_num_args (phi) == 0)
+         if (gimple_phi_num_args (phi) > 2)
            goto done;
          if (gimple_phi_num_args (phi) == 1)
            op = gimple_phi_arg_def (phi, 0);

I'm going to bootstrap & test this.

Still the block duplication during threading that happens looks odd to me.



More information about the Gcc-bugs mailing list