From patchwork Thu Dec 1 09:53:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 61305 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 662A53858D3C for ; Thu, 1 Dec 2022 09:54:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 662A53858D3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669888447; bh=j2bWBO3ZtPd9Oj5tj0iHMWtZu0lvXSIuJmjBGcIVZ9U=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=vmnr+M35QuYT8H+2zG2LOLXM6w6PH4Myi+tQwH75b/5KoXY5x/gW/9/6IKi9rsu4R w08Pz2DJj9IjnOPi8u1XFbnI3nPNl/f7bwkkgQOMnZokCpm1Ry70P1WffV9YFkCGMs n8WrLANBqaSRia9KNCnUesVSQZP9Aj6hVspFbGtI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id 5FFAA3858D32 for ; Thu, 1 Dec 2022 09:53:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5FFAA3858D32 Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (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-out1.suse.de (Postfix) with ESMTPS id 4901421AAE for ; Thu, 1 Dec 2022 09:53:35 +0000 (UTC) Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (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 imap1.suse-dmz.suse.de (Postfix) with ESMTPS id 355711320E for ; Thu, 1 Dec 2022 09:53:35 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap1.suse-dmz.suse.de with ESMTPSA id AqfSC595iGPhGQAAGKfGzw (envelope-from ) for ; Thu, 01 Dec 2022 09:53:35 +0000 Date: Thu, 1 Dec 2022 10:53:34 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/107937 - uninit predicate simplification fixup MIME-Version: 1.0 Message-Id: <20221201095335.355711320E@imap1.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 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" The following changes the predicate representation to record the value of a predicate with an empty set of AND predicates. That's necessary to properly represent the conservative fallback for the def vs use predicates. Since simplification now can result in such an empty set this distinction becomes important and we need to check for this as we otherwise ICE. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/107937 * gimple-predicate-analysis.h (predicate::is_true): New. (predicate::is_false): Likewise. (predicate::empty_val): Likewise. (uninit_analysis::uninit_analysis): Properly initialize def_preds. * gimple-predicate-analysis.cc (simplify_1b): Indicate whether the chain became empty. (predicate::simplify): Release emptied chain before removing it. (predicate::normalize): Replace temporary object with assertion. (uninit_analysis::is_use_guarded): Deal with predicates that simplify to true/false. * gcc.dg/pr107937.c: New testcase. --- gcc/gimple-predicate-analysis.cc | 24 +++++++++++++++++++----- gcc/gimple-predicate-analysis.h | 23 ++++++++++++++++++++--- gcc/testsuite/gcc.dg/pr107937.c | 24 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr107937.c diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc index ce2e1d10e43..afe01e7f4b8 100644 --- a/gcc/gimple-predicate-analysis.cc +++ b/gcc/gimple-predicate-analysis.cc @@ -1249,7 +1249,7 @@ simplify_1a (pred_chain &chain) } /* Implement rule 1b above. PREDS is the AND predicate to simplify - in place. Returns true if CHAIN simplifies to true. */ + in place. Returns true if CHAIN simplifies to true or false. */ static bool simplify_1b (pred_chain &chain) @@ -1290,6 +1290,8 @@ simplify_1b (pred_chain &chain) { chain.ordered_remove (j); chain.ordered_remove (i); + if (chain.is_empty ()) + return true; i--; break; } @@ -1503,6 +1505,7 @@ predicate::simplify (gimple *use_or_def, bool is_use) ::simplify_1a (m_preds[i]); if (::simplify_1b (m_preds[i])) { + m_preds[i].release (); m_preds.ordered_remove (i); i--; } @@ -1719,10 +1722,11 @@ predicate::normalize (const pred_chain &chain) while (!work_list.is_empty ()) { pred_info pi = work_list.pop (); - predicate pred; /* The predicate object is not modified here, only NORM_CHAIN and WORK_LIST are appended to. */ - pred.normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set); + unsigned oldlen = m_preds.length (); + normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set); + gcc_assert (m_preds.length () == oldlen); } m_preds.safe_push (norm_chain); @@ -1740,7 +1744,7 @@ predicate::normalize (gimple *use_or_def, bool is_use) dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n"); } - predicate norm_preds; + predicate norm_preds (empty_val ()); for (unsigned i = 0; i < m_preds.length (); i++) { if (m_preds[i].length () != 1) @@ -2076,6 +2080,8 @@ predicate::operator= (const predicate &rhs) if (this == &rhs) return *this; + m_cval = rhs.m_cval; + unsigned n = m_preds.length (); for (unsigned i = 0; i != n; ++i) m_preds[i].release (); @@ -2204,11 +2210,15 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb, /* Try to build the predicate expression under which the PHI flows into its use. This will be empty if the PHI is defined and used in the same bb. */ - predicate use_preds; + predicate use_preds (true); if (!init_use_preds (use_preds, def_bb, use_bb)) return false; use_preds.simplify (use_stmt, /*is_use=*/true); + if (use_preds.is_false ()) + return true; + if (use_preds.is_true ()) + return false; use_preds.normalize (use_stmt, /*is_use=*/true); /* Try to prune the dead incoming phi edges. */ @@ -2227,6 +2237,10 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb, return false; m_phi_def_preds.simplify (phi); + if (m_phi_def_preds.is_false ()) + return false; + if (m_phi_def_preds.is_true ()) + return true; m_phi_def_preds.normalize (phi); } diff --git a/gcc/gimple-predicate-analysis.h b/gcc/gimple-predicate-analysis.h index 972af5e0b2d..c4a7ed51967 100644 --- a/gcc/gimple-predicate-analysis.h +++ b/gcc/gimple-predicate-analysis.h @@ -45,7 +45,7 @@ class predicate { public: /* Construct with the specified EVAL object. */ - predicate () : m_preds (vNULL) { } + predicate (bool empty_val) : m_preds (vNULL), m_cval (empty_val) { } /* Copy. */ predicate (const predicate &rhs) : m_preds (vNULL) { *this = rhs; } @@ -60,6 +60,21 @@ class predicate return m_preds.is_empty (); } + bool is_true () const + { + return is_empty () && m_cval; + } + + bool is_false () const + { + return is_empty () && !m_cval; + } + + bool empty_val () const + { + return m_cval; + } + const pred_chain_union chain () const { return m_preds; @@ -92,8 +107,10 @@ private: bool simplify_3 (); bool simplify_4 (); - /* Representation of the predicate expression(s). */ + /* Representation of the predicate expression(s). The predicate is + m_cval || m_preds[0] || ... */ pred_chain_union m_preds; + bool m_cval; }; /* Represents a complex Boolean predicate expression. */ @@ -119,7 +136,7 @@ class uninit_analysis /* Construct with the specified EVAL object. */ uninit_analysis (func_t &eval) - : m_phi_def_preds (), m_eval (eval) { } + : m_phi_def_preds (false), m_eval (eval) { } /* Copy. */ uninit_analysis (const uninit_analysis &rhs) = delete; diff --git a/gcc/testsuite/gcc.dg/pr107937.c b/gcc/testsuite/gcc.dg/pr107937.c new file mode 100644 index 00000000000..524850bcfa5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107937.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized" } */ + +int _setjmp(int); +int regs, vm_debug_engine_vp_0, vm_debug_engine_vp_2; + +void +vm_dispatch_hook(); + + +void +vm_debug_engine() { + int fp; + void *jump_table = &&l_nop; +l_nop: + if (__builtin_expect(vm_debug_engine_vp_2, 0)) + vm_dispatch_hook(); + if (_setjmp(regs)) { + fp = fp; + vm_dispatch_hook(); + goto *jump_table; + } + vm_debug_engine_vp_0 = fp; +}