From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id F37463851163; Tue, 6 Sep 2022 11:41:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F37463851163 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662464489; bh=EkCuH1AgBRZvFQyVT75seROpjUtwUsdu/tMufgOEZI4=; h=From:To:Subject:Date:From; b=jjN6kjJR7jqgNQ2CiMSqf3cX6+/Rmj1SxCxatp511B2mjgH1y440c/zDxb6QzG+Ue HEB18wAVLg+6NLt8okKIGp3dI/nQZ4btBVVxDavLthVnqIo0bUxM/eTTPdFGeRtOgK 80eSOxpqk9lg89vTWowOtEtkA4QxBMWDoJckf3lM= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2497] Fix use predicate computation for uninit analysis X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 190c644c06369766aa2537851ddbf83b1231b65b X-Git-Newrev: 12f0783111067b68673284665a886cdd0c8f55c3 Message-Id: <20220906114128.F37463851163@sourceware.org> Date: Tue, 6 Sep 2022 11:41:28 +0000 (GMT) List-Id: https://gcc.gnu.org/g:12f0783111067b68673284665a886cdd0c8f55c3 commit r13-2497-g12f0783111067b68673284665a886cdd0c8f55c3 Author: Richard Biener Date: Tue Sep 6 11:56:04 2022 +0200 Fix use predicate computation for uninit analysis In uninit analysis we try to prove that a use is always properly guarded so it is never reached when the used value is not initialized. This fails to be conservative when during the computation of the use predicate components of the || .. || .. chain are dropped so we have to detect this case and fall back to the conservative computation. * gimple-predicate-analysis.cc (compute_control_dep_chain): Add output flag to indicate whether we possibly have dropped any chains. Return whether the info is complete from the wrapping overload. (uninit_analysis::init_use_preds): Adjust accordingly, with a workaround for PR106754. (uninit_analysis::init_from_phi_def): Properly guard the case where we complete an empty chain. Diff: --- gcc/gimple-predicate-analysis.cc | 54 +++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc index ef2906ebc51..ac34b7007a6 100644 --- a/gcc/gimple-predicate-analysis.cc +++ b/gcc/gimple-predicate-analysis.cc @@ -990,13 +990,16 @@ dfs_mark_dominating_region (edge exit, basic_block dom, int flag, *NUM_CALLS is the number of recursive calls to control unbounded recursion. Return true if the information is successfully computed, false if - there is no control dependence or not computed. */ + there is no control dependence or not computed. + *COMPLETE_P is set to false if we stopped walking due to limits. + In this case there might be missing chains. */ static bool compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, vec cd_chains[], unsigned *num_chains, vec &cur_cd_chain, unsigned *num_calls, - unsigned in_region = 0, unsigned depth = 0) + unsigned in_region, unsigned depth, + bool *complete_p) { /* In our recursive calls this doesn't happen. */ if (single_succ_p (dom_bb)) @@ -1009,6 +1012,7 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, if (dump_file) fprintf (dump_file, "MAX_CHAIN_LEN exceeded: %u\n", cur_chain_len); + *complete_p = false; return false; } @@ -1077,6 +1081,7 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, if (dump_file) fprintf (dump_file, "param_uninit_control_dep_attempts " "exceeded: %u\n", *num_calls); + *complete_p = false; break; } ++*num_calls; @@ -1085,7 +1090,8 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, if (!single_succ_p (cd_bb) && compute_control_dep_chain (cd_bb, dep_bb, cd_chains, num_chains, cur_cd_chain, - num_calls, in_region, depth + 1)) + num_calls, in_region, depth + 1, + complete_p)) { found_cd_chain = true; break; @@ -1109,6 +1115,9 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, return found_cd_chain; } +/* Wrapper around the compute_control_dep_chain worker above. Returns + true when the collected set of chains in CD_CHAINS is complete. */ + static bool compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, vec cd_chains[], unsigned *num_chains, @@ -1117,8 +1126,11 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, auto_vec cur_cd_chain; unsigned num_calls = 0; unsigned depth = 0; - return compute_control_dep_chain (dom_bb, dep_bb, cd_chains, num_chains, - cur_cd_chain, &num_calls, in_region, depth); + bool complete_p = true; + compute_control_dep_chain (dom_bb, dep_bb, cd_chains, num_chains, + cur_cd_chain, &num_calls, in_region, depth, + &complete_p); + return complete_p; } /* Implemented simplifications: @@ -1888,6 +1900,10 @@ bool uninit_analysis::init_use_preds (predicate &use_preds, basic_block def_bb, basic_block use_bb) { + if (DEBUG_PREDICATE_ANALYZER && dump_file) + fprintf (dump_file, "init_use_preds (def_bb = %u, use_bb = %u)\n", + def_bb->index, use_bb->index); + gcc_assert (use_preds.is_empty () && dominated_by_p (CDI_DOMINATORS, use_bb, def_bb)); @@ -1919,17 +1935,20 @@ uninit_analysis::init_use_preds (predicate &use_preds, basic_block def_bb, unsigned num_chains = 0; auto_vec dep_chains[MAX_NUM_CHAINS]; - if (!compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains)) + if (!compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains) + /* ??? Workaround PR106754. */ + || num_chains == 0) { - gcc_assert (num_chains == 0); + /* If the info in dep_chains is not complete we need to use a + conservative approximation for the use predicate. */ + if (DEBUG_PREDICATE_ANALYZER && dump_file) + fprintf (dump_file, "init_use_preds: dep_chain incomplete, using " + "conservative approximation\n"); + num_chains = 1; + dep_chains[0].truncate (0); simple_control_dep_chain (dep_chains[0], cd_root, use_bb); - num_chains++; } - if (DEBUG_PREDICATE_ANALYZER && dump_file) - fprintf (dump_file, "init_use_preds (def_bb = %u, use_bb = %u)\n", - def_bb->index, use_bb->index); - /* From the set of edges computed above initialize *THIS as the OR condition under which the definition in DEF_BB is used in USE_BB. Each OR subexpression is represented by one element of DEP_CHAINS, @@ -2021,13 +2040,18 @@ uninit_analysis::init_from_phi_def (gphi *phi) { edge e = def_edges[i]; unsigned prev_nc = num_chains; - compute_control_dep_chain (cd_root, e->src, dep_chains, - &num_chains, in_region); + bool complete_p = compute_control_dep_chain (cd_root, e->src, dep_chains, + &num_chains, in_region); /* Update the newly added chains with the phi operand edge. */ if (EDGE_COUNT (e->src->succs) > 1) { - if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS) + if (complete_p + && prev_nc == num_chains + && num_chains < MAX_NUM_CHAINS) + /* We can only add a chain for the PHI operand edge when the + collected info was complete, otherwise the predicate may + not be conservative. */ dep_chains[num_chains++] = vNULL; for (unsigned j = prev_nc; j < num_chains; j++) dep_chains[j].safe_push (e);