re PR tree-optimization/48172 (incorrect vectorization of loop in GCC 4.5.* with...
authorRichard Guenther <rguenther@suse.de>
Thu, 12 May 2011 12:14:45 +0000 (12:14 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 12 May 2011 12:14:45 +0000 (12:14 +0000)
2011-05-12  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/48172
* tree-vect-loop-manip.c (vect_vfa_segment_size): Do not exclude
the number of iterations from the segment size calculation.
(vect_create_cond_for_alias_checks): Adjust.

* gcc.dg/vect/pr48172.c: New testcase.

From-SVN: r173703

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr48172.c [new file with mode: 0644]
gcc/tree-vect-loop-manip.c

index 6f994adaedbe6fcb18ca2ffdc616170a5fc61be7..71cb451cf26900f628c8dca8a458f6ac9c13ad5e 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-12  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48172
+       * tree-vect-loop-manip.c (vect_vfa_segment_size): Do not exclude
+       the number of iterations from the segment size calculation.
+       (vect_create_cond_for_alias_checks): Adjust.
+
 2011-05-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/48967
index b0b337445adabf051da666b9806e38fa7348c841..f6b9ba047dd0500548960ceac91a9d0eb6293b12 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-12  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48172
+       * gcc.dg/vect/pr48172.c: New testcase.
+
 2011-05-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/48967
diff --git a/gcc/testsuite/gcc.dg/vect/pr48172.c b/gcc/testsuite/gcc.dg/vect/pr48172.c
new file mode 100644 (file)
index 0000000..892aeca
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+extern void *memset(void *s, int c, __SIZE_TYPE__ n);
+extern void abort (void);
+
+#define ASIZE 1028
+#define HALF (ASIZE/2)
+
+int main() {
+  unsigned int array[ASIZE];
+  int i;
+
+  memset(array, 0, sizeof(array));
+
+  /* initialize first half of the array */
+  for (i = 0; i < HALF; i++)
+    array[i] = i;
+
+  /* fill second half of array in by summing earlier elements of the array
+     gcc 4.5.1 and 4.5.2 incorrectly vectorize this loop!  aray[1025] is left
+     at 0 for ASIZE=1028 */
+  for (i = 0; i < HALF-1; i++)
+    array[HALF+i] = array[2*i] + array[2*i + 1];
+
+  /* see if we have any failures */
+  for (i = 0; i < HALF - 1; i++)
+    if (array[HALF+i] != array[2*i] + array[2*i + 1])
+      abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 28b75f1ecbbc218cf3f0d3503d9f5887e7da008f..d990e7f45f84bc0437408104ab3a83891d871e50 100644 (file)
@@ -2354,26 +2354,31 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
    Input:
      DR: The data reference.
      VECT_FACTOR: vectorization factor.
+     SCALAR_LOOP_NITERS: number of iterations.
 
    Return an expression whose value is the size of segment which will be
    accessed by DR.  */
 
 static tree
-vect_vfa_segment_size (struct data_reference *dr, tree vect_factor)
+vect_vfa_segment_size (struct data_reference *dr, int vect_factor,
+                      tree scalar_loop_niters)
 {
-  tree segment_length = fold_build2 (MULT_EXPR, integer_type_node,
-                                    DR_STEP (dr), vect_factor);
-
+  tree segment_length;
+  segment_length = size_binop (MULT_EXPR,
+                              fold_convert (sizetype, DR_STEP (dr)),
+                              size_int (vect_factor));
+  segment_length = size_binop (MULT_EXPR,
+                              segment_length,
+                              fold_convert (sizetype, scalar_loop_niters));
   if (vect_supportable_dr_alignment (dr, false)
         == dr_explicit_realign_optimized)
     {
       tree vector_size = TYPE_SIZE_UNIT
                          (STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr))));
 
-      segment_length = fold_build2 (PLUS_EXPR, integer_type_node,
-                                   segment_length, vector_size);
+      segment_length = size_binop (PLUS_EXPR, segment_length, vector_size);
     }
-  return fold_convert (sizetype, segment_length);
+  return segment_length;
 }
 
 
@@ -2407,8 +2412,8 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   VEC (ddr_p, heap) * may_alias_ddrs =
     LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
-  tree vect_factor =
-    build_int_cst (integer_type_node, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+  int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+  tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
 
   ddr_p ddr;
   unsigned int i;
@@ -2460,8 +2465,10 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
         vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
                                              NULL_TREE, loop);
 
-      segment_length_a = vect_vfa_segment_size (dr_a, vect_factor);
-      segment_length_b = vect_vfa_segment_size (dr_b, vect_factor);
+      segment_length_a = vect_vfa_segment_size (dr_a, vect_factor,
+                                               scalar_loop_iters);
+      segment_length_b = vect_vfa_segment_size (dr_b, vect_factor,
+                                               scalar_loop_iters);
 
       if (vect_print_dump_info (REPORT_DR_DETAILS))
        {