aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0275-2011-05-18-Richard-Guenther-rguenther-suse.de.patch
blob: b47545cc63237b1cc7ceb17e3767e2df0e8e1a2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From f7dad9af02c21ad7f0b6d01ffecc0b7d1a6b03ed Mon Sep 17 00:00:00 2001
From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 18 May 2011 13:24:05 +0000
Subject: [PATCH] 2011-05-18  Richard Guenther  <rguenther@suse.de>

        Backport from mainline
        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-13  Richard Guenther  <rguenther@suse.de>

        PR tree-optimization/48172
        * tree-vect-loop-manip.c (vect_vfa_segment_size): Avoid
        multiplying by number of iterations for equal step.
        (vect_create_cond_for_alias_checks): Likewise.

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


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173859 138bc75d-0d04-0410-961f-82ee72b054a4

index d3585ce..28581a0 100644
new file mode 100644
index 0000000..892aeca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr48172.c
@@ -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" } } */
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 28b75f1..b691cd2 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2353,27 +2353,27 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
 
    Input:
      DR: The data reference.
-     VECT_FACTOR: vectorization factor.
+     LENGTH_FACTOR: segment length to consider.
 
    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, tree length_factor)
 {
-  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)),
+			       fold_convert (sizetype, length_factor));
   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,12 +2407,12 @@ 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;
-  tree part_cond_expr;
+  tree part_cond_expr, length_factor;
 
   /* Create expression
      ((store_ptr_0 + store_segment_length_0) < load_ptr_0)
@@ -2460,8 +2460,12 @@ 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);
+      if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0))
+	length_factor = scalar_loop_iters;
+      else
+	length_factor = size_int (vect_factor);
+      segment_length_a = vect_vfa_segment_size (dr_a, length_factor);
+      segment_length_b = vect_vfa_segment_size (dr_b, length_factor);
 
       if (vect_print_dump_info (REPORT_DR_DETAILS))
 	{
-- 
1.7.0.4