Re: [PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
On Fri, Sep 13, 2013 at 8:06 PM, Cong Hou wrote: > A new test case is added to testsuite/gcc.dg/vect, which will fail > without this patch and pass with it. Bootstrap also get passed. No > additional test failure is introduced. > > The new test case includes a dot product on two arrays with short and > int types. The loop will still be vectorized (using punpcklwd on array > with short type), but should not be recognized as a dot-product > pattern. Ok if the patch bootstraps and passes regression tests. Thanks, Richard. > > thanks, > Cong > > > > > > Index: gcc/tree-vect-patterns.c > === > --- gcc/tree-vect-patterns.c (revision 202572) > +++ gcc/tree-vect-patterns.c (working copy) > @@ -397,7 +397,7 @@ vect_recog_dot_prod_pattern (vec >|| !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: gcc/ChangeLog > === > --- gcc/ChangeLog (revision 202572) > +++ gcc/ChangeLog (working copy) > @@ -1,3 +1,9 @@ > +2013-09-13 Cong Hou > + > + * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Fix a bug > + when checking the dot production pattern. The type of rhs operand > + of multiply is now checked correctly. > + > 2013-09-13 Jan Hubicka > > PR middle-end/58094 > Index: gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c > === > --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c (revision 0) > +++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c (revision 0) > @@ -0,0 +1,73 @@ > +/* { dg-require-effective-target vect_int } */ > + > +#include > +#include "tree-vect.h" > + > +#define N 64 > +#define DOT 43680 > + > +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); > +signed int Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); > + > +/* (short, int)->int->int dot product. > + Not detected as a dot-product pattern. */ > + > +__attribute__ ((noinline)) int > +foo (int len) > +{ > + int i; > + int result = 0; > + > + for (i = 0; i < len; i++) > +{ > + result += (X[i] * Y[i]); > +} > + return result; > +} > + > + > +/* (int, short)->int->int dot product. > + Not detected as a dot-product pattern. */ > + > +__attribute__ ((noinline)) int > +bar (int len) > +{ > + int i; > + int result = 0; > + > + for (i = 0; i < len; i++) > +{ > + result += (Y[i] * X[i]); > +} > + return result; > +} > + > +int > +main (void) > +{ > + int i; > + int dot; > + > + check_vect (); > + > + for (i = 0; i < N; i++) > +{ > + X[i] = i; > + Y[i] = N - i; > + __asm__ volatile (""); > +} > + > + dot = foo (N); > + if (dot != DOT) > +abort (); > + > + dot = bar (N); > + if (dot != DOT) > +abort (); > + > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { > target vect_unpack } } } */ > +/* { dg-final { cleanup-tree-dump "vect" } } */ > + > Index: gcc/testsuite/ChangeLog > === > --- gcc/testsuite/ChangeLog (revision 202572) > +++ gcc/testsuite/ChangeLog (working copy) > @@ -1,3 +1,9 @@ > +2013-09-13 Cong Hou > + > + * gcc.dg/vect/vect-reduc-dot-s16c.c: Add a test case with dot product > + on two arrays with short and int types. This should not be recognized > + as a dot product pattern. > + > 2013-09-13 Kai Tietz > > gcc.target/i386/pr57848.c: New file. > > > > > On Wed, Sep 11, 2013 at 6:55 PM, Xinliang David Li wrote: >> Can you add a test case to the regression suite? >> >> When the type of arguments are unsigned short/unsigned int, GCC does >> not vectorize the loop anymore -- this is worth a separate bug to >> track. punpcklwd instruction can be used to do zero extension of the >> short type. >> >> David >> >> On Wed, Sep 11, 2013 at 6:16 PM, Cong Hou wrote: >>> 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 >>> 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 reduc
Re: [PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
A new test case is added to testsuite/gcc.dg/vect, which will fail without this patch and pass with it. Bootstrap also get passed. No additional test failure is introduced. The new test case includes a dot product on two arrays with short and int types. The loop will still be vectorized (using punpcklwd on array with short type), but should not be recognized as a dot-product pattern. thanks, Cong Index: gcc/tree-vect-patterns.c === --- gcc/tree-vect-patterns.c (revision 202572) +++ gcc/tree-vect-patterns.c (working copy) @@ -397,7 +397,7 @@ vect_recog_dot_prod_pattern (vec || !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: gcc/ChangeLog === --- gcc/ChangeLog (revision 202572) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2013-09-13 Cong Hou + + * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Fix a bug + when checking the dot production pattern. The type of rhs operand + of multiply is now checked correctly. + 2013-09-13 Jan Hubicka PR middle-end/58094 Index: gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c === --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c (revision 0) +++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c (revision 0) @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +#define N 64 +#define DOT 43680 + +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed int Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* (short, int)->int->int dot product. + Not detected as a dot-product pattern. */ + +__attribute__ ((noinline)) int +foo (int len) +{ + int i; + int result = 0; + + for (i = 0; i < len; i++) +{ + result += (X[i] * Y[i]); +} + return result; +} + + +/* (int, short)->int->int dot product. + Not detected as a dot-product pattern. */ + +__attribute__ ((noinline)) int +bar (int len) +{ + int i; + int result = 0; + + for (i = 0; i < len; i++) +{ + result += (Y[i] * X[i]); +} + return result; +} + +int +main (void) +{ + int i; + int dot; + + check_vect (); + + for (i = 0; i < N; i++) +{ + X[i] = i; + Y[i] = N - i; + __asm__ volatile (""); +} + + dot = foo (N); + if (dot != DOT) +abort (); + + dot = bar (N); + if (dot != DOT) +abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + Index: gcc/testsuite/ChangeLog === --- gcc/testsuite/ChangeLog (revision 202572) +++ gcc/testsuite/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2013-09-13 Cong Hou + + * gcc.dg/vect/vect-reduc-dot-s16c.c: Add a test case with dot product + on two arrays with short and int types. This should not be recognized + as a dot product pattern. + 2013-09-13 Kai Tietz gcc.target/i386/pr57848.c: New file. On Wed, Sep 11, 2013 at 6:55 PM, Xinliang David Li wrote: > Can you add a test case to the regression suite? > > When the type of arguments are unsigned short/unsigned int, GCC does > not vectorize the loop anymore -- this is worth a separate bug to > track. punpcklwd instruction can be used to do zero extension of the > short type. > > David > > On Wed, Sep 11, 2013 at 6:16 PM, Cong Hou wrote: >> 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 >> 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
Re: [PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
On Thu, Sep 12, 2013 at 3:16 AM, Cong Hou wrote: > 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 > 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; > } Bootstrapped and tested on ... ? Please add a testcase that fails at runtime without the patch and succeeds with it. Thanks, Richard. > > 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 >|| !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;
Re: [PATCH] [vectorizer] Fixing a bug in tree-vect-patterns.c in GCC vectorizer.
Can you add a test case to the regression suite? When the type of arguments are unsigned short/unsigned int, GCC does not vectorize the loop anymore -- this is worth a separate bug to track. punpcklwd instruction can be used to do zero extension of the short type. David On Wed, Sep 11, 2013 at 6:16 PM, Cong Hou wrote: > 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 > 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 >|| !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;
[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 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 || !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;