diff options
author | Richard Guenther <rguenther@suse.de> | 2010-10-21 11:10:41 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-10-21 11:10:41 +0000 |
commit | 46241ea9d1ecf8a9b337bc6cbeb4f28421060f85 (patch) | |
tree | 07db227d6df5b3850d566a5d4679103b4ded669c /gcc/tree-vect-data-refs.c | |
parent | 82c1834a6f07c83204ef8c2c426355e433cbef29 (diff) | |
download | gcc-46241ea9d1ecf8a9b337bc6cbeb4f28421060f85.tar.gz |
re PR tree-optimization/45764 (wrong code -O2 vs -O3 (problem in vectorizer???))
2010-10-21 Richard Guenther <rguenther@suse.de>
Michael Matz <matz@suse.de>
PR tree-optimization/45764
* tree-vect-data-refs.c (vect_compute_data_ref_alignment):
Adjust initial misalignment for negative DR_STEP.
(vect_find_same_alignment_drs): Two DRs with different DR_STEP
do not have the same alignment over the whole iteration domain.
* gcc.dg/torture/pr45764.c: New testcase.
Co-Authored-By: Michael Matz <matz@suse.de>
From-SVN: r165768
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 71825137cd7..0828e22114a 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -900,6 +900,19 @@ vect_compute_data_ref_alignment (struct data_reference *dr) || (TREE_CODE (base) == VAR_DECL && DECL_ALIGN (base) >= TYPE_ALIGN (vectype))); + /* If this is a backward running DR then first access in the larger + vectype actually is N-1 elements before the address in the DR. + Adjust misalign accordingly. */ + if (tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0) + { + tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1); + /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type, + otherwise we wouldn't be here. */ + offset = fold_build2 (MULT_EXPR, ssizetype, offset, DR_STEP (dr)); + /* PLUS because DR_STEP was negative. */ + misalign = size_binop (PLUS_EXPR, misalign, offset); + } + /* Modulo alignment. */ misalign = size_binop (FLOOR_MOD_EXPR, misalign, alignment); @@ -1934,6 +1947,13 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr, if (DDR_NUM_DIST_VECTS (ddr) == 0) return; + /* Data-dependence analysis reports a distance vector of zero + for data-references that overlap only in the first iteration + but have different sign step (see PR45764). + So as a sanity check require equal DR_STEP. */ + if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0)) + return; + loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr)); FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v) { |