Fix PR43430: vectorize conditionals with multiple types

Michael Matz matz@suse.de
Tue Sep 7 13:35:00 GMT 2010


Hi,

for this testcase we need to emit multiple vectorized conditional 
statement per original statement (ncopies > 1).  This patch implements the 
support for that in case the conditional isn't part of a reduction (I'm 
didn't 100% follow the code under which conditions reduc_index is != 0 and 
what reduc_def then is, exactly).

Regstrapped on x86_64-linux, no regressions.  Okay?


Ciao,
Michael.
-- 
	PR tree-optimization/43430
	* tree-vect-stmts.c (vectorizable_condition): Support multiple
	copies for conditional statements if it's not part of a reduction.

testsuite/
	PR tree-optimization/43430
	* gcc.dg/vect/pr43430-2.c: New test.
	
Index: tree-vect-stmts.c
===================================================================
--- tree-vect-stmts.c	(revision 163773)
+++ tree-vect-stmts.c	(working copy)
@@ -4011,16 +4011,18 @@ vectorizable_condition (gimple stmt, gim
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   enum machine_mode vec_mode;
   tree def;
-  enum vect_def_type dt;
+  enum vect_def_type dt, dts[4];
   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
   int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
   enum tree_code code;
+  stmt_vec_info prev_stmt_info = NULL;
+  int j;
 
   /* FORNOW: unsupported in basic block SLP.  */
   gcc_assert (loop_vinfo);
 
   gcc_assert (ncopies >= 1);
-  if (ncopies > 1)
+  if (reduc_index && ncopies > 1)
     return false; /* FORNOW */
 
   if (!STMT_VINFO_RELEVANT_P (stmt_info))
@@ -4107,29 +4109,68 @@ vectorizable_condition (gimple stmt, gim
   vec_dest = vect_create_destination_var (scalar_dest, vectype);
 
   /* Handle cond expr.  */
-  vec_cond_lhs =
-    vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL);
-  vec_cond_rhs =
-    vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL);
-  if (reduc_index == 1)
-    vec_then_clause = reduc_def;
-  else
-    vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL);
-  if (reduc_index == 2)
-    vec_else_clause = reduc_def;
-  else
-    vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
-
-  /* Arguments are ready. Create the new vector stmt.  */
-  vec_compare = build2 (TREE_CODE (cond_expr), vectype,
-			vec_cond_lhs, vec_cond_rhs);
-  vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
-			  vec_compare, vec_then_clause, vec_else_clause);
-
-  *vec_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
-  new_temp = make_ssa_name (vec_dest, *vec_stmt);
-  gimple_assign_set_lhs (*vec_stmt, new_temp);
-  vect_finish_stmt_generation (stmt, *vec_stmt, gsi);
+  for (j = 0; j < ncopies; j++)
+    {
+      gimple new_stmt;
+      if (j == 0)
+	{
+	  gimple gtemp;
+	  vec_cond_lhs =
+	      vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
+					    stmt, NULL);
+	  vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
+			      NULL, &gtemp, &def, &dts[0]);
+	  vec_cond_rhs =
+	      vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
+					    stmt, NULL);
+	  vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
+			      NULL, &gtemp, &def, &dts[1]);
+	  if (reduc_index == 1)
+	    vec_then_clause = reduc_def;
+	  else
+	    {
+	      vec_then_clause = vect_get_vec_def_for_operand (then_clause,
+							      stmt, NULL);
+	      vect_is_simple_use (then_clause, loop_vinfo,
+				  NULL, &gtemp, &def, &dts[2]);
+	    }
+	  if (reduc_index == 2)
+	    vec_else_clause = reduc_def;
+	  else
+	    {
+	      vec_else_clause = vect_get_vec_def_for_operand (else_clause,
+							      stmt, NULL);
+	      vect_is_simple_use (else_clause, loop_vinfo,
+				  NULL, &gtemp, &def, &dts[3]);
+	    }
+	}
+      else
+	{
+	  vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs);
+	  vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs);
+	  vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2],
+							    vec_then_clause);
+	  vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3],
+							    vec_else_clause);
+	}
+
+      /* Arguments are ready. Create the new vector stmt.  */
+      vec_compare = build2 (TREE_CODE (cond_expr), vectype,
+			    vec_cond_lhs, vec_cond_rhs);
+      vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
+			      vec_compare, vec_then_clause, vec_else_clause);
+
+      new_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
+      new_temp = make_ssa_name (vec_dest, new_stmt);
+      gimple_assign_set_lhs (new_stmt, new_temp);
+      vect_finish_stmt_generation (stmt, new_stmt, gsi);
+      if (j == 0)
+        STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+      else
+        STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+      prev_stmt_info = vinfo_for_stmt (new_stmt);
+    }
 
   return true;
 }
Index: testsuite/gcc.dg/vect/pr43430-2.c
===================================================================
--- testsuite/gcc.dg/vect/pr43430-2.c	(revision 0)
+++ testsuite/gcc.dg/vect/pr43430-2.c	(revision 0)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -fno-vect-cost-model -fdump-tree-vect-details" } */
+typedef unsigned char uint8_t;
+vsad16_c (void *c, uint8_t * s1, uint8_t * s2, int stride, int h)
+{
+  int score = 0;
+  int x, y;
+  for (x = 0; x < 16; x++)
+    score += ((s1[x] - s1[x + stride] + s2[x + stride]) >= 0 ?
+              s1[x] + s2[x + stride] :
+              s2[x + stride]);
+  return score;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */



More information about the Gcc-patches mailing list