public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC, vectorizer] Allow single element vector types for vector reduction operations
@ 2017-08-28  8:22 Jon Beniston
  2017-08-28  8:29 ` Richard Biener
  2017-09-07 11:08 ` Bernd Schmidt
  0 siblings, 2 replies; 33+ messages in thread
From: Jon Beniston @ 2017-08-28  8:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther

[-- Attachment #1: Type: text/plain, Size: 2398 bytes --]

Hi,

I have an out-of-tree GCC port and it is struggling supporting
auto-vectorization on some dot product instructions.  For example, I have an
instruction that takes three operands which are all 32-bit general
registers. The second and third operands will be treated as V2HI then do dot
product, and then generate an SI result which is then added to the first
operand which is SI as well.

I do see there is dot product recognizer in tree-vect-patters.c, however, I
found the following testcase still can't be auto-vectorized on my port which
has implemented all necessary dot product standard patterns.  This testcase
can't be auto-vectorized on other targets that have similar V2HI dot product
instructions as well, for example ARC.

=== test.c ===
#define K 4
#define M 4
#define N 256
int in[N*K][M];
int out[K];
int coeff[N][M];
void
foo (void)
{
  int i, j, k;
  int sum;
  for (k = 0; k < K; k++)
    {
      sum = 0;
      for (j = 0; j < M; j++)
        for (i = 0; i < N; i++)
          sum += in[i+k][j] * coeff[i][j];
      out[k] = sum;
    }
}
===
  The reason that auto-vectorizer doesn't work seems to be that GCC doesn't
support single-element vector types in get_vectype_for_scalar_type_and_size.
tree-vect-stmts.c: get_vectype_for_scalar_type_and_size
  ...
  if (nunits <= 1)
    return NULL_TREE;

So, I am thinking this actually should be relaxed to support more cases.  At
least on vector reduction operations which normally will have scalar result
with wider types than the element type of input operands.

I have tried to make the auto-vectorizer work for my V2HI dot product case,
with the patch attached. Is this the correct approach?

Cheers,
Jon

gcc/
2017-08-27  Jon Beniston <jon@beniston.com>

        * tree-vectorizer.h (get_vectype_for_scalar_type): New optional
        parameter declaration.
        * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): Add new
        optional parameter "reduct_p".  Support single element vector types
        if it is true.
        (get_vectype_for_scalar_type): Add new parameter "reduct_p".
        * tree-vect-patterns.c (vect_pattern_recog_1): Pass new parameter
        "reduct_p".
        * tree-vect-loop.c (vect_determine_vectorization_factor): Likewise.
        (vect_model_reduction_cost): Likewise.
        (get_initial_def_for_induction): Likewise.
        (vect_create_epilog_for_reduction): Likewise.


[-- Attachment #2: fix-vec-reduct.patch --]
[-- Type: application/octet-stream, Size: 4690 bytes --]

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c
+++ gcc/tree-vect-loop.c
@@ -232,7 +232,7 @@
                   dump_printf (MSG_NOTE, "\n");
 		}
 
-	      vectype = get_vectype_for_scalar_type (scalar_type);
+	      vectype = get_vectype_for_scalar_type (scalar_type, true);
 	      if (!vectype)
 		{
 		  if (dump_enabled_p ())
@@ -465,7 +465,7 @@
 		  dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
                   dump_printf (MSG_NOTE, "\n");
 		}
-	      vectype = get_vectype_for_scalar_type (scalar_type);
+	      vectype = get_vectype_for_scalar_type (scalar_type, true);
 	      if (!vectype)
 		{
 		  if (dump_enabled_p ())
@@ -510,7 +510,7 @@
 		  dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
 		  dump_printf (MSG_NOTE, "\n");
 		}
-	      vf_vectype = get_vectype_for_scalar_type (scalar_type);
+	      vf_vectype = get_vectype_for_scalar_type (scalar_type, true);
 	    }
 	  if (!vf_vectype)
 	    {
@@ -3673,7 +3673,7 @@
 
   reduction_op = get_reduction_op (stmt, reduc_index);
 
-  vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
+  vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op), true);
   if (!vectype)
     {
       if (dump_enabled_p ())
@@ -4202,7 +4202,7 @@
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   tree scalar_type = TREE_TYPE (init_val);
-  tree vectype = get_vectype_for_scalar_type (scalar_type);
+  tree vectype = get_vectype_for_scalar_type (scalar_type, true);
   int nunits;
   enum tree_code code = gimple_assign_rhs_code (stmt);
   tree def_for_init;
@@ -4455,7 +4455,7 @@
 
   reduction_op = get_reduction_op (stmt, reduc_index);
 
-  vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
+  vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op), true);
   gcc_assert (vectype);
   mode = TYPE_MODE (vectype);
 
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c
+++ gcc/tree-vect-patterns.c
@@ -4176,12 +4176,22 @@
       type_in = get_vectype_for_scalar_type (type_in);
       if (!type_in)
 	return false;
