From patchwork Wed Aug 31 14:25:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 57210 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9B54B3851142 for ; Wed, 31 Aug 2022 14:26:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B54B3851142 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661955995; bh=D8LqqcIp5viwCjqNk6GLP4kLbQc4NmmnoyvKmeTaDoU=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=FmW3IYz+TvxcvBKvyDOuh1RGrfSoTGpASnKWUbNjE0KM/66SitfVQWU/yH18CfPYd IN1Rh1GdsNno1LG+AfDbK1HKelgMW5S+OzPyomsNlRT1DkvIb4iCGiPfzTY2iulYFk QIhUKDJZJwWQf5AzAJOo20gb2zDaJQZZaKWHtURY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id DF1233858D39 for ; Wed, 31 Aug 2022 14:26:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DF1233858D39 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 9F01B1F893 for ; Wed, 31 Aug 2022 14:25:59 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8B6F61332D for ; Wed, 31 Aug 2022 14:25:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id PVTyIHdvD2OxUAAAMHmgww (envelope-from ) for ; Wed, 31 Aug 2022 14:25:59 +0000 Date: Wed, 31 Aug 2022 16:25:59 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] Avoid fatal fails in predicate::init_from_control_deps MIME-Version: 1.0 Message-Id: <20220831142559.8B6F61332D@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" When processing USE predicates we can drop from the AND chain, when procsssing DEF predicates we can drop from the OR chain. Do that instead of giving up completely. This also removes cases that should never trigger. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Assert the guard_bb isn't empty and has more than one successor. Drop appropriate parts of the predicate when an edge fails to register a predicate. (predicate::dump): Dump empty predicate as TRUE. --- gcc/gimple-predicate-analysis.cc | 119 ++++++++++++++----------------- 1 file changed, 55 insertions(+), 64 deletions(-) diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc index 58eade433dc..eb1e11cead8 100644 --- a/gcc/gimple-predicate-analysis.cc +++ b/gcc/gimple-predicate-analysis.cc @@ -1671,7 +1671,6 @@ predicate::init_from_control_deps (const vec *dep_chains, { gcc_assert (is_empty ()); - bool has_valid_pred = false; if (num_chains == 0) return; @@ -1689,27 +1688,16 @@ predicate::init_from_control_deps (const vec *dep_chains, of the predicates. */ const vec &path = dep_chains[i]; - has_valid_pred = false; + bool has_valid_pred = false; /* The chain of predicates guarding the definition along this path. */ pred_chain t_chain{ }; for (unsigned j = 0; j < path.length (); j++) { edge e = path[j]; basic_block guard_bb = e->src; - /* Ignore empty forwarder blocks. */ - if (empty_block_p (guard_bb) && single_succ_p (guard_bb)) - continue; - /* An empty basic block here is likely a PHI, and is not one - of the cases we handle below. */ - gimple_stmt_iterator gsi = gsi_last_bb (guard_bb); - if (gsi_end_p (gsi)) - { - has_valid_pred = false; - break; - } - /* Get the conditional controlling the bb exit edge. */ - gimple *cond_stmt = gsi_stmt (gsi); + gcc_assert (!empty_block_p (guard_bb) && !single_succ_p (guard_bb)); + /* Skip this edge if it is bypassing an abort - when the condition is not satisfied we are neither reaching the definition nor the use so it isn't meaningful. Note if @@ -1730,8 +1718,13 @@ predicate::init_from_control_deps (const vec *dep_chains, } } if (skip) - continue; + { + has_valid_pred = true; + continue; + } } + /* Get the conditional controlling the bb exit edge. */ + gimple *cond_stmt = last_stmt (guard_bb); if (gimple_code (cond_stmt) == GIMPLE_COND) { /* The true edge corresponds to the uninteresting condition. @@ -1757,37 +1750,29 @@ predicate::init_from_control_deps (const vec *dep_chains, } else if (gswitch *gs = dyn_cast (cond_stmt)) { - /* Avoid quadratic behavior. */ - if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES) - { - has_valid_pred = false; - break; - } - /* Find the case label. */ tree l = NULL_TREE; - unsigned idx; - for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx) - { - tree tl = gimple_switch_label (gs, idx); - if (e->dest == label_to_block (cfun, CASE_LABEL (tl))) - { - if (!l) - l = tl; - else - { - l = NULL_TREE; - break; - } - } - } + /* Find the case label, but avoid quadratic behavior. */ + if (gimple_switch_num_labels (gs) <= MAX_SWITCH_CASES) + for (unsigned idx = 0; + idx < gimple_switch_num_labels (gs); ++idx) + { + tree tl = gimple_switch_label (gs, idx); + if (e->dest == label_to_block (cfun, CASE_LABEL (tl))) + { + if (!l) + l = tl; + else + { + l = NULL_TREE; + break; + } + } + } /* If more than one label reaches this block or the case label doesn't have a contiguous range of values (like the default one) fail. */ if (!l || !CASE_LOW (l)) - { - has_valid_pred = false; - break; - } + has_valid_pred = false; else if (!CASE_HIGH (l) || operand_equal_p (CASE_LOW (l), CASE_HIGH (l))) { @@ -1824,31 +1809,37 @@ predicate::init_from_control_deps (const vec *dep_chains, both the USE (valid) and DEF (questionable) case. */ has_valid_pred = true; else - { - has_valid_pred = false; - break; - } + has_valid_pred = false; + + /* For USE predicates we can drop components of the + AND chain. */ + if (!has_valid_pred && !is_use) + break; } - if (!has_valid_pred) - break; - else - m_preds.quick_push (t_chain); - } + /* For DEF predicates we have to drop components of the OR chain + on failure. */ + if (!has_valid_pred && !is_use) + { + t_chain.release (); + continue; + } - if (has_valid_pred) - { - gcc_assert (m_preds.length () != 0); - if (DEBUG_PREDICATE_ANALYZER && dump_file) - dump (NULL, ""); - } - else - { - if (DEBUG_PREDICATE_ANALYZER && dump_file) - fprintf (dump_file, "\tFAILED\n"); - /* Clear M_PREDS to indicate failure. */ - m_preds.release (); + /* When we add || 1 simply prune the chain and return. */ + if (t_chain.is_empty ()) + { + t_chain.release (); + for (auto chain : m_preds) + chain.release (); + m_preds.truncate (0); + break; + } + + m_preds.quick_push (t_chain); } + + if (DEBUG_PREDICATE_ANALYZER && dump_file) + dump (NULL, ""); } /* Store a PRED in *THIS. */ @@ -1877,7 +1868,7 @@ predicate::dump (gimple *stmt, const char *msg) const unsigned np = m_preds.length (); if (np == 0) { - fprintf (dump_file, "\t(empty)\n"); + fprintf (dump_file, "\tTRUE (empty)\n"); return; }