https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96881
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- The CD-DCE issue is that we do not mark CLOBBERs as necessary but in the end choose to keep them, even if we elided its control dependences. The following fixes that in the simplest conservative way. This is really wrong-code. Testcase struct S { int s; ~S () {} } s; void __attribute__((noinline)) foo (int flag) { s.s = 1; if (!flag) // dependend on which path CDDCE preserves the CLOBBER gets elided anyway return; s.~S(); } int main () { foo (0); if (s.s != 1) __builtin_abort (); } diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index f1034878eaf..c78d7c6ccc7 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -1272,7 +1272,7 @@ maybe_optimize_arith_overflow (gimple_stmt_iterator *gsi, contributes nothing to the program, and can be deleted. */ static bool -eliminate_unnecessary_stmts (void) +eliminate_unnecessary_stmts (bool aggressive) { bool something_changed = false; basic_block bb; @@ -1366,7 +1366,9 @@ eliminate_unnecessary_stmts (void) break; } } - if (!dead) + if (!dead + && (!aggressive + || bitmap_bit_p (visited_control_parents, bb->index))) { bitmap_clear (debug_seen); continue; @@ -1876,7 +1878,7 @@ perform_tree_ssa_dce (bool aggressive) propagate_necessity (aggressive); BITMAP_FREE (visited); - something_changed |= eliminate_unnecessary_stmts (); + something_changed |= eliminate_unnecessary_stmts (aggressive); something_changed |= cfg_altered; /* We do not update postdominators, so free them unconditionally. */