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

Reply via email to