From f7b94dec4876c161d7e97ad0ce19695aa487b04a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 23 Nov 2018 12:53:39 +0000 Subject: [PATCH] re PR tree-optimization/88149 (ICE in vect_transform_stmt since r265959) 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: r266406 --- gcc/ChangeLog | 7 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/torture/pr88149.C | 63 ++++++++++++++++++++++++++ gcc/tree-vect-slp.c | 40 ++++++++++++---- 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr88149.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91469b190cc..7a2ee245c39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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. + 2018-23-11 Mihail Ionescu * config/arm/arm.c (arm_expand_compare_and_swap): Simplify and call diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 355221c3812..3652268e82d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-23 Richard Biener + + PR tree-optimization/88149 + * g++.dg/torture/pr88149.C: New testcase. + 2018-11-23 Jakub Jelinek PR tree-optimization/86614 diff --git a/gcc/testsuite/g++.dg/torture/pr88149.C b/gcc/testsuite/g++.dg/torture/pr88149.C new file mode 100644 index 00000000000..2700a091740 --- /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 f2bb8da9de2..9e805d07726 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2557,22 +2557,46 @@ vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node, visited, lvisited, cost_vec)) return false; + /* ??? 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 (SLP_TREE_SCALAR_STMTS (child)[0]); + /* 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 (SLP_TREE_SCALAR_STMTS (child)[0]) = SLP_TREE_DEF_TYPE (child); - bool res = vect_slp_analyze_node_operations_1 (vinfo, node, node_instance, - cost_vec); - /* Restore def-types. */ + + /* Check everything worked out. */ + bool res = true; FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) - STMT_VINFO_DEF_TYPE (SLP_TREE_SCALAR_STMTS (child)[0]) - = vect_internal_def; - if (! res) - return false; + { + if (STMT_VINFO_DEF_TYPE (SLP_TREE_SCALAR_STMTS (child)[0]) + != SLP_TREE_DEF_TYPE (child)) + res = false; + } + else if (STMT_VINFO_DEF_TYPE (SLP_TREE_SCALAR_STMTS (child)[0]) != 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"); - return true; + if (res) + res = vect_slp_analyze_node_operations_1 (vinfo, node, node_instance, + cost_vec); + + /* Restore def-types. */ + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + STMT_VINFO_DEF_TYPE (SLP_TREE_SCALAR_STMTS (child)[0]) = dt[j]; + + return res; } -- 2.30.2