From f671f26a19dc2755864208ead756b14de2086c8e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Sep 2019 10:51:02 +0000 Subject: [PATCH] backport: re PR tree-optimization/88149 (ICE in vect_transform_stmt since r265959) 2019-09-04 Richard Biener Backport from mainline 2018-11-23 Richard Biener PR tree-optimization/88149 * tree-vect-slp.c (vect_slp_analyze_node_operations): Detect the case where there are two different def types for the same operand at different operand position in the same stmt. * g++.dg/torture/pr88149.C: New testcase. From-SVN: r275370 --- gcc/ChangeLog | 10 ++++ gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/g++.dg/torture/pr88149.C | 63 ++++++++++++++++++++++++++ gcc/tree-vect-slp.c | 34 +++++++++++++- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr88149.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 774808a66001..f666940c6076 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-04 Richard Biener + + Backport from mainline + 2018-11-23 Richard Biener + + PR tree-optimization/88149 + * tree-vect-slp.c (vect_slp_analyze_node_operations): Detect + the case where there are two different def types for the + same operand at different operand position in the same stmt. + 2019-09-04 Richard Biener Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 21443a52fe0e..1e848f2b3b57 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-09-04 Richard Biener + + Backport from mainline + 2018-11-23 Richard Biener + + PR tree-optimization/88149 + * g++.dg/torture/pr88149.C: New testcase. + 2019-09-04 Richard Biener Backport from mainline diff --git a/gcc/testsuite/g++.dg/torture/pr88149.C b/gcc/testsuite/g++.dg/torture/pr88149.C new file mode 100644 index 000000000000..2700a0917404 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr88149.C @@ -0,0 +1,63 @@ +// { dg-do compile } +// { dg-additional-options "-ftree-vectorize" } + +template struct a; +template struct a { + typedef long c; + typedef b &d; +}; +template class f { + e ab; + typedef a ac; + +public: + typename ac::d operator[](typename ac::c o) { return ab[o]; } +}; +template struct au; +template au operator+(au o, au p2) { + au ax = o; + ax += p2; + return ax; +} +template au operator-(au o, au p2) { + au ax = o; + ax -= p2; + return ax; +} +template au operator*(au, au &p2) { + au ax; + ax *= p2; + return ax; +} +template <> struct au { + double p() { return __real__ az; } + double q() { return __imag__ az; } + void operator+=(au o) { + az += o.p(); + __imag__ az += o.q(); + } + void operator-=(au o) { + az -= o.p(); + __imag__ az -= o.q(); + } + void operator*=(au &o) { + _Complex bd = o.p(); + __imag__ bd = o.q(); + az *= bd; + } + _Complex az; +}; +long bm, m; +f *> g; +au h, i, l; +void bn() { + au bq; + for (long k; m;) { + au br; + for (long j = 0; j < bm; ++j) { + au n = br * h; + i = l + n; + g[k] = l - bq; + } + } +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index e2f1c6c7096c..6ae43b932082 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2482,17 +2482,47 @@ vect_slp_analyze_node_operations (slp_tree node) gcc_assert (stmt_info); gcc_assert (STMT_SLP_TYPE (stmt_info) != loop_vect); + /* ??? We have to catch the case late where two first scalar stmts appear + in multiple SLP children with different def type and fail. Remember + original def types first since SLP_TREE_DEF_TYPE doesn't necessarily + match it when that is vect_internal_def. */ + auto_vec dt; + dt.safe_grow (SLP_TREE_CHILDREN (node).length ()); + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + dt[j] + = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])); + /* Push SLP node def-type to stmt operands. */ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])) = SLP_TREE_DEF_TYPE (child); - res = vect_analyze_stmt (stmt, &dummy, node); + + /* Check everything worked out. */ + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) + { + if (STMT_VINFO_DEF_TYPE + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])) + != SLP_TREE_DEF_TYPE (child)) + res = false; + } + else if (STMT_VINFO_DEF_TYPE + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])) != dt[j]) + res = false; + if (!res && dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: same operand with different " + "def type in stmt.\n"); + + if (res) + res = vect_analyze_stmt (stmt, &dummy, node); + /* Restore def-types. */ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])) - = vect_internal_def; + = dt[j]; if (! res) break; } -- 2.47.2