OSDN Git Service

PR tree-optimization/43430
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Sep 2010 12:40:24 +0000 (12:40 +0000)
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Sep 2010 12:40:24 +0000 (12:40 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163999 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr43430-2.c [new file with mode: 0644]
gcc/tree-vect-stmts.c

index ff56d4b..788fd02 100644 (file)
@@ -1,5 +1,11 @@
 2010-09-08  Michael Matz  <matz@suse.de>
 
+       PR tree-optimization/43430
+       * tree-vect-stmts.c (vectorizable_condition): Support multiple
+       copies for conditional statements if it's not part of a reduction.
+
+2010-09-08  Michael Matz  <matz@suse.de>
+
        PR tree-optimization/33244
        * tree-ssa-sink.c (statement_sink_location): Don't sink into
        empty loop latches.
index 7b40021..13a7cce 100644 (file)
@@ -1,5 +1,10 @@
 2010-09-08  Michael Matz  <matz@suse.de>
 
+       PR tree-optimization/43430
+       * gcc.dg/vect/pr43430-2.c: New test.
+       
+2010-09-08  Michael Matz  <matz@suse.de>
+
        PR tree-optimization/33244
        * gfortran.dg/vect/fast-math-vect-8.f90: New test.
 
diff --git a/gcc/testsuite/gcc.dg/vect/pr43430-2.c b/gcc/testsuite/gcc.dg/vect/pr43430-2.c
new file mode 100644 (file)
index 0000000..631dade
--- /dev/null
@@ -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" } } */
index 7b6e281..6d15bda 100644 (file)
@@ -4038,16 +4038,18 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
   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))
@@ -4134,29 +4136,68 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
   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;
 }