This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/64191] [4.9/5 Regression] -march=native messes up dead code elimination in loop calling dtor
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 08 Dec 2014 14:22:34 +0000
- Subject: [Bug c++/64191] [4.9/5 Regression] -march=native messes up dead code elimination in loop calling dtor
- Auto-submitted: auto-generated
- References: <bug-64191-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64191
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> 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);
Or rather
/* Keep clobbers that we can keep live live. */
if (gimple_clobber_p (stmt))
{
ssa_op_iter iter;
use_operand_p use_p;
bool dead = true;
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_nop_p (def)
|| gimple_plf (def, STMT_NECESSARY))
{
dead = false;
break;
}
}
so we keep the indirect clobbers in destructors (with use of parameter
SSA default defs).