https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85757
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- Ontop of recent patches: diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 32a25b9eb1e..1b672ad204a 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -577,6 +577,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt, else defvar = gimple_vdef (temp); auto_vec<gimple *, 10> defs; + gimple *phi_def = NULL; FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar) { /* Limit stmt walking. */ @@ -600,7 +601,10 @@ dse_classify_store (ao_ref *ref, gimple *stmt, processing. */ if (!bitmap_bit_p (visited, SSA_NAME_VERSION (PHI_RESULT (use_stmt)))) - defs.safe_push (use_stmt); + { + defs.safe_push (use_stmt); + phi_def = use_stmt; + } } /* If the statement is a use the store is not dead. */ else if (ref_maybe_used_by_stmt_p (use_stmt, ref)) @@ -660,12 +671,25 @@ dse_classify_store (ao_ref *ref, gimple *stmt, /* Process defs and remove paths starting with a kill from further processing. */ for (unsigned i = 0; i < defs.length (); ++i) - if (stmt_kills_ref_p (defs[i], ref)) - { - if (by_clobber_p && !gimple_clobber_p (defs[i])) - *by_clobber_p = false; + { + gimple *def = defs[i]; + gimple *use_stmt; + use_operand_p use_p; + if (stmt_kills_ref_p (def, ref)) + { + if (by_clobber_p && !gimple_clobber_p (def)) + *by_clobber_p = false; + defs.unordered_remove (i); + } + /* In addition to kills we can remove defs whose only use + is another def in defs. That can only ever be PHIs of which + we track a single for simplicity reasons (we fail for multiple + PHIs anyways). */ + else if (gimple_code (def) != GIMPLE_PHI + && single_imm_use (gimple_vdef (def), &use_p, &use_stmt) + && use_stmt == phi_def) defs.unordered_remove (i); - } + } /* If all defs kill the ref we are done. */ if (defs.is_empty ())