+
+      tree type_out_backup = type_out;
       if (type_out)
 	type_out = get_vectype_for_scalar_type (type_out);
       else
 	type_out = type_in;
       if (!type_out)
-	return false;
+	{
+	  /* dot_prod is vector reduction operation that we want allow
+	     single element vector types.  */
+	  if (!strcmp (recog_func->name, "dot_prod"))
+	    type_out = get_vectype_for_scalar_type (type_out_backup, true);
+
+	  if (!type_out)
+	    return false;
+	}
       pattern_vectype = type_out;
 
       if (is_gimple_assign (pattern_stmt))
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c
+++ gcc/tree-vect-stmts.c
@@ -8985,7 +8985,8 @@
    by the target.  */
 
 static tree
-get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
+get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size,
+				      bool reduct_p = false)
 {
   tree orig_scalar_type = scalar_type;
   machine_mode inner_mode = TYPE_MODE (scalar_type);
@@ -9039,7 +9040,7 @@
   else
     simd_mode = mode_for_vector (inner_mode, size / nbytes);
   nunits = GET_MODE_SIZE (simd_mode) / nbytes;
-  if (nunits < 1) /* Support V1SI.  */
+  if (nunits < 1 || (nunits == 1 && !reduct_p))
     return NULL_TREE;
 
   vectype = build_vector_type (scalar_type, nunits);
@@ -9065,11 +9066,12 @@
    by the target.  */
 
 tree
-get_vectype_for_scalar_type (tree scalar_type)
+get_vectype_for_scalar_type (tree scalar_type, bool reduct_p)
 {
   tree vectype;
   vectype = get_vectype_for_scalar_type_and_size (scalar_type,
-						  current_vector_size);
+						  current_vector_size,
+						  reduct_p);
   if (vectype
       && current_vector_size == 0)
     current_vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h
+++ gcc/tree-vectorizer.h
@@ -1062,7 +1062,7 @@
 
 /* In tree-vect-stmts.c.  */
 extern unsigned int current_vector_size;
-extern tree get_vectype_for_scalar_type (tree);
+extern tree get_vectype_for_scalar_type (tree, bool = false);
 extern tree get_mask_type_for_scalar_type (tree);
 extern tree get_same_sized_vectype (tree, tree);
 extern bool vect_is_simple_use (tree, vec_info *, gimple **,

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2017-09-12 17:13 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-28  8:22 [RFC, vectorizer] Allow single element vector types for vector reduction operations Jon Beniston
2017-08-28  8:29 ` Richard Biener
2017-08-28  9:04   ` Jon Beniston
2017-08-28 11:41     ` Richard Biener
2017-08-30 11:13       ` Jon Beniston
2017-08-30 12:28         ` Richard Biener
2017-08-30 15:52           ` Jon Beniston
2017-08-30 16:32             ` Richard Biener
2017-08-30 20:42             ` Richard Sandiford
2017-09-02 21:58             ` Andreas Schwab
2017-09-04  8:58               ` Tamar Christina
2017-09-04  9:19                 ` Richard Biener
2017-09-04 14:28                   ` Tamar Christina
2017-09-04 16:48                     ` Andrew Pinski
2017-09-05  9:37                       ` Richard Biener
2017-09-05 10:24                         ` Tamar Christina
2017-09-05 10:41                           ` Richard Biener
2017-09-05 12:50                             ` Richard Biener
2017-09-05 13:06                               ` Tamar Christina
2017-09-05 13:12                                 ` Richard Biener
2017-09-05 14:00                                   ` Tamar Christina
2017-09-11 15:39                                   ` Vidya Praveen
2017-09-12  7:13                                     ` Richard Biener
2017-09-12  8:45                                       ` Tamar Christina
2017-09-12  9:03                                         ` Richard Biener
2017-09-12 10:50                                           ` Richard Biener
2017-09-12 16:26                                             ` Andreas Schwab
2017-09-12 16:36                                               ` Richard Biener
2017-09-12 17:13                                                 ` Tamar Christina
2017-09-04 15:04             ` Christophe Lyon
2017-09-07 11:08 ` Bernd Schmidt
2017-09-07 11:20   ` Jon Beniston
2017-09-07 14:42     ` 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).