diff options
Diffstat (limited to 'gcc/tree-vect-slp.c')
-rw-r--r-- | gcc/tree-vect-slp.c | 20 |
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 |