We can use TBAA even when we have a DR, do so.  For the testcase
that means fully vectorizing it instead of only vectorizing
the first store group resulting in suboptimal code.

Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1.

2021-04-09  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/99971
        * tree-vect-data-refs.c (vect_slp_analyze_node_dependences):
        Always use TBAA for loads.

        * g++.dg/vect/slp-pr99971.cc: New testcase.
---
 gcc/testsuite/g++.dg/vect/slp-pr99971.cc | 36 ++++++++++++++++++++++++
 gcc/tree-vect-data-refs.c                | 18 +++++++-----
 2 files changed, 47 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/vect/slp-pr99971.cc

diff --git a/gcc/testsuite/g++.dg/vect/slp-pr99971.cc 
b/gcc/testsuite/g++.dg/vect/slp-pr99971.cc
new file mode 100644
index 00000000000..bec6418d4e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/slp-pr99971.cc
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// { dg-require-effective-target vect_int }
+
+struct A
+{
+  unsigned int a, b, c, d;
+
+  A& operator+= (A const& that)
+    {
+      a += that.a;
+      b += that.b;
+      c += that.c;
+      d += that.d;
+      return *this;
+    }
+
+  A& operator-= (A const& that)
+    {
+      a -= that.a;
+      b -= that.b;
+      c -= that.c;
+      d -= that.d;
+      return *this;
+    }
+};
+
+void test(A& x, A const& y1, A const& y2)
+{
+  x += y1;
+  x -= y2;
+}
+
+// We want to SLP vectorize a single connected SLP subgraph with two instances
+// { dg-final { scan-tree-dump-not "removing SLP instance" "slp2" } }
+// { dg-final { scan-tree-dump-times "SLPing BB part" 1 "slp2" } }
+// { dg-final { scan-tree-dump-times "Vectorizing SLP" 2 "slp2" } }
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index ee266ba62a8..6ea5e3a3eda 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -780,16 +780,20 @@ vect_slp_analyze_node_dependences (vec_info *vinfo, 
slp_tree node,
                 stmt we have to resort to the alias oracle.  */
              stmt_vec_info stmt_info = vinfo->lookup_stmt (stmt);
              data_reference *dr_b = STMT_VINFO_DATA_REF (stmt_info);
-             if (!dr_b)
+
+             /* We are hoisting a load - this means we can use
+                TBAA for disambiguation.  */
+             if (!ref_initialized_p)
+               ao_ref_init (&ref, DR_REF (dr_a));
+             if (stmt_may_clobber_ref_p_1 (stmt, &ref, true))
                {
-                 /* We are hoisting a load - this means we can use
-                    TBAA for disambiguation.  */
-                 if (!ref_initialized_p)
-                   ao_ref_init (&ref, DR_REF (dr_a));
-                 if (stmt_may_clobber_ref_p_1 (stmt, &ref, true))
+                 if (!dr_b)
                    return false;
-                 continue;
+                 /* Resort to dependence checking below.  */
                }
+             else
+               /* No dependence.  */
+               continue;
 
              bool dependent = false;
              /* If we run into a store of this same instance (we've just
-- 
2.26.2

Reply via email to