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