re PR tree-optimization/45764 (wrong code -O2 vs -O3 (problem in vectorizer???))
authorRichard Guenther <rguenther@suse.de>
Thu, 21 Oct 2010 11:10:41 +0000 (11:10 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 21 Oct 2010 11:10:41 +0000 (11:10 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr45764.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

index 8fc317f..c0b14a3 100644 (file)
@@ -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.
index 78d4bc1..8b12fca 100644 (file)
@@ -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 (file)
index 0000000..6d43b87
--- /dev/null
@@ -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;
+}
index 7182513..0828e22 100644 (file)
@@ -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)
     {