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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
It also seems that DCE cannot remove the empty loop with the clobber, because
it's marked useful and thus its SSA requirements are marked useful (we
explicitely exclude the VDEF but _not_ the SSA uses on the LHS of
*ssa_2 = {} clobbers).  Even if we don't make that SSA use necessary we
still have made the clobber itself necessary and thus marked control dependent
edges necessary.

Thus IMHO we shouldn't make clobbers necessary at all but only keep those
live that we can keep live (all uses still live).  That makes cddce1
kill bar_dtor_loop:

void bar_dtor_loop(Bar*, unsigned int) (struct Bar * p, unsigned int n)
{
  struct Bar * e;

  <bb 2>:
  return;

}

but of course it probably will DCE all indirect clobbers on an address
that is otherwise unused.  Jakub - do you think this will be a problem?

Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c  (revision 218479)
+++ gcc/tree-ssa-dce.c  (working copy)
@@ -292,8 +292,7 @@ mark_stmt_if_obviously_necessary (gimple
       break;

     case GIMPLE_ASSIGN:
-      if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
-         && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt)))
+      if (gimple_clobber_p (stmt))
        return;
       break;

@@ -813,8 +812,9 @@ propagate_necessity (bool aggressive)
                }
            }

-         FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
-           mark_operand_necessary (use);
+         if (!gimple_clobber_p (stmt))
+           FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
+             mark_operand_necessary (use);

          use = gimple_vuse (stmt);
          if (!use)
@@ -1362,6 +1362,24 @@ eliminate_unnecessary_stmts (void)
          /* If GSI is not necessary then remove it.  */
          if (!gimple_plf (stmt, STMT_NECESSARY))
            {
+             /* Keep clobbers that we can keep live live.  */
+             if (gimple_clobber_p (stmt))
+               {
+                 ssa_op_iter iter;
+                 use_operand_p use_p;
+                 bool dead = false;
+                 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+                   {
+                     gimple def = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
+                     if (!gimple_plf (def, STMT_NECESSARY))
+                       {
+                         dead = true;
+                         break;
+                       }
+                   }
+                 if (!dead)
+                   continue;
+               }
              if (!is_gimple_debug (stmt))
                something_changed = true;
              remove_dead_stmt (&gsi, bb);

Reply via email to