This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.


Hi

There is a bug in the function vect_recog_dot_prod_pattern() in
tree-vect-patterns.c. This function checks if a loop is of dot
production pattern. Specifically, according to the comment of this
function:

/*
 Try to find the following pattern:

     type x_t, y_t;
     TYPE1 prod;
     TYPE2 sum = init;
   loop:
     sum_0 = phi <init, sum_1>
     S1  x_t = ...
     S2  y_t = ...
     S3  x_T = (TYPE1) x_t;
     S4  y_T = (TYPE1) y_t;
     S5  prod = x_T * y_T;
     [S6  prod = (TYPE2) prod;  #optional]
     S7  sum_1 = prod + sum_0;

   where 'TYPE1' is exactly double the size of type 'type', and
'TYPE2' is the same size of 'TYPE1' or bigger. This is a special case
of a reduction computation.
*/

This function should check if x_t and y_t have the same type (type)
which has the half size of TYPE1. The corresponding code is shown
below:

      oprnd0 = gimple_assign_rhs1 (stmt);
      oprnd1 = gimple_assign_rhs2 (stmt);
      if (!types_compatible_p (TREE_TYPE (oprnd0), prod_type) ||
!types_compatible_p (TREE_TYPE (oprnd1), prod_type))
        return NULL;
      if (!type_conversion_p (oprnd0, stmt, true, &half_type0,
&def_stmt, &promotion) || !promotion)
        return NULL;
      oprnd00 = gimple_assign_rhs1 (def_stmt);

/*======================V  see here! */
      if (!type_conversion_p (oprnd0, stmt, true, &half_type1,
&def_stmt, &promotion) || !promotion)
        return NULL;
      oprnd01 = gimple_assign_rhs1 (def_stmt);
      if (!types_compatible_p (half_type0, half_type1))
        return NULL;
      if (TYPE_PRECISION (prod_type) != TYPE_PRECISION (half_type0) * 2)
return NULL;

Here the function uses x_T (oprnd0) to check the type of y_t, which is
incorrect. The fix is simple: just replace it by oprnd1.

The failed test case for this bug is shown below:

int foo(short *a, int *b, int n) {
  int sum = 0;
  for (int i = 0; i < n; ++i)
    sum += a[i] * b[i];
  return sum;
}


thanks,
Cong


Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c (revision 200988)
+++ gcc/tree-vect-patterns.c (working copy)
@@ -397,7 +397,7 @@ vect_recog_dot_prod_pattern (vec<gimple>
           || !promotion)
         return NULL;
       oprnd00 = gimple_assign_rhs1 (def_stmt);
-      if (!type_conversion_p (oprnd0, stmt, true, &half_type1, &def_stmt,
+      if (!type_conversion_p (oprnd1, stmt, true, &half_type1, &def_stmt,
                                 &promotion)
           || !promotion)
         return NULL;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]