diff options
author | Ira Rosen <ira.rosen@linaro.org> | 2011-05-26 07:50:09 +0000 |
---|---|---|
committer | Ira Rosen <irar@gcc.gnu.org> | 2011-05-26 07:50:09 +0000 |
commit | 48df3fa66cf86d6da365a459aae689bb937128a3 (patch) | |
tree | bb4f5ec4b88af2d477845faf8d6148011a0f8df8 /gcc/tree-vect-data-refs.c | |
parent | 688571c7d50ec32bd99ee6acda4afc2d3f8ab247 (diff) | |
download | gcc-48df3fa66cf86d6da365a459aae689bb937128a3.zip gcc-48df3fa66cf86d6da365a459aae689bb937128a3.tar.gz gcc-48df3fa66cf86d6da365a459aae689bb937128a3.tar.bz2 |
re PR tree-optimization/49038 (-ftree-vectorise introduces reads past end of array)
PR tree-optimization/49038
* tree-vect-loop-manip.c (vect_generate_tmps_on_preheader):
Ensure at least one epilogue iteration if required by data
accesses with gaps.
* tree-vectorizer.h (struct _loop_vec_info): Add new field
to mark loops that require peeling for gaps.
* tree-vect-loop.c (new_loop_vec_info): Initialize new field.
(vect_get_known_peeling_cost): Take peeling for gaps into
account.
(vect_transform_loop): Generate epilogue if required by data
access with gaps.
* tree-vect-data-refs.c (vect_analyze_group_access): Mark the
loop as requiring an epilogue if there are gaps in the end of
the strided group.
From-SVN: r174265
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 8d3b253..ee05997 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2043,7 +2043,7 @@ vect_analyze_group_access (struct data_reference *dr) loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step); - HOST_WIDE_INT stride; + HOST_WIDE_INT stride, last_accessed_element = 1; bool slp_impossible = false; /* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the @@ -2072,6 +2072,16 @@ vect_analyze_group_access (struct data_reference *dr) fprintf (vect_dump, " step "); print_generic_expr (vect_dump, step, TDF_SLIM); } + + if (loop_vinfo) + { + LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true; + + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Data access with gaps requires scalar " + "epilogue loop"); + } + return true; } @@ -2137,6 +2147,7 @@ vect_analyze_group_access (struct data_reference *dr) next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next)); continue; } + prev = next; /* Check that all the accesses have the same STEP. */ @@ -2167,6 +2178,8 @@ vect_analyze_group_access (struct data_reference *dr) gaps += diff - 1; } + last_accessed_element += diff; + /* Store the gap from the previous member of the group. If there is no gap in the access, GROUP_GAP is always 1. */ GROUP_GAP (vinfo_for_stmt (next)) = diff; @@ -2245,6 +2258,15 @@ vect_analyze_group_access (struct data_reference *dr) VEC_safe_push (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo), stmt); } + + /* There is a gap in the end of the group. */ + if (stride - last_accessed_element > 0 && loop_vinfo) + { + LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true; + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Data access with gaps requires scalar " + "epilogue loop"); + } } return true; |