> >> PR 108007 is another manifestation where we rely on DCE to clean-up > >> after IPA-SRA and if the user explicitely switches DCE off, IPA-SRA > >> can leave behind statements which are fed uninitialized values and > >> trap, even though their results are themselves never used. > >> > >> I have already fixed this for unused parameters in callees, this bug > >> shows that almost the same thing can happen for removed returns, on > >> the side of callers. This means that the issue has to be fixed > >> elsewhere, in call redirection. This patch adds a function which > >> recursivewly looks for uses of operations fed specific SSA names and > >> removes them all. > >> > >> That would have been easy if it wasn't for debug statements during > >> tree-inline (from which call redirection is also invoked). Debug > >> statements are decoupled from the rest at this point and iterating > >> over uses of SSAs does not bring them up. During tree-inline they are > >> handled especially at the end, I assume in order to make sure that > >> relative ordering of UIDs are the same with and without debug info. > >> > >> This means that during tree-inline we need to make a hash of killed > >> SSAs, that we already have in copy_body_data, available to the > >> function making the purging. So the patch duly does also that, making > >> the interface slightly ugly. > >> > >> Bootstrapped and tested on x86_64-linux. OK for master? (I am not sure > >> the problem is grave enough to warrant backporting to release branches > >> but can do that as well if people think I should.) > >> > >> Thanks, > >> > >> Martin > >> > >> > >> gcc/ChangeLog: > >> > >> 2023-05-11 Martin Jambor <mjam...@suse.cz> > >> > >> PR ipa/108007 > >> * cgraph.h (cgraph_edge): Add a parameter to > >> redirect_call_stmt_to_callee. > >> * ipa-param-manipulation.h (ipa_param_adjustments): Added a > >> parameter to modify_call. > >> * cgraph.cc (cgraph_edge::redirect_call_stmt_to_callee): New > >> parameter killed_ssas, pass it to padjs->modify_call. > >> * ipa-param-manipulation.cc (purge_transitive_uses): New function. > >> (ipa_param_adjustments::modify_call): New parameter killed_ssas. > >> Instead of substitutin uses, invoke purge_transitive_uses. If > >> hash of killed SSAs has not been provided, create a temporary one > >> and release SSAs that have been added to it. > >> * tree-inline.cc (redirect_all_calls): Create > >> id->killed_new_ssa_names earlier, pass it to edge redirection, > >> adjust a comment. > >> (copy_body): Release SSAs in id->killed_new_ssa_names. > >> > >> gcc/testsuite/ChangeLog: > >> > >> 2023-05-11 Martin Jambor <mjam...@suse.cz> > >> > >> PR ipa/108007 > >> * gcc.dg/ipa/pr108007.c: New test. > >> --- > >> gcc/cgraph.cc | 10 +++- > >> gcc/cgraph.h | 9 ++- > >> gcc/ipa-param-manipulation.cc | 85 +++++++++++++++++++++-------- > >> gcc/ipa-param-manipulation.h | 3 +- > >> gcc/testsuite/gcc.dg/ipa/pr108007.c | 32 +++++++++++ > >> gcc/tree-inline.cc | 28 ++++++---- > >> 6 files changed, 129 insertions(+), 38 deletions(-) > >> create mode 100644 gcc/testsuite/gcc.dg/ipa/pr108007.c > >> > >> +/* Remove all statements that use NAME and transitively those that use the > >> + result of such statements. KILLED_SSAS contains the SSA_NAMEs that are > >> + already being or have been processed and new ones need to be added to > >> it. > >> + The funtction only has to process situations handled by > >> + ssa_name_only_returned_p in ipa-sra.cc with the exception that it can > >> assume > >> + it must never reach a use in a return statement. */ > >> + > >> +static void > >> +purge_transitive_uses (tree name, hash_set <tree> *killed_ssas) > >> +{ > >> + imm_use_iterator imm_iter; > >> + gimple *stmt; > >> + > >> + FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name) > >> + { > >> + if (gimple_debug_bind_p (stmt)) > >> + { > >> + /* When runing within tree-inline, we will never end up here but > >> + adding the SSAs to killed_ssas will do the trick in this case and > >> + the respective debug statements will get reset. */ > >> + > >> + gimple_debug_bind_reset_value (stmt); > >> + update_stmt (stmt); > >> + continue; > >> + } > >> + > >> + tree lhs = NULL_TREE; > >> + if (is_gimple_assign (stmt)) > >> + lhs = gimple_assign_lhs (stmt); > >> + else if (gimple_code (stmt) == GIMPLE_PHI) > >> + lhs = gimple_phi_result (stmt); > >> + gcc_assert (lhs > >> + && (TREE_CODE (lhs) == SSA_NAME) > >> + && !gimple_vdef (stmt)); > >> + > >> + if (!killed_ssas->contains (lhs)) > >> + { > >> + killed_ssas->add (lhs); > >> + purge_transitive_uses (lhs, killed_ssas);
SSA graph may be deep so this may cause stack overflow, so I think we should use worklist here (it is also easy to do). OK with that change. Honza