aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-slp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vect-slp.c')
-rw-r--r--gcc/tree-vect-slp.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 15e5f27..811d1b2 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2244,6 +2244,7 @@ vect_analyze_slp_instance (vec_info *vinfo,
SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
SLP_INSTANCE_LOADS (new_instance) = vNULL;
SLP_INSTANCE_ROOT_STMT (new_instance) = constructor ? stmt_info : NULL;
+ new_instance->reduc_phis = NULL;
vect_gather_slp_loads (new_instance, node);
if (dump_enabled_p ())
@@ -4565,6 +4566,25 @@ vect_schedule_slp (vec_info *vinfo)
stmt_vec_info store_info;
unsigned int j;
+ /* For reductions set the latch values of the vectorized PHIs. */
+ if (instance->reduc_phis
+ && STMT_VINFO_REDUC_TYPE (SLP_TREE_REPRESENTATIVE
+ (instance->reduc_phis)) != FOLD_LEFT_REDUCTION
+ && STMT_VINFO_REDUC_TYPE (SLP_TREE_REPRESENTATIVE
+ (instance->reduc_phis)) != EXTRACT_LAST_REDUCTION)
+ {
+ slp_tree slp_node = root;
+ slp_tree phi_node = instance->reduc_phis;
+ gphi *phi = as_a <gphi *> (SLP_TREE_SCALAR_STMTS (phi_node)[0]->stmt);
+ edge e = loop_latch_edge (gimple_bb (phi)->loop_father);
+ gcc_assert (SLP_TREE_VEC_STMTS (phi_node).length ()
+ == SLP_TREE_VEC_STMTS (slp_node).length ());
+ for (unsigned j = 0; j < SLP_TREE_VEC_STMTS (phi_node).length (); ++j)
+ add_phi_arg (as_a <gphi *> (SLP_TREE_VEC_STMTS (phi_node)[j]),
+ vect_get_slp_vect_def (slp_node, j),
+ e, gimple_phi_arg_location (phi, e->dest_idx));
+ }
+
/* Remove scalar call stmts. Do not do this for basic-block
vectorization as not all uses may be vectorized.
??? Why should this be necessary? DCE should be able to