From 85a846a29ab1ddab45ef5f8cc1640d27f0da5fc5 Mon Sep 17 00:00:00 2001 From: rguenth Date: Thu, 21 Oct 2010 11:10:41 +0000 Subject: 2010-10-21 Richard Guenther Michael Matz 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165768 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/torture/pr45764.c | 27 +++++++++++++++++++++++++++ gcc/tree-vect-data-refs.c | 20 ++++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr45764.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fc317f1e3d..c0b14a36e39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-10-21 Richard Guenther + Michael Matz + + 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. + 2010-10-21 Richard Guenther PR tree-optimization/46111 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 78d4bc1c6cd..8b12fcaec46 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-10-21 Richard Guenther + Michael Matz + + PR tree-optimization/45764 + * gcc.dg/torture/pr45764.c: New testcase. + 2010-10-21 Richard Guenther PR tree-optimization/46111 diff --git a/gcc/testsuite/gcc.dg/torture/pr45764.c b/gcc/testsuite/gcc.dg/torture/pr45764.c new file mode 100644 index 00000000000..6d43b872596 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr45764.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ + +int result[64][16]; + +int main() +{ + double dbuf[1000] = {0.0}; + int ibuf[900]; + int i, j; + + double d1 = 0.0; + double d2 = 0.0; + for (i = 0; i < 900; ++i) { + ibuf[i] = (int)(d2 - d1); + d1 += dbuf[i]; + d2 += dbuf[i + 64]; + } + + for (i = 0; i < 64; ++i) { + for (j = 0; j < 8; ++j) { + result[i][ j] = ibuf[64 - i + 64 * j]; + result[i][15 - j] = ibuf[ i + 64 * j]; + } + } + + return 0; +} 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) { -- cgit v1.2.1