diff mbox series

[v2] Add single-lane SLP support to .GOMP_SIMD_LANE vectorization

Message ID 20241005121655.44F9813736@imap1.dmz-prg2.suse.org
State New
Headers show
Series [v2] Add single-lane SLP support to .GOMP_SIMD_LANE vectorization | expand

Commit Message

Richard Biener Oct. 5, 2024, 12:16 p.m. UTC
The following adds basic support for single-lane SLP .GOMP_SIMD_LANE
vectorization, in particular it enables SLP discovery.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

	* tree-vect-slp.cc (no_arg_map): New.
	(vect_get_operand_map): Handle IFN_GOMP_SIMD_LANE.
	(vect_build_slp_tree_1): Likewise.
	* tree-vect-stmts.cc (vectorizable_call): Handle single-lane SLP
	for .GOMP_SIMD_LANE calls.
---
 gcc/tree-vect-slp.cc   | 11 +++++++++++
 gcc/tree-vect-stmts.cc | 26 ++++++++++++++++++++++++--
 2 files changed, 35 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 2274d0e428e..125e69cf0eb 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -507,6 +507,7 @@  static const int cond_expr_maps[3][5] = {
   { 4, -2, -1, 1, 2 },
   { 4, -1, -2, 2, 1 }
 };
+static const int no_arg_map[] = { 0 };
 static const int arg0_map[] = { 1, 0 };
 static const int arg1_map[] = { 1, 1 };
 static const int arg2_map[] = { 1, 2 };
@@ -587,6 +588,9 @@  vect_get_operand_map (const gimple *stmt, bool gather_scatter_p = false,
 	  case IFN_CTZ:
 	    return arg0_map;
 
+	  case IFN_GOMP_SIMD_LANE:
+	    return no_arg_map;
+
 	  default:
 	    break;
 	  }
@@ -1175,6 +1179,8 @@  vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
 	      ldst_p = true;
 	      rhs_code = CFN_MASK_STORE;
 	    }
+	  else if (cfn == CFN_GOMP_SIMD_LANE)
+	    ;
 	  else if ((cfn != CFN_LAST
 		    && cfn != CFN_MASK_CALL
 		    && internal_fn_p (cfn)
@@ -1273,6 +1279,11 @@  vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
 	      need_same_oprnds = true;
 	      first_op1 = gimple_call_arg (call_stmt, 1);
 	    }
+	  else if (rhs_code == CFN_GOMP_SIMD_LANE)
+	    {
+	      need_same_oprnds = true;
+	      first_op1 = gimple_call_arg (call_stmt, 1);
+	    }
 	}
       else
 	{
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 1ecf6532e54..6ce98b613e5 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -3392,7 +3392,7 @@  vectorizable_call (vec_info *vinfo,
   if (ifn == IFN_LAST && !fndecl)
     {
       if (cfn == CFN_GOMP_SIMD_LANE
-	  && !slp_node
+	  && (!slp_node || SLP_TREE_LANES (slp_node) == 1)
 	  && loop_vinfo
 	  && LOOP_VINFO_LOOP (loop_vinfo)->simduid
 	  && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
@@ -3538,8 +3538,30 @@  vectorizable_call (vec_info *vinfo,
 	  /* Build argument list for the vectorized call.  */
 	  if (slp_node)
 	    {
-	      vec<tree> vec_oprnds0;
+	      if (cfn == CFN_GOMP_SIMD_LANE)
+		{
+		  for (i = 0; i < SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++i)
+		    {
+		      /* ???  For multi-lane SLP we'd need to build
+			 { 0, 0, .., 1, 1, ... }.  */
+		      tree cst = build_index_vector (vectype_out,
+						     i * nunits_out, 1);
+		      tree new_var
+			  = vect_get_new_ssa_name (vectype_out, vect_simple_var,
+						   "cst_");
+		      gimple *init_stmt = gimple_build_assign (new_var, cst);
+		      vect_init_vector_1 (vinfo, stmt_info, init_stmt, NULL);
+		      new_temp = make_ssa_name (vec_dest);
+		      gimple *new_stmt
+			= gimple_build_assign (new_temp, new_var);
+		      vect_finish_stmt_generation (vinfo, stmt_info, new_stmt,
+						   gsi);
+		      slp_node->push_vec_def (new_stmt);
+		    }
+		  continue;
+		}
 
+	      vec<tree> vec_oprnds0;
 	      vect_get_slp_defs (vinfo, slp_node, &vec_defs);
 	      vec_oprnds0 = vec_defs[0];