This removes a check preventing vectorization of live results of vectorized comparisons. I tested it with AVX512 mask registers (inspecting assembly) and traditional vector masks.
Bootstrap & regtest running on x86_64-unknown-linux-gnu. One alternative to live stmt vectorization is forcing of a scalar epilouge btw, for the case where we generate such (but not necessarily enter it) this might be the overall cheaper way of dealing with live ops since it avoids some live registers across the loop nests. Richard. 2020-09-09 Richard Biener <rguent...@suse.de> * tree-vect-stmts.c (vectorizable_comparison): Allow STMT_VINFO_LIVE_P stmts. * gcc.dg/vect/vect-live-6.c: New testcase. --- gcc/testsuite/gcc.dg/vect/vect-live-6.c | 31 +++++++++++++++++++++++++ gcc/tree-vect-stmts.c | 8 ------- 2 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-live-6.c diff --git a/gcc/testsuite/gcc.dg/vect/vect-live-6.c b/gcc/testsuite/gcc.dg/vect/vect-live-6.c new file mode 100644 index 00000000000..c986c97650f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-live-6.c @@ -0,0 +1,31 @@ +#include "tree-vect.h" + +int a[1024]; +int b[1024]; + +_Bool +fn1 () +{ + _Bool tem; + for (int i = 0; i < 1024; ++i) + { + tem = !a[i]; + b[i] = tem; + } + return tem; +} + +int main() +{ + check_vect (); + for (int i = 0; i < 1024; ++i) + { + a[i] = i & 5; + __asm__ volatile ("" ::: "memory"); + } + if (fn1 () != !(1023 & 5) || b[2] != 1) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target vect_int } } } */ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index e069f874f72..191957c3543 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -10319,14 +10319,6 @@ vectorizable_comparison (vec_info *vinfo, if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def) return false; - if (loop_vinfo && STMT_VINFO_LIVE_P (stmt_info)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "value used after loop.\n"); - return false; - } - gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt); if (!stmt) return false; -- 2.26.2