diff options
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r-- | gcc/tree-vect-stmts.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 687f982..3b078da 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6246,15 +6246,45 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, that leaves unused vector loads around punt - we at least create very sub-optimal code in that case (and blow up memory, see PR65518). */ + bool force_peeling = false; if (first_stmt == stmt - && !GROUP_NEXT_ELEMENT (stmt_info) - && GROUP_SIZE (stmt_info) > TYPE_VECTOR_SUBPARTS (vectype)) + && !GROUP_NEXT_ELEMENT (stmt_info)) + { + if (GROUP_SIZE (stmt_info) > TYPE_VECTOR_SUBPARTS (vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "single-element interleaving not supported " + "for not adjacent vector loads\n"); + return false; + } + + /* Single-element interleaving requires peeling for gaps. */ + force_peeling = true; + } + + /* If there is a gap in the end of the group or the group size cannot + be made a multiple of the vector element count then we access excess + elements in the last iteration and thus need to peel that off. */ + if (loop_vinfo + && ! STMT_VINFO_STRIDED_P (stmt_info) + && (force_peeling + || GROUP_GAP (vinfo_for_stmt (first_stmt)) != 0 + || (!slp && vf % GROUP_SIZE (vinfo_for_stmt (first_stmt)) != 0))) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "single-element interleaving not supported " - "for not adjacent vector loads\n"); - return false; + "Data access with gaps requires scalar " + "epilogue loop\n"); + if (loop->inner) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Peeling for outer loop is not supported\n"); + return false; + } + + LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true; } if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) |