From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id E39D338582AE for ; Tue, 6 Sep 2022 11:41:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E39D338582AE Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id BF5E61F9E3 for ; Tue, 6 Sep 2022 11:41:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1662464467; h=from:from:reply-to:date:date:to:to:cc:mime-version:mime-version: content-type:content-type; bh=hZmjn0EHm7/ihvMmkHs+ezMgscG6jaWTf6nSSpikOaE=; b=Vq1yYLf1qK+0GlH7HARa0h6FwlI7PJiOEQpSoZODVm6BCTAuOpIKfT4n0GUts54q6xRX/x 38Eac73V6iejjcI4SNqcicS+AUXyfU6OsX8NmuqCYEG5elsbDBwWBfSf8JIuPsT4w97JAT +AD4o34RMJG0cfpd8VXb27t0m7MbF+I= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1662464467; h=from:from:reply-to:date:date:to:to:cc:mime-version:mime-version: content-type:content-type; bh=hZmjn0EHm7/ihvMmkHs+ezMgscG6jaWTf6nSSpikOaE=; b=XM0E8jwBuSbVex7WXi+csodo9jTIU6MUARkBFA5050VjCticwwNwbV9Ngbi4RGVNI9Vxao D1OG9cSYWQLLpfDg== Received: from wotan.suse.de (wotan.suse.de [10.160.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id BA7A62C141 for ; Tue, 6 Sep 2022 11:41:07 +0000 (UTC) Date: Tue, 6 Sep 2022 11:41:07 +0000 (UTC) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix use predicate computation for uninit analysis User-Agent: Alpine 2.22 (LSU 394 2020-01-19) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,MISSING_MID,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Message-ID: <20220906114107.hC9PEdB6EEVykd8lGXFMJsNTHQRAL9IbWAPXBuf67vU@z> 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. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. * 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. --- 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); -- 2.35.3