public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] middle-end/105715 - missed RTL if-conversion with COND_EXPR expansion
@ 2023-07-18 10:21 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2023-07-18 10:21 UTC (permalink / raw)
  To: gcc-patches

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 <gassign *> (*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<gassign *, 4> 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 <gassign *> (USE_STMT (use_p)));
+		}
+	      for (unsigned i = cond_exprs.length () == cnt ? 1 : 0;
+		   i < cond_exprs.length (); ++i)
+		{
+		  gassign *copy = as_a <gassign *> (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<tree, unsigned int>::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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-18 10:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-18 10:21 [PATCH] middle-end/105715 - missed RTL if-conversion with COND_EXPR expansion Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).