new file mode 100644
@@ -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];
+ }
+}
@@ -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);
@@ -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);
@@ -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