aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-stmts.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vect-stmts.cc')
-rw-r--r--gcc/tree-vect-stmts.cc66
1 files changed, 46 insertions, 20 deletions
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ea0b426..a8762ba 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -419,18 +419,21 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info, loop_vec_info loop_vinfo,
}
}
- /* Check if it's an induction and multiple exits. In this case there will be
- a usage later on after peeling which is needed for the alternate exit. */
+ /* Check if it's a not live PHI and multiple exits. In this case
+ there will be a usage later on after peeling which is needed for the
+ alternate exit. */
if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
- && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+ && is_a <gphi *> (stmt)
+ && ((! VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
+ && ! *live_p)
+ || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def))
{
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vec_stmt_relevant_p: induction forced for "
- "early break.\n");
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vec_stmt_relevant_p: PHI forced live for "
+ "early break.\n");
LOOP_VINFO_EARLY_BREAKS_LIVE_IVS (loop_vinfo).safe_push (stmt_info);
*live_p = true;
-
}
if (*live_p && *relevant == vect_unused_in_scope
@@ -714,6 +717,8 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo, bool *fatal)
bb = bbs[i];
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ if (virtual_operand_p (gimple_phi_result (gsi_stmt (si))))
+ continue;
stmt_vec_info phi_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "init: phi relevant? %G",
@@ -8786,6 +8791,15 @@ vectorizable_store (vec_info *vinfo,
if (n == const_nunits)
{
int mis_align = dr_misalignment (first_dr_info, vectype);
+ /* With VF > 1 we advance the DR by step, if that is constant
+ and only aligned when performed VF times, DR alignment
+ analysis can analyze this as aligned since it assumes
+ contiguous accesses. But that is not how we code generate
+ here, so adjust for this. */
+ if (maybe_gt (vf, 1u)
+ && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr),
+ DR_TARGET_ALIGNMENT (first_dr_info)))
+ mis_align = -1;
dr_alignment_support dr_align
= vect_supportable_dr_alignment (vinfo, dr_info, vectype,
mis_align);
@@ -8807,6 +8821,10 @@ vectorizable_store (vec_info *vinfo,
ltype = build_vector_type (elem_type, n);
lvectype = vectype;
int mis_align = dr_misalignment (first_dr_info, ltype);
+ if (maybe_gt (vf, 1u)
+ && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr),
+ DR_TARGET_ALIGNMENT (first_dr_info)))
+ mis_align = -1;
dr_alignment_support dr_align
= vect_supportable_dr_alignment (vinfo, dr_info, ltype,
mis_align);
@@ -8867,17 +8885,10 @@ vectorizable_store (vec_info *vinfo,
}
}
unsigned align;
- /* ??? We'd want to use
- if (alignment_support_scheme == dr_aligned)
- align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
- since doing that is what we assume we can in the above checks.
- But this interferes with groups with gaps where for example
- VF == 2 makes the group in the unrolled loop aligned but the
- fact that we advance with step between the two subgroups
- makes the access to the second unaligned. See PR119586.
- We have to anticipate that here or adjust code generation to
- avoid the misaligned loads by means of permutations. */
- align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
+ if (alignment_support_scheme == dr_aligned)
+ align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
+ else
+ align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
/* Alignment is at most the access size if we do multiple stores. */
if (nstores > 1)
align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align);
@@ -10805,6 +10816,15 @@ vectorizable_load (vec_info *vinfo,
if (n == const_nunits)
{
int mis_align = dr_misalignment (first_dr_info, vectype);
+ /* With VF > 1 we advance the DR by step, if that is constant
+ and only aligned when performed VF times, DR alignment
+ analysis can analyze this as aligned since it assumes
+ contiguous accesses. But that is not how we code generate
+ here, so adjust for this. */
+ if (maybe_gt (vf, 1u)
+ && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr),
+ DR_TARGET_ALIGNMENT (first_dr_info)))
+ mis_align = -1;
dr_alignment_support dr_align
= vect_supportable_dr_alignment (vinfo, dr_info, vectype,
mis_align);
@@ -10833,6 +10853,10 @@ vectorizable_load (vec_info *vinfo,
if (VECTOR_TYPE_P (ptype))
{
mis_align = dr_misalignment (first_dr_info, ptype);
+ if (maybe_gt (vf, 1u)
+ && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr),
+ DR_TARGET_ALIGNMENT (first_dr_info)))
+ mis_align = -1;
dr_align
= vect_supportable_dr_alignment (vinfo, dr_info, ptype,
mis_align);
@@ -10852,8 +10876,10 @@ vectorizable_load (vec_info *vinfo,
}
}
unsigned align;
- /* ??? The above is still wrong, see vectorizable_store. */
- align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
+ if (alignment_support_scheme == dr_aligned)
+ align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
+ else
+ align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
/* Alignment is at most the access size if we do multiple loads. */
if (nloads > 1)
align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align);