On Wed, 2 Mar 2016, Jakub Jelinek wrote: > Hi! > > This patch fixes two issues: > 1) reverts part of https://gcc.gnu.org/ml/gcc-patches/2011-06/msg02183.html > changes, my understanding is that we don't emit or support what has been > mentioned as rationale for that, now that we can stick multiple pattern > stmts into a sequence; without this reversion, we mark both the pattern > and normal stmt relevant and then when vectorizing use in one spot > the pattern stmt and in another one the original stmt, while we clearly > want to use the pattern stmt always; also, without the reversion we > consider the original stmt as needed for VF computation and thus think > the loop needs QImode elements in addition to SImode and DImode. > 2) if the shift count is coming from stmt with corresponding pattern stmt, > we shouldn't look through it, because we might again refer to the middle > of a pattern stmt (this is similar to the recently committed patch); we > don't need to punt completely in that case though, the code can just > add a cast into the pattern sequence as it does in many other cases. > > Bootstrapped/regtested on {x86_64,i686,powerpc64,powerpc64le}-linux, > bootstrap/regtest is still pending on {s390,s390x,aarch64,armv7hl}-linux, > ok for trunk if it passes even there?
Ok. I've been trying to understand this code multiple times myself and I'm happy to see it go ;) Even though in all cases I remember the issue was elsewhere... Thanks, Richard. > 2016-03-02 Jakub Jelinek <ja...@redhat.com> > > PR target/70021 > * tree-vect-stmts.c (vect_mark_relevant): Remove USED_IN_PATTERN > argument, if STMT_VINFO_IN_PATTERN_P (stmt_info), always mark > the pattern no matter if it is used just by non-pattern, pattern > or mix thereof. > (process_use, vect_mark_stmts_to_be_vectorized): Adjust callers. > * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern): If > oprnd1 def_stmt is in pattern, don't look through it. > > * gcc.dg/vect/pr70021.c: New test. > * gcc.target/i386/pr70021.c: New test. > > --- gcc/tree-vect-stmts.c.jj 2016-03-01 19:23:51.000000000 +0100 > +++ gcc/tree-vect-stmts.c 2016-03-02 15:40:53.777231771 +0100 > @@ -181,8 +181,7 @@ create_array_ref (tree type, tree ptr, s > > static void > vect_mark_relevant (vec<gimple *> *worklist, gimple *stmt, > - enum vect_relevant relevant, bool live_p, > - bool used_in_pattern) > + enum vect_relevant relevant, bool live_p) > { > stmt_vec_info stmt_info = vinfo_for_stmt (stmt); > enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info); > @@ -202,62 +201,22 @@ vect_mark_relevant (vec<gimple *> *workl > stmt itself should be marked. */ > if (STMT_VINFO_IN_PATTERN_P (stmt_info)) > { > - bool found = false; > - if (!used_in_pattern) > - { > - imm_use_iterator imm_iter; > - use_operand_p use_p; > - gimple *use_stmt; > - tree lhs; > - loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); > - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); > - > - if (is_gimple_assign (stmt)) > - lhs = gimple_assign_lhs (stmt); > - else > - lhs = gimple_call_lhs (stmt); > - > - /* This use is out of pattern use, if LHS has other uses that are > - pattern uses, we should mark the stmt itself, and not the > pattern > - stmt. */ > - if (lhs && TREE_CODE (lhs) == SSA_NAME) > - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) > - { > - if (is_gimple_debug (USE_STMT (use_p))) > - continue; > - use_stmt = USE_STMT (use_p); > - > - if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) > - continue; > - > - if (vinfo_for_stmt (use_stmt) > - && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) > - { > - found = true; > - break; > - } > - } > - } > + /* This is the last stmt in a sequence that was detected as a > + pattern that can potentially be vectorized. Don't mark the stmt > + as relevant/live because it's not going to be vectorized. > + Instead mark the pattern-stmt that replaces it. */ > > - if (!found) > - { > - /* This is the last stmt in a sequence that was detected as a > - pattern that can potentially be vectorized. Don't mark the stmt > - as relevant/live because it's not going to be vectorized. > - Instead mark the pattern-stmt that replaces it. */ > - > - pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); > - > - if (dump_enabled_p ()) > - dump_printf_loc (MSG_NOTE, vect_location, > - "last stmt in pattern. don't mark" > - " relevant/live.\n"); > - stmt_info = vinfo_for_stmt (pattern_stmt); > - gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); > - save_relevant = STMT_VINFO_RELEVANT (stmt_info); > - save_live_p = STMT_VINFO_LIVE_P (stmt_info); > - stmt = pattern_stmt; > - } > + pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); > + > + if (dump_enabled_p ()) > + dump_printf_loc (MSG_NOTE, vect_location, > + "last stmt in pattern. don't mark" > + " relevant/live.\n"); > + stmt_info = vinfo_for_stmt (pattern_stmt); > + gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); > + save_relevant = STMT_VINFO_RELEVANT (stmt_info); > + save_live_p = STMT_VINFO_LIVE_P (stmt_info); > + stmt = pattern_stmt; > } > > STMT_VINFO_LIVE_P (stmt_info) |= live_p; > @@ -572,8 +531,7 @@ process_use (gimple *stmt, tree use, loo > } > } > > - vect_mark_relevant (worklist, def_stmt, relevant, live_p, > - is_pattern_stmt_p (stmt_vinfo)); > + vect_mark_relevant (worklist, def_stmt, relevant, live_p); > return true; > } > > @@ -630,7 +588,7 @@ vect_mark_stmts_to_be_vectorized (loop_v > } > > if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p)) > - vect_mark_relevant (&worklist, phi, relevant, live_p, false); > + vect_mark_relevant (&worklist, phi, relevant, live_p); > } > for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) > { > @@ -642,7 +600,7 @@ vect_mark_stmts_to_be_vectorized (loop_v > } > > if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p)) > - vect_mark_relevant (&worklist, stmt, relevant, live_p, false); > + vect_mark_relevant (&worklist, stmt, relevant, live_p); > } > } > > --- gcc/tree-vect-patterns.c.jj 2016-03-02 14:07:55.242244657 +0100 > +++ gcc/tree-vect-patterns.c 2016-03-02 15:41:33.307698533 +0100 > @@ -2090,7 +2090,8 @@ vect_recog_vector_vector_shift_pattern ( > return NULL; > > tree def = NULL_TREE; > - if (gimple_assign_cast_p (def_stmt)) > + stmt_vec_info def_vinfo = vinfo_for_stmt (def_stmt); > + if (!STMT_VINFO_IN_PATTERN_P (def_vinfo) && gimple_assign_cast_p > (def_stmt)) > { > tree rhs1 = gimple_assign_rhs1 (def_stmt); > if (TYPE_MODE (TREE_TYPE (rhs1)) == TYPE_MODE (TREE_TYPE (oprnd0)) > --- gcc/testsuite/gcc.dg/vect/pr70021.c.jj 2016-03-02 15:41:33.308698520 > +0100 > +++ gcc/testsuite/gcc.dg/vect/pr70021.c 2016-03-02 15:41:33.308698520 > +0100 > @@ -0,0 +1,40 @@ > +/* PR target/70021 */ > +/* { dg-do run } */ > + > +#include "tree-vect.h" > + > +#define N 160 > +int a[N]; > +unsigned long long int b[N], c[N], d[N], e[N]; > + > +__attribute__((noinline, noclone)) void > +foo (void) > +{ > + int i; > + for (i = 0; i < N; i += 4) > + { > + unsigned long long int f = (_Bool) b[i]; > + unsigned long long int g = c[i] != d[i]; > + e[i] = g ^ (a[i] & (g << f)); > + } > +} > + > +int > +main () > +{ > + int i; > + check_vect (); > + for (i = 0; i < N; ++i) > + { > + a[i] = 1618000128; > + b[i] = 10919594786573202791ULL; > + c[i] = 2593730175074624973ULL; > + d[i] = 7447894520878803661ULL; > + e[i] = 14234165565810642243ULL; > + } > + foo (); > + for (i = 0; i < N; ++i) > + if (e[i] != ((i & 3) ? 14234165565810642243ULL : 1ULL)) > + __builtin_abort (); > + return 0; > +} > --- gcc/testsuite/gcc.target/i386/pr70021.c.jj 2016-03-02 > 15:41:33.308698520 +0100 > +++ gcc/testsuite/gcc.target/i386/pr70021.c 2016-03-02 15:43:17.798289031 > +0100 > @@ -0,0 +1,42 @@ > +/* PR target/70021 */ > +/* { dg-do run } */ > +/* { dg-require-effective-target avx2 } */ > +/* { dg-options "-O2 -ftree-vectorize -mavx2 -fdump-tree-vect-details" } */ > + > +#include "avx2-check.h" > + > +#define N 160 > +int a[N]; > +unsigned long long int b[N], c[N], d[N], e[N]; > + > +__attribute__((noinline, noclone)) void > +foo (void) > +{ > + int i; > + for (i = 0; i < N; i += 4) > + { > + unsigned long long int f = (_Bool) b[i]; > + unsigned long long int g = c[i] != d[i]; > + e[i] = g ^ (a[i] & (g << f)); > + } > +} > + > +void > +avx2_test () > +{ > + int i; > + for (i = 0; i < N; ++i) > + { > + a[i] = 1618000128; > + b[i] = 10919594786573202791ULL; > + c[i] = 2593730175074624973ULL; > + d[i] = 7447894520878803661ULL; > + e[i] = 14234165565810642243ULL; > + } > + foo (); > + for (i = 0; i < N; ++i) > + if (e[i] != ((i & 3) ? 14234165565810642243ULL : 1ULL)) > + __builtin_abort (); > +} > + > +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)