summaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch805
1 files changed, 0 insertions, 805 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch
deleted file mode 100644
index ea42ad6ee..000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch
+++ /dev/null
@@ -1,805 +0,0 @@
12011-11-22 Ira Rosen <ira.rosen@linaro.org>
2 Backport from mainline:
3
4 2011-11-06 Ira Rosen <ira.rosen@linaro.org>
5
6 gcc/
7 * tree-vectorizer.h (vectorizable_condition): Add argument.
8 * tree-vect-loop.c (vectorizable_reduction): Fail for condition
9 in SLP. Update calls to vectorizable_condition.
10 * tree-vect-stmts.c (vect_is_simple_cond): Add basic block info to
11 the arguments. Pass it to vect_is_simple_use_1.
12 (vectorizable_condition): Add slp_node to the arguments. Support
13 vectorization of basic blocks. Fail for reduction in SLP. Update
14 calls to vect_is_simple_cond and vect_is_simple_use. Support SLP:
15 call vect_get_slp_defs to get vector operands.
16 (vect_analyze_stmt): Update calls to vectorizable_condition.
17 (vect_transform_stmt): Likewise.
18 * tree-vect-slp.c (vect_create_new_slp_node): Handle COND_EXPR.
19 (vect_get_and_check_slp_defs): Handle COND_EXPR. Allow pattern
20 def stmts.
21 (vect_build_slp_tree): Handle COND_EXPR.
22 (vect_analyze_slp_instance): Push pattern statements to root node.
23 (vect_get_constant_vectors): Fix comments. Handle COND_EXPR.
24
25 gcc/testsuite/
26 * gcc.dg/vect/bb-slp-cond-1.c: New test.
27 * gcc.dg/vect/slp-cond-1.c: New test.
28
29=== added file 'gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c'
30--- old/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c 1970-01-01 00:00:00 +0000
31+++ new/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c 2011-11-20 08:24:08 +0000
32@@ -0,0 +1,46 @@
33+/* { dg-require-effective-target vect_condition } */
34+
35+#include "tree-vect.h"
36+
37+#define N 128
38+
39+__attribute__((noinline, noclone)) void
40+foo (int *a, int stride)
41+{
42+ int i;
43+
44+ for (i = 0; i < N/stride; i++, a += stride)
45+ {
46+ a[0] = a[0] ? 1 : 5;
47+ a[1] = a[1] ? 2 : 6;
48+ a[2] = a[2] ? 3 : 7;
49+ a[3] = a[3] ? 4 : 8;
50+ }
51+}
52+
53+
54+int a[N];
55+int main ()
56+{
57+ int i;
58+
59+ check_vect ();
60+
61+ for (i = 0; i < N; i++)
62+ a[i] = i;
63+
64+ foo (a, 4);
65+
66+ for (i = 1; i < N; i++)
67+ if (a[i] != i%4 + 1)
68+ abort ();
69+
70+ if (a[0] != 5)
71+ abort ();
72+
73+ return 0;
74+}
75+
76+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */
77+/* { dg-final { cleanup-tree-dump "slp" } } */
78+
79
80=== added file 'gcc/testsuite/gcc.dg/vect/slp-cond-1.c'
81--- old/gcc/testsuite/gcc.dg/vect/slp-cond-1.c 1970-01-01 00:00:00 +0000
82+++ new/gcc/testsuite/gcc.dg/vect/slp-cond-1.c 2011-11-20 08:24:08 +0000
83@@ -0,0 +1,126 @@
84+/* { dg-require-effective-target vect_condition } */
85+#include "tree-vect.h"
86+
87+#define N 32
88+int a[N], b[N];
89+int d[N], e[N];
90+int k[N];
91+
92+__attribute__((noinline, noclone)) void
93+f1 (void)
94+{
95+ int i;
96+ for (i = 0; i < N/4; i++)
97+ {
98+ k[4*i] = a[4*i] < b[4*i] ? 17 : 0;
99+ k[4*i+1] = a[4*i+1] < b[4*i+1] ? 17 : 0;
100+ k[4*i+2] = a[4*i+2] < b[4*i+2] ? 17 : 0;
101+ k[4*i+3] = a[4*i+3] < b[4*i+3] ? 17 : 0;
102+ }
103+}
104+
105+__attribute__((noinline, noclone)) void
106+f2 (void)
107+{
108+ int i;
109+ for (i = 0; i < N/2; ++i)
110+ {
111+ k[2*i] = a[2*i] < b[2*i] ? 0 : 24;
112+ k[2*i+1] = a[2*i+1] < b[2*i+1] ? 7 : 4;
113+ }
114+}
115+
116+__attribute__((noinline, noclone)) void
117+f3 (void)
118+{
119+ int i;
120+ for (i = 0; i < N/2; ++i)
121+ {
122+ k[2*i] = a[2*i] < b[2*i] ? 51 : 12;
123+ k[2*i+1] = a[2*i+1] > b[2*i+1] ? 51 : 12;
124+ }
125+}
126+
127+__attribute__((noinline, noclone)) void
128+f4 (void)
129+{
130+ int i;
131+ for (i = 0; i < N/2; ++i)
132+ {
133+ int d0 = d[2*i], e0 = e[2*i];
134+ int d1 = d[2*i+1], e1 = e[2*i+1];
135+ k[2*i] = a[2*i] >= b[2*i] ? d0 : e0;
136+ k[2*i+1] = a[2*i+1] >= b[2*i+1] ? d1 : e1;
137+ }
138+}
139+
140+int
141+main ()
142+{
143+ int i;
144+
145+ check_vect ();
146+
147+ for (i = 0; i < N; i++)
148+ {
149+ switch (i % 9)
150+ {
151+ case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break;
152+ case 1: a[i] = 0; b[i] = 0; break;
153+ case 2: a[i] = i + 1; b[i] = - i - 1; break;
154+ case 3: a[i] = i; b[i] = i + 7; break;
155+ case 4: a[i] = i; b[i] = i; break;
156+ case 5: a[i] = i + 16; b[i] = i + 3; break;
157+ case 6: a[i] = - i - 5; b[i] = - i; break;
158+ case 7: a[i] = - i; b[i] = - i; break;
159+ case 8: a[i] = - i; b[i] = - i - 7; break;
160+ }
161+ d[i] = i;
162+ e[i] = 2 * i;
163+ }
164+ f1 ();
165+ for (i = 0; i < N; i++)
166+ if (k[i] != ((i % 3) == 0 ? 17 : 0))
167+ abort ();
168+
169+ f2 ();
170+ for (i = 0; i < N; i++)
171+ {
172+ switch (i % 9)
173+ {
174+ case 0:
175+ case 6:
176+ if (k[i] != ((i/9 % 2) == 0 ? 0 : 7))
177+ abort ();
178+ break;
179+ case 1:
180+ case 5:
181+ case 7:
182+ if (k[i] != ((i/9 % 2) == 0 ? 4 : 24))
183+ abort ();
184+ break;
185+ case 2:
186+ case 4:
187+ case 8:
188+ if (k[i] != ((i/9 % 2) == 0 ? 24 : 4))
189+ abort ();
190+ break;
191+ case 3:
192+ if (k[i] != ((i/9 % 2) == 0 ? 7 : 0))
193+ abort ();
194+ break;
195+ }
196+ }
197+
198+ f3 ();
199+
200+ f4 ();
201+ for (i = 0; i < N; i++)
202+ if (k[i] != ((i % 3) == 0 ? e[i] : d[i]))
203+ abort ();
204+
205+ return 0;
206+}
207+
208+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */
209+/* { dg-final { cleanup-tree-dump "vect" } } */
210
211=== modified file 'gcc/tree-vect-loop.c'
212--- old/gcc/tree-vect-loop.c 2011-11-14 11:38:08 +0000
213+++ new/gcc/tree-vect-loop.c 2011-11-20 08:24:08 +0000
214@@ -4087,6 +4087,9 @@
215 gcc_unreachable ();
216 }
217
218+ if (code == COND_EXPR && slp_node)
219+ return false;
220+
221 scalar_dest = gimple_assign_lhs (stmt);
222 scalar_type = TREE_TYPE (scalar_dest);
223 if (!POINTER_TYPE_P (scalar_type) && !INTEGRAL_TYPE_P (scalar_type)
224@@ -4161,7 +4164,7 @@
225
226 if (code == COND_EXPR)
227 {
228- if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0))
229+ if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0, NULL))
230 {
231 if (vect_print_dump_info (REPORT_DETAILS))
232 fprintf (vect_dump, "unsupported condition in reduction");
233@@ -4433,7 +4436,7 @@
234 gcc_assert (!slp_node);
235 vectorizable_condition (stmt, gsi, vec_stmt,
236 PHI_RESULT (VEC_index (gimple, phis, 0)),
237- reduc_index);
238+ reduc_index, NULL);
239 /* Multiple types are not supported for condition. */
240 break;
241 }
242
243=== modified file 'gcc/tree-vect-slp.c'
244--- old/gcc/tree-vect-slp.c 2011-11-14 11:38:08 +0000
245+++ new/gcc/tree-vect-slp.c 2011-11-21 06:58:40 +0000
246@@ -109,7 +109,11 @@
247 if (is_gimple_call (stmt))
248 nops = gimple_call_num_args (stmt);
249 else if (is_gimple_assign (stmt))
250- nops = gimple_num_ops (stmt) - 1;
251+ {
252+ nops = gimple_num_ops (stmt) - 1;
253+ if (gimple_assign_rhs_code (stmt) == COND_EXPR)
254+ nops = 4;
255+ }
256 else
257 return NULL;
258
259@@ -190,20 +194,51 @@
260 bool different_types = false;
261 bool pattern = false;
262 slp_oprnd_info oprnd_info, oprnd0_info, oprnd1_info;
263+ int op_idx = 1;
264+ tree compare_rhs = NULL_TREE, rhs = NULL_TREE;
265+ int cond_idx = -1;
266
267 if (loop_vinfo)
268 loop = LOOP_VINFO_LOOP (loop_vinfo);
269
270 if (is_gimple_call (stmt))
271 number_of_oprnds = gimple_call_num_args (stmt);
272+ else if (is_gimple_assign (stmt))
273+ {
274+ number_of_oprnds = gimple_num_ops (stmt) - 1;
275+ if (gimple_assign_rhs_code (stmt) == COND_EXPR)
276+ {
277+ number_of_oprnds = 4;
278+ cond_idx = 0;
279+ rhs = gimple_assign_rhs1 (stmt);
280+ }
281+ }
282 else
283- number_of_oprnds = gimple_num_ops (stmt) - 1;
284+ return false;
285
286 for (i = 0; i < number_of_oprnds; i++)
287 {
288- oprnd = gimple_op (stmt, i + 1);
289+ if (compare_rhs)
290+ oprnd = compare_rhs;
291+ else
292+ oprnd = gimple_op (stmt, op_idx++);
293+
294 oprnd_info = VEC_index (slp_oprnd_info, *oprnds_info, i);
295
296+ if (-1 < cond_idx && cond_idx < 4)
297+ {
298+ if (compare_rhs)
299+ compare_rhs = NULL_TREE;
300+ else
301+ oprnd = TREE_OPERAND (rhs, cond_idx++);
302+ }
303+
304+ if (COMPARISON_CLASS_P (oprnd))
305+ {
306+ compare_rhs = TREE_OPERAND (oprnd, 1);
307+ oprnd = TREE_OPERAND (oprnd, 0);
308+ }
309+
310 if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def,
311 &dt)
312 || (!def_stmt && dt != vect_constant_def))
313@@ -243,8 +278,7 @@
314 def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt));
315 dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt));
316
317- if (dt == vect_unknown_def_type
318- || STMT_VINFO_PATTERN_DEF_STMT (vinfo_for_stmt (def_stmt)))
319+ if (dt == vect_unknown_def_type)
320 {
321 if (vect_print_dump_info (REPORT_DETAILS))
322 fprintf (vect_dump, "Unsupported pattern.");
323@@ -423,6 +457,7 @@
324 VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node);
325 gimple stmt = VEC_index (gimple, stmts, 0);
326 enum tree_code first_stmt_code = ERROR_MARK, rhs_code = ERROR_MARK;
327+ enum tree_code first_cond_code = ERROR_MARK;
328 tree lhs;
329 bool stop_recursion = false, need_same_oprnds = false;
330 tree vectype, scalar_type, first_op1 = NULL_TREE;
331@@ -439,11 +474,18 @@
332 VEC (slp_oprnd_info, heap) *oprnds_info;
333 unsigned int nops;
334 slp_oprnd_info oprnd_info;
335+ tree cond;
336
337 if (is_gimple_call (stmt))
338 nops = gimple_call_num_args (stmt);
339+ else if (is_gimple_assign (stmt))
340+ {
341+ nops = gimple_num_ops (stmt) - 1;
342+ if (gimple_assign_rhs_code (stmt) == COND_EXPR)
343+ nops = 4;
344+ }
345 else
346- nops = gimple_num_ops (stmt) - 1;
347+ return false;
348
349 oprnds_info = vect_create_oprnd_info (nops, group_size);
350
351@@ -484,6 +526,22 @@
352 return false;
353 }
354
355+ if (is_gimple_assign (stmt)
356+ && gimple_assign_rhs_code (stmt) == COND_EXPR
357+ && (cond = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0))
358+ && !COMPARISON_CLASS_P (cond))
359+ {
360+ if (vect_print_dump_info (REPORT_SLP))
361+ {
362+ fprintf (vect_dump,
363+ "Build SLP failed: condition is not comparison ");
364+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
365+ }
366+
367+ vect_free_oprnd_info (&oprnds_info);
368+ return false;
369+ }
370+
371 scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy);
372 vectype = get_vectype_for_scalar_type (scalar_type);
373 if (!vectype)
374@@ -737,7 +795,8 @@
375
376 /* Not memory operation. */
377 if (TREE_CODE_CLASS (rhs_code) != tcc_binary
378- && TREE_CODE_CLASS (rhs_code) != tcc_unary)
379+ && TREE_CODE_CLASS (rhs_code) != tcc_unary
380+ && rhs_code != COND_EXPR)
381 {
382 if (vect_print_dump_info (REPORT_SLP))
383 {
384@@ -750,6 +809,26 @@
385 return false;
386 }
387
388+ if (rhs_code == COND_EXPR)
389+ {
390+ tree cond_expr = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
391+
392+ if (i == 0)
393+ first_cond_code = TREE_CODE (cond_expr);
394+ else if (first_cond_code != TREE_CODE (cond_expr))
395+ {
396+ if (vect_print_dump_info (REPORT_SLP))
397+ {
398+ fprintf (vect_dump, "Build SLP failed: different"
399+ " operation");
400+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
401+ }
402+
403+ vect_free_oprnd_info (&oprnds_info);
404+ return false;
405+ }
406+ }
407+
408 /* Find the def-stmts. */
409 if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, stmt,
410 ncopies_for_cost, (i == 0),
411@@ -1395,7 +1474,12 @@
412 /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */
413 while (next)
414 {
415- VEC_safe_push (gimple, heap, scalar_stmts, next);
416+ if (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (next))
417+ && STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next)))
418+ VEC_safe_push (gimple, heap, scalar_stmts,
419+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next)));
420+ else
421+ VEC_safe_push (gimple, heap, scalar_stmts, next);
422 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
423 }
424 }
425@@ -1404,7 +1488,7 @@
426 /* Collect reduction statements. */
427 VEC (gimple, heap) *reductions = LOOP_VINFO_REDUCTIONS (loop_vinfo);
428 for (i = 0; VEC_iterate (gimple, reductions, i, next); i++)
429- VEC_safe_push (gimple, heap, scalar_stmts, next);
430+ VEC_safe_push (gimple, heap, scalar_stmts, next);
431 }
432
433 node = vect_create_new_slp_node (scalar_stmts);
434@@ -2160,15 +2244,15 @@
435
436 For example, we have two scalar operands, s1 and s2 (e.g., group of
437 strided accesses of size two), while NUNITS is four (i.e., four scalars
438- of this type can be packed in a vector). The output vector will contain
439- two copies of each scalar operand: {s1, s2, s1, s2}. (NUMBER_OF_COPIES
440+ of this type can be packed in a vector). The output vector will contain
441+ two copies of each scalar operand: {s1, s2, s1, s2}. (NUMBER_OF_COPIES
442 will be 2).
443
444 If GROUP_SIZE > NUNITS, the scalars will be split into several vectors
445 containing the operands.
446
447 For example, NUNITS is four as before, and the group size is 8
448- (s1, s2, ..., s8). We will create two vectors {s1, s2, s3, s4} and
449+ (s1, s2, ..., s8). We will create two vectors {s1, s2, s3, s4} and
450 {s5, s6, s7, s8}. */
451
452 number_of_copies = least_common_multiple (nunits, group_size) / group_size;
453@@ -2180,8 +2264,18 @@
454 {
455 if (is_store)
456 op = gimple_assign_rhs1 (stmt);
457- else
458+ else if (gimple_assign_rhs_code (stmt) != COND_EXPR)
459 op = gimple_op (stmt, op_num + 1);
460+ else
461+ {
462+ if (op_num == 0 || op_num == 1)
463+ {
464+ tree cond = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
465+ op = TREE_OPERAND (cond, op_num);
466+ }
467+ else
468+ op = TREE_OPERAND (gimple_assign_rhs1 (stmt), op_num - 1);
469+ }
470
471 if (reduc_index != -1)
472 {
473
474=== modified file 'gcc/tree-vect-stmts.c'
475--- old/gcc/tree-vect-stmts.c 2011-11-22 16:52:23 +0000
476+++ new/gcc/tree-vect-stmts.c 2011-11-22 17:10:17 +0000
477@@ -4816,7 +4816,7 @@
478 condition operands are supportable using vec_is_simple_use. */
479
480 static bool
481-vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
482+vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
483 {
484 tree lhs, rhs;
485 tree def;
486@@ -4831,7 +4831,7 @@
487 if (TREE_CODE (lhs) == SSA_NAME)
488 {
489 gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
490- if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
491+ if (!vect_is_simple_use (lhs, loop_vinfo, bb_vinfo, &lhs_def_stmt, &def,
492 &dt))
493 return false;
494 }
495@@ -4842,7 +4842,7 @@
496 if (TREE_CODE (rhs) == SSA_NAME)
497 {
498 gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
499- if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
500+ if (!vect_is_simple_use (rhs, loop_vinfo, bb_vinfo, &rhs_def_stmt, &def,
501 &dt))
502 return false;
503 }
504@@ -4868,7 +4868,8 @@
505
506 bool
507 vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
508- gimple *vec_stmt, tree reduc_def, int reduc_index)
509+ gimple *vec_stmt, tree reduc_def, int reduc_index,
510+ slp_tree slp_node)
511 {
512 tree scalar_dest = NULL_TREE;
513 tree vec_dest = NULL_TREE;
514@@ -4885,19 +4886,24 @@
515 tree def;
516 enum vect_def_type dt, dts[4];
517 int nunits = TYPE_VECTOR_SUBPARTS (vectype);
518- int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
519+ int ncopies;
520 enum tree_code code;
521 stmt_vec_info prev_stmt_info = NULL;
522- int j;
523+ int i, j;
524+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
525+ VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
526+ VEC (tree, heap) *vec_oprnds2 = NULL, *vec_oprnds3 = NULL;
527
528- /* FORNOW: unsupported in basic block SLP. */
529- gcc_assert (loop_vinfo);
530+ if (slp_node || PURE_SLP_STMT (stmt_info))
531+ ncopies = 1;
532+ else
533+ ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
534
535 gcc_assert (ncopies >= 1);
536- if (reduc_index && ncopies > 1)
537+ if (reduc_index && (ncopies > 1 || STMT_SLP_TYPE (stmt_info)))
538 return false; /* FORNOW */
539
540- if (!STMT_VINFO_RELEVANT_P (stmt_info))
541+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
542 return false;
543
544 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
545@@ -4905,10 +4911,6 @@
546 && reduc_def))
547 return false;
548
549- /* FORNOW: SLP not supported. */
550- if (STMT_SLP_TYPE (stmt_info))
551- return false;
552-
553 /* FORNOW: not yet supported. */
554 if (STMT_VINFO_LIVE_P (stmt_info))
555 {
556@@ -4932,7 +4934,7 @@
557 then_clause = TREE_OPERAND (op, 1);
558 else_clause = TREE_OPERAND (op, 2);
559
560- if (!vect_is_simple_cond (cond_expr, loop_vinfo))
561+ if (!vect_is_simple_cond (cond_expr, loop_vinfo, bb_vinfo))
562 return false;
563
564 /* We do not handle two different vector types for the condition
565@@ -4944,7 +4946,7 @@
566 if (TREE_CODE (then_clause) == SSA_NAME)
567 {
568 gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
569- if (!vect_is_simple_use (then_clause, loop_vinfo, NULL,
570+ if (!vect_is_simple_use (then_clause, loop_vinfo, bb_vinfo,
571 &then_def_stmt, &def, &dt))
572 return false;
573 }
574@@ -4956,7 +4958,7 @@
575 if (TREE_CODE (else_clause) == SSA_NAME)
576 {
577 gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
578- if (!vect_is_simple_use (else_clause, loop_vinfo, NULL,
579+ if (!vect_is_simple_use (else_clause, loop_vinfo, bb_vinfo,
580 &else_def_stmt, &def, &dt))
581 return false;
582 }
583@@ -4974,7 +4976,15 @@
584 return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode);
585 }
586
587- /* Transform */
588+ /* Transform. */
589+
590+ if (!slp_node)
591+ {
592+ vec_oprnds0 = VEC_alloc (tree, heap, 1);
593+ vec_oprnds1 = VEC_alloc (tree, heap, 1);
594+ vec_oprnds2 = VEC_alloc (tree, heap, 1);
595+ vec_oprnds3 = VEC_alloc (tree, heap, 1);
596+ }
597
598 /* Handle def. */
599 scalar_dest = gimple_assign_lhs (stmt);
600@@ -4983,67 +4993,118 @@
601 /* Handle cond expr. */
602 for (j = 0; j < ncopies; j++)
603 {
604- gimple new_stmt;
605+ gimple new_stmt = NULL;
606 if (j == 0)
607 {
608- gimple gtemp;
609- vec_cond_lhs =
610+ if (slp_node)
611+ {
612+ VEC (tree, heap) *ops = VEC_alloc (tree, heap, 4);
613+ VEC (slp_void_p, heap) *vec_defs;
614+
615+ vec_defs = VEC_alloc (slp_void_p, heap, 4);
616+ VEC_safe_push (tree, heap, ops, TREE_OPERAND (cond_expr, 0));
617+ VEC_safe_push (tree, heap, ops, TREE_OPERAND (cond_expr, 1));
618+ VEC_safe_push (tree, heap, ops, then_clause);
619+ VEC_safe_push (tree, heap, ops, else_clause);
620+ vect_get_slp_defs (ops, slp_node, &vec_defs, -1);
621+ vec_oprnds3 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs);
622+ vec_oprnds2 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs);
623+ vec_oprnds1 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs);
624+ vec_oprnds0 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs);
625+
626+ VEC_free (tree, heap, ops);
627+ VEC_free (slp_void_p, heap, vec_defs);
628+ }
629+ else
630+ {
631+ gimple gtemp;
632+ vec_cond_lhs =
633 vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
634 stmt, NULL);
635- vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
636+ vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
637 NULL, &gtemp, &def, &dts[0]);
638- vec_cond_rhs =
639- vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
640- stmt, NULL);
641- vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
642- NULL, &gtemp, &def, &dts[1]);
643- if (reduc_index == 1)
644- vec_then_clause = reduc_def;
645- else
646- {
647- vec_then_clause = vect_get_vec_def_for_operand (then_clause,
648- stmt, NULL);
649- vect_is_simple_use (then_clause, loop_vinfo,
650- NULL, &gtemp, &def, &dts[2]);
651- }
652- if (reduc_index == 2)
653- vec_else_clause = reduc_def;
654- else
655- {
656- vec_else_clause = vect_get_vec_def_for_operand (else_clause,
657- stmt, NULL);
658- vect_is_simple_use (else_clause, loop_vinfo,
659+
660+ vec_cond_rhs =
661+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
662+ stmt, NULL);
663+ vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
664+ NULL, &gtemp, &def, &dts[1]);
665+ if (reduc_index == 1)
666+ vec_then_clause = reduc_def;
667+ else
668+ {
669+ vec_then_clause = vect_get_vec_def_for_operand (then_clause,
670+ stmt, NULL);
671+ vect_is_simple_use (then_clause, loop_vinfo,
672+ NULL, &gtemp, &def, &dts[2]);
673+ }
674+ if (reduc_index == 2)
675+ vec_else_clause = reduc_def;
676+ else
677+ {
678+ vec_else_clause = vect_get_vec_def_for_operand (else_clause,
679+ stmt, NULL);
680+ vect_is_simple_use (else_clause, loop_vinfo,
681 NULL, &gtemp, &def, &dts[3]);
682+ }
683 }
684 }
685 else
686 {
687- vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs);
688- vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs);
689+ vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0],
690+ VEC_pop (tree, vec_oprnds0));
691+ vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1],
692+ VEC_pop (tree, vec_oprnds1));
693 vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2],
694- vec_then_clause);
695+ VEC_pop (tree, vec_oprnds2));
696 vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3],
697- vec_else_clause);
698+ VEC_pop (tree, vec_oprnds3));
699+ }
700+
701+ if (!slp_node)
702+ {
703+ VEC_quick_push (tree, vec_oprnds0, vec_cond_lhs);
704+ VEC_quick_push (tree, vec_oprnds1, vec_cond_rhs);
705+ VEC_quick_push (tree, vec_oprnds2, vec_then_clause);
706+ VEC_quick_push (tree, vec_oprnds3, vec_else_clause);
707 }
708
709 /* Arguments are ready. Create the new vector stmt. */
710- vec_compare = build2 (TREE_CODE (cond_expr), vectype,
711- vec_cond_lhs, vec_cond_rhs);
712- vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
713- vec_compare, vec_then_clause, vec_else_clause);
714-
715- new_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
716- new_temp = make_ssa_name (vec_dest, new_stmt);
717- gimple_assign_set_lhs (new_stmt, new_temp);
718- vect_finish_stmt_generation (stmt, new_stmt, gsi);
719- if (j == 0)
720- STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
721- else
722- STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
723-
724- prev_stmt_info = vinfo_for_stmt (new_stmt);
725+ FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vec_cond_lhs)
726+ {
727+ vec_cond_rhs = VEC_index (tree, vec_oprnds1, i);
728+ vec_then_clause = VEC_index (tree, vec_oprnds2, i);
729+ vec_else_clause = VEC_index (tree, vec_oprnds3, i);
730+
731+ vec_compare = build2 (TREE_CODE (cond_expr), vectype,
732+ vec_cond_lhs, vec_cond_rhs);
733+ vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
734+ vec_compare, vec_then_clause, vec_else_clause);
735+
736+ new_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
737+ new_temp = make_ssa_name (vec_dest, new_stmt);
738+ gimple_assign_set_lhs (new_stmt, new_temp);
739+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
740+ if (slp_node)
741+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
742+ }
743+
744+ if (slp_node)
745+ continue;
746+
747+ if (j == 0)
748+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
749+ else
750+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
751+
752+ prev_stmt_info = vinfo_for_stmt (new_stmt);
753 }
754
755+ VEC_free (tree, heap, vec_oprnds0);
756+ VEC_free (tree, heap, vec_oprnds1);
757+ VEC_free (tree, heap, vec_oprnds2);
758+ VEC_free (tree, heap, vec_oprnds3);
759+
760 return true;
761 }
762
763@@ -5217,7 +5278,7 @@
764 || vectorizable_call (stmt, NULL, NULL)
765 || vectorizable_store (stmt, NULL, NULL, NULL)
766 || vectorizable_reduction (stmt, NULL, NULL, NULL)
767- || vectorizable_condition (stmt, NULL, NULL, NULL, 0));
768+ || vectorizable_condition (stmt, NULL, NULL, NULL, 0, NULL));
769 else
770 {
771 if (bb_vinfo)
772@@ -5227,7 +5288,8 @@
773 || vectorizable_operation (stmt, NULL, NULL, node)
774 || vectorizable_assignment (stmt, NULL, NULL, node)
775 || vectorizable_load (stmt, NULL, NULL, node, NULL)
776- || vectorizable_store (stmt, NULL, NULL, node));
777+ || vectorizable_store (stmt, NULL, NULL, node)
778+ || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node));
779 }
780
781 if (!ok)
782@@ -5343,8 +5405,7 @@
783 break;
784
785 case condition_vec_info_type:
786- gcc_assert (!slp_node);
787- done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0);
788+ done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0, slp_node);
789 gcc_assert (done);
790 break;
791
792
793=== modified file 'gcc/tree-vectorizer.h'
794--- old/gcc/tree-vectorizer.h 2011-11-22 16:52:23 +0000
795+++ new/gcc/tree-vectorizer.h 2011-11-22 17:10:17 +0000
796@@ -832,7 +832,7 @@
797 extern void vect_remove_stores (gimple);
798 extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
799 extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
800- tree, int);
801+ tree, int, slp_tree);
802 extern void vect_get_load_cost (struct data_reference *, int, bool,
803 unsigned int *, unsigned int *);
804 extern void vect_get_store_cost (struct data_reference *, int, unsigned int *);
805