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 72BEA38582B0 for ; Tue, 18 Jul 2023 10:21:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 72BEA38582B0 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 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 9B7AF1FDC4 for ; Tue, 18 Jul 2023 10:21:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689675668; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type; bh=Z5ThTkAzk+YonUZ4K2uqyZ4x1KhGSrYm/LOv9TDFdc0=; b=yTEMYie2dnSlbWFnstf8Nkq54zVh9BLvkV2kSB8xjb+mh96nFRLluLxWHHq9ggG7XctMCZ EtAl55QBR+PDjz4YTPhNge5LP/FSr1PZ24M/1LS6j6CV8Z2spnF8/o7af0F9gFQImmFyYj M3i9EZD9JmkDRMIgFH0GhBnlBDYmntE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689675668; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type; bh=Z5ThTkAzk+YonUZ4K2uqyZ4x1KhGSrYm/LOv9TDFdc0=; b=a6L3HKvvIEFffSYAEAGH+YA+R8bIWIXv93eJQafDPjjAOf7AEK5nPD5VAYlUZ7b35gULY1 9rPsWjIBdgpKhpAA== 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 8837D134B0 for ; Tue, 18 Jul 2023 10:21:08 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id f2kaIJRntmRwfwAAMHmgww (envelope-from ) for ; Tue, 18 Jul 2023 10:21:08 +0000 Date: Tue, 18 Jul 2023 12:21:08 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] middle-end/105715 - missed RTL if-conversion with COND_EXPR expansion MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Message-Id: <20230718102108.8837D134B0@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,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: When the COND_EXPR condition operand was split out to a separate stmt it became subject to CSE with other condition evaluations. This unfortunately leads to TER no longer applying and in turn RTL expansion of COND_EXPRs no longer seeing the condition and thus failing to try conditional move expansion. This can be seen with gcc.target/i386/pr45685.c when built with -march=cascadelake which then FAILs to produce the expected number of cmovs. It can also be seen when we create more COND_EXPRs early like for instruction selection of MIN/MAX operations that map to IEEE a > b ? a : b expression semantics. Bootstrapped and tested on x86_64-unknown-linux-gnu. I'll push this after confirming it fixes all the fallout of early MIN/MAX if conversion. PR middle-end/105715 * gimple-isel.cc (gimple_expand_vec_exprs): Merge into... (pass_gimple_isel::execute): ... this. Duplicate comparison defs of COND_EXPRs. --- gcc/gimple-isel.cc | 121 ++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index e5670645d76..8deb3719c35 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -336,11 +336,43 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi, -/* Iterate all gimple statements and try to expand - VEC_COND_EXPR assignments. */ +namespace { + +const pass_data pass_data_gimple_isel = +{ + GIMPLE_PASS, /* type */ + "isel", /* name */ + OPTGROUP_VEC, /* optinfo_flags */ + TV_NONE, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa, /* todo_flags_finish */ +}; -static unsigned int -gimple_expand_vec_exprs (struct function *fun) +class pass_gimple_isel : public gimple_opt_pass +{ +public: + pass_gimple_isel (gcc::context *ctxt) + : gimple_opt_pass (pass_data_gimple_isel, ctxt) + {} + + /* opt_pass methods: */ + bool gate (function *) final override + { + return true; + } + + unsigned int execute (function *fun) final override; +}; // class pass_gimple_isel + + +/* Iterate all gimple statements and perform pre RTL expansion + GIMPLE massaging to improve instruction selection. */ + +unsigned int +pass_gimple_isel::execute (struct function *fun) { gimple_stmt_iterator gsi; basic_block bb; @@ -352,6 +384,8 @@ gimple_expand_vec_exprs (struct function *fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { + /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function + calls mapping to supported optabs. */ gimple *g = gimple_expand_vec_cond_expr (fun, &gsi, &vec_cond_ssa_name_uses); if (g != NULL) @@ -361,14 +395,54 @@ gimple_expand_vec_exprs (struct function *fun) gsi_replace (&gsi, g, false); } + /* Recognize .VEC_SET and .VEC_EXTRACT patterns. */ cfg_changed |= gimple_expand_vec_set_extract_expr (fun, &gsi); - if (gsi_end_p (gsi)) break; + + gassign *stmt = dyn_cast (*gsi); + if (!stmt) + continue; + + tree_code code = gimple_assign_rhs_code (stmt); + tree lhs = gimple_assign_lhs (stmt); + if (TREE_CODE_CLASS (code) == tcc_comparison + && !has_single_use (lhs)) + { + /* Duplicate COND_EXPR condition defs when they are + comparisons so RTL expansion with the help of TER + can perform better if conversion. */ + imm_use_iterator imm_iter; + use_operand_p use_p; + auto_vec cond_exprs; + unsigned cnt = 0; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) + { + if (is_gimple_debug (USE_STMT (use_p))) + continue; + cnt++; + if (gimple_bb (USE_STMT (use_p)) == bb + && is_gimple_assign (USE_STMT (use_p)) + && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use + && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR) + cond_exprs.safe_push (as_a (USE_STMT (use_p))); + } + for (unsigned i = cond_exprs.length () == cnt ? 1 : 0; + i < cond_exprs.length (); ++i) + { + gassign *copy = as_a (gimple_copy (stmt)); + tree new_def = duplicate_ssa_name (lhs, copy); + gimple_assign_set_lhs (copy, new_def); + auto gsi2 = gsi_for_stmt (cond_exprs[i]); + gsi_insert_before (&gsi2, copy, GSI_SAME_STMT); + gimple_assign_set_rhs1 (cond_exprs[i], new_def); + update_stmt (cond_exprs[i]); + } + } } } - for (hash_map::iterator it = vec_cond_ssa_name_uses.begin (); + for (auto it = vec_cond_ssa_name_uses.begin (); it != vec_cond_ssa_name_uses.end (); ++it) bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION ((*it).first)); @@ -377,41 +451,6 @@ gimple_expand_vec_exprs (struct function *fun) return cfg_changed ? TODO_cleanup_cfg : 0; } -namespace { - -const pass_data pass_data_gimple_isel = -{ - GIMPLE_PASS, /* type */ - "isel", /* name */ - OPTGROUP_VEC, /* optinfo_flags */ - TV_NONE, /* tv_id */ - PROP_cfg, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_update_ssa, /* todo_flags_finish */ -}; - -class pass_gimple_isel : public gimple_opt_pass -{ -public: - pass_gimple_isel (gcc::context *ctxt) - : gimple_opt_pass (pass_data_gimple_isel, ctxt) - {} - - /* opt_pass methods: */ - bool gate (function *) final override - { - return true; - } - - unsigned int execute (function *fun) final override - { - return gimple_expand_vec_exprs (fun); - } - -}; // class pass_gimple_isel - } // anon namespace gimple_opt_pass * -- 2.35.3