The following moves dealing with extern vector defs in internal
permute nodes to where it is more appropriate and also catches
the failing stmt-based dominance check from the testcase in PR128347.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Will
push when that succeeds.
Richard.
PR tree-optimization/128347
* tree-vect-slp.cc (vect_schedule_slp_node): Move extern
vector def fixup.
* g++.dg/vect/pr128347.cc: New testcase.
---
gcc/testsuite/g++.dg/vect/pr128347.cc | 38 +++++++++++++++++++++++++++
gcc/tree-vect-slp.cc | 19 +++++++-------
2 files changed, 47 insertions(+), 10 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/vect/pr128347.cc
diff --git a/gcc/testsuite/g++.dg/vect/pr128347.cc
b/gcc/testsuite/g++.dg/vect/pr128347.cc
new file mode 100644
index 00000000000..80f876f4ffa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr128347.cc
@@ -0,0 +1,38 @@
+// { dg-do compile }
+
+struct vector {
+ ~vector();
+};
+int expand_dx;
+template <int SIZE> struct Tuple {
+ template <typename IdxT> int &operator[](IdxT i) { return mm[i]; }
+ int mm[SIZE];
+};
+struct Vec3 : Tuple<3> {
+ void x();
+ void operator-=(Vec3 v1) {
+ mm[0] -= v1[0];
+ mm[1] -= v1[1];
+ }
+};
+struct BBox {
+ Vec3 extents() {
+ Vec3 __trans_tmp_2, result(mMax);
+ result -= mMin;
+ __trans_tmp_2 = result;
+ return __trans_tmp_2;
+ }
+ void expand() {
+ for (int i = 0; i < 3; ++i)
+ mMin[i] -= mMax[i] += expand_dx;
+ }
+ Vec3 mMin, mMax;
+};
+int size();
+void TestBody() {
+ vector points;
+ BBox region;
+ region.expand();
+ if (size())
+ region.extents().x();
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index ae73837a76d..87a235f28b1 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -12335,7 +12335,15 @@ vect_schedule_slp_node (vec_info *vinfo,
&& !SSA_NAME_IS_DEFAULT_DEF (vdef))
{
gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
- if (!last_stmt)
+ /* Ignore existing external vector defs so we insert
+ at region boundary. Those can leak to an
+ internal identity permute node. */
+ if (is_a <bb_vec_info> (vinfo)
+ && vinfo->bbs[0] != gimple_bb (vstmt)
+ && dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
+ gimple_bb (vstmt)))
+ ;
+ else if (!last_stmt)
last_stmt = vstmt;
else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
last_stmt = vstmt;
@@ -12396,15 +12404,6 @@ vect_schedule_slp_node (vec_info *vinfo,
}
}
- /* When we face existing vector defs that are external, make sure
- to insert at region boundary. */
- if (last_stmt
- && is_a <bb_vec_info> (vinfo)
- && vinfo->bbs[0] != gimple_bb (last_stmt)
- && dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
- gimple_bb (last_stmt)))
- last_stmt = NULL;
-
/* We split regions to vectorize at control altering stmts
with a definition so this can only be an external. */
gcc_checking_assert (!last_stmt
--
2.51.0