summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr45764.c27
-rw-r--r--gcc/tree-vect-data-refs.c20
4 files changed, 62 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8fc317f1e3d..c0b14a36e39 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,13 @@
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.
+
+2010-10-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46111
* tree-parloops.c (take_address_of): Re-organize for MEM_REF.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 78d4bc1c6cd..8b12fcaec46 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,4 +1,10 @@
2010-10-21 Richard Guenther <rguenther@suse.de>
+ Michael Matz <matz@suse.de>
+
+ PR tree-optimization/45764
+ * gcc.dg/torture/pr45764.c: New testcase.
+
+2010-10-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46111
* g++.dg/torture/pr46111.C: New testcase.
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)
{