diff options
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr95272.c | 18 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 8 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 15 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 4 |
4 files changed, 33 insertions, 12 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr95272.c b/gcc/testsuite/gcc.dg/vect/pr95272.c new file mode 100644 index 0000000..47698ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr95272.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +enum { a = 5, b }; +typedef struct { + int c[b]; +} d; +extern d e[]; +int f; +int g[6]; +void h() { + int i; + for (; f; f++) { + i = 0; + for (; i < b; i++) + if (e[f].c[i]) + g[i] = e[f].c[i]; + } +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4f94b4b..3c5c0ea 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6192,9 +6192,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo, { slp_for_stmt_info = slp_node_instance->root; /* And then there's reduction chain with a conversion ... */ - if (SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)[0] != stmt_info) + if (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) != stmt_info) slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; - gcc_assert (SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)[0] == stmt_info); + gcc_assert (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) == stmt_info); } slp_tree *slp_op = XALLOCAVEC (slp_tree, op_type); for (i = 0; i < op_type; i++) @@ -7952,6 +7952,10 @@ vectorizable_live_operation (loop_vec_info loop_vinfo, all involved stmts together. */ else if (slp_index != 0) return true; + else + /* For SLP reductions the meta-info is attached to + the representative. */ + stmt_info = SLP_TREE_REPRESENTATIVE (slp_node); } stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); gcc_assert (reduc_info->is_reduc_info); diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 5976e91..836defc 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -61,6 +61,7 @@ _slp_tree::_slp_tree () SLP_TREE_TWO_OPERATORS (this) = false; SLP_TREE_DEF_TYPE (this) = vect_uninitialized_def; SLP_TREE_VECTYPE (this) = NULL_TREE; + SLP_TREE_REPRESENTATIVE (this) = NULL; this->refcnt = 1; this->max_nunits = 1; } @@ -132,6 +133,7 @@ vect_create_new_slp_node (vec<stmt_vec_info> scalar_stmts, unsigned nops) SLP_TREE_SCALAR_STMTS (node) = scalar_stmts; SLP_TREE_CHILDREN (node).create (nops); SLP_TREE_DEF_TYPE (node) = vect_internal_def; + SLP_TREE_REPRESENTATIVE (node) = scalar_stmts[0]; unsigned i; stmt_vec_info stmt_info; @@ -1741,6 +1743,7 @@ slp_copy_subtree (slp_tree node, hash_map<slp_tree, slp_tree> &map) slp_tree copy = copy_ref; SLP_TREE_DEF_TYPE (copy) = SLP_TREE_DEF_TYPE (node); SLP_TREE_VECTYPE (copy) = SLP_TREE_VECTYPE (node); + SLP_TREE_REPRESENTATIVE (copy) = SLP_TREE_REPRESENTATIVE (node); copy->max_nunits = node->max_nunits; copy->refcnt = 0; if (SLP_TREE_SCALAR_STMTS (node).exists ()) @@ -1786,14 +1789,6 @@ vect_slp_rearrange_stmts (slp_tree node, unsigned int group_size, if (SLP_TREE_SCALAR_STMTS (node).exists ()) { gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ()); - /* ??? Computation nodes are isomorphic and need no rearrangement. - This is a quick hack to cover those where rearrangement breaks - semantics because only the first stmt is guaranteed to have the - correct operation code due to others being swapped or inverted. */ - stmt_vec_info first = SLP_TREE_SCALAR_STMTS (node)[0]; - if (is_gimple_assign (first->stmt) - && gimple_assign_rhs_code (first->stmt) == COND_EXPR) - return; vec<stmt_vec_info> tmp_stmts; tmp_stmts.create (group_size); tmp_stmts.quick_grow (group_size); @@ -2664,7 +2659,7 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node, slp_instance node_instance, stmt_vector_for_cost *cost_vec) { - stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); gcc_assert (STMT_SLP_TYPE (stmt_info) != loop_vect); /* Calculate the number of vector statements to be created for the @@ -4079,7 +4074,7 @@ vect_schedule_slp_instance (vec_info *vinfo, STMT_VINFO_DEF_TYPE (child_stmt_info) = SLP_TREE_DEF_TYPE (child); } - stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); /* VECTYPE is the type of the destination. */ tree vectype = STMT_VINFO_VECTYPE (stmt_info); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 2bde717..5a5648b 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -128,6 +128,9 @@ struct _slp_tree { vec<stmt_vec_info> stmts; /* A group of scalar operands to be vectorized together. */ vec<tree> ops; + /* The representative that should be used for analysis and + code generation. */ + stmt_vec_info representative; /* Load permutation relative to the stores, NULL if there is no permutation. */ @@ -193,6 +196,7 @@ public: #define SLP_TREE_TWO_OPERATORS(S) (S)->two_operators #define SLP_TREE_DEF_TYPE(S) (S)->def_type #define SLP_TREE_VECTYPE(S) (S)->vectype +#define SLP_TREE_REPRESENTATIVE(S) (S)->representative /* Key for map that records association between scalar conditions and corresponding loop mask, and |