summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-18 12:57:17 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-18 12:57:17 +0000
commit8bbe6b756672ca7d0a6167311a49b670cf7c7c6b (patch)
treed2f83ada3798b32cb210ac1543a9fa62b2494525 /gcc/tree-vect-data-refs.c
parent1e9af25c012141fc8ba5c2723cb185686424791c (diff)
downloadgcc-8bbe6b756672ca7d0a6167311a49b670cf7c7c6b.tar.gz
2013-04-18 Richard Biener <rguenther@suse.de>
* tree-vect-data-refs.c (vect_analyze_group_access): Properly handle negative step. Remove redundant checks. (vect_create_data_ref_ptr): Avoid ICEs with non-constant steps. * tree-vect-stmts.c (vectorizable_load): Instead of asserting for negative step and grouped loads fail to vectorize. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198054 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 1fe5047c70b..9cbc5c72cf6 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2024,7 +2024,7 @@ vect_analyze_group_access (struct data_reference *dr)
/* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
size of the interleaving group (including gaps). */
- groupsize = dr_step / type_size;
+ groupsize = absu_hwi (dr_step) / type_size;
/* Not consecutive access is possible only if it is a part of interleaving. */
if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
@@ -2094,10 +2094,10 @@ vect_analyze_group_access (struct data_reference *dr)
gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
struct data_reference *data_ref = dr;
unsigned int count = 1;
- tree next_step;
tree prev_init = DR_INIT (data_ref);
gimple prev = stmt;
- HOST_WIDE_INT diff, count_in_bytes, gaps = 0;
+ HOST_WIDE_INT diff, gaps = 0;
+ unsigned HOST_WIDE_INT count_in_bytes;
while (next)
{
@@ -2126,18 +2126,11 @@ vect_analyze_group_access (struct data_reference *dr)
}
prev = next;
+ data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
- /* Check that all the accesses have the same STEP. */
- next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
- if (tree_int_cst_compare (step, next_step))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not consecutive access in interleaving");
- return false;
- }
+ /* All group members have the same STEP by construction. */
+ gcc_checking_assert (operand_equal_p (DR_STEP (data_ref), step, 0));
- data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
/* Check that the distance between two accesses is equal to the type
size. Otherwise, we have gaps. */
diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
@@ -2175,7 +2168,8 @@ vect_analyze_group_access (struct data_reference *dr)
/* Check that the size of the interleaving (including gaps) is not
greater than STEP. */
- if (dr_step && dr_step < count_in_bytes + gaps * type_size)
+ if (dr_step != 0
+ && absu_hwi (dr_step) < count_in_bytes + gaps * type_size)
{
if (dump_enabled_p ())
{
@@ -2188,7 +2182,8 @@ vect_analyze_group_access (struct data_reference *dr)
/* Check that the size of the interleaving is equal to STEP for stores,
i.e., that there are no gaps. */
- if (dr_step && dr_step != count_in_bytes)
+ if (dr_step != 0
+ && absu_hwi (dr_step) != count_in_bytes)
{
if (DR_IS_READ (dr))
{
@@ -2208,7 +2203,8 @@ vect_analyze_group_access (struct data_reference *dr)
}
/* Check that STEP is a multiple of type size. */
- if (dr_step && (dr_step % type_size) != 0)
+ if (dr_step != 0
+ && (dr_step % type_size) != 0)
{
if (dump_enabled_p ())
{
@@ -3520,7 +3516,6 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop,
tree aptr;
gimple_stmt_iterator incr_gsi;
bool insert_after;
- bool negative;
tree indx_before_incr, indx_after_incr;
gimple incr;
tree step;
@@ -3550,11 +3545,10 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop,
else
step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
- if (tree_int_cst_compare (step, size_zero_node) == 0)
+ if (integer_zerop (step))
*inv_p = true;
else
*inv_p = false;
- negative = tree_int_cst_compare (step, size_zero_node) < 0;
/* Create an expression for the first address accessed by this load
in LOOP. */
@@ -3693,18 +3687,18 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop,
else
{
/* The step of the aggregate pointer is the type size. */
- tree step = TYPE_SIZE_UNIT (aggr_type);
+ tree iv_step = TYPE_SIZE_UNIT (aggr_type);
/* One exception to the above is when the scalar step of the load in
LOOP is zero. In this case the step here is also zero. */
if (*inv_p)
- step = size_zero_node;
- else if (negative)
- step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step);
+ iv_step = size_zero_node;
+ else if (tree_int_cst_sgn (step) == -1)
+ iv_step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv_step), iv_step);
standard_iv_increment_position (loop, &incr_gsi, &insert_after);
create_iv (aggr_ptr_init,
- fold_convert (aggr_ptr_type, step),
+ fold_convert (aggr_ptr_type, iv_step),
aggr_ptr, loop, &incr_gsi, insert_after,
&indx_before_incr, &indx_after_incr);
incr = gsi_stmt (incr_gsi);