diff options
author | Richard Biener <rguenther@suse.de> | 2018-11-23 12:53:39 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-11-23 12:53:39 +0000 |
commit | f7b94dec4876c161d7e97ad0ce19695aa487b04a (patch) | |
tree | b0dcf998453b7e2fae018cf158d70450d7387d83 /gcc/tree-vect-slp.c | |
parent | ff03f2d18df99b3ca637b81c35e516bbf5454687 (diff) | |
download | gcc-f7b94dec4876c161d7e97ad0ce19695aa487b04a.zip gcc-f7b94dec4876c161d7e97ad0ce19695aa487b04a.tar.gz gcc-f7b94dec4876c161d7e97ad0ce19695aa487b04a.tar.bz2 |
re PR tree-optimization/88149 (ICE in vect_transform_stmt since r265959)
2018-11-23 Richard Biener <rguenther@suse.de>
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
Diffstat (limited to 'gcc/tree-vect-slp.c')
-rw-r--r-- | gcc/tree-vect-slp.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index f2bb8da..9e805d0 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<vect_def_type, 4> 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; } |