This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
- From: Cong Hou <congh at google dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: David Li <davidxl at google dot com>
- Date: Wed, 11 Sep 2013 18:16:53 -0700
- Subject: [PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
- Authentication-results: sourceware.org; auth=none
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;