tree-vect-generic.c (expand_vector_operations_1): Do nothing for operations we cannot...
[platform/upstream/gcc.git] / gcc / tree-vect-generic.c
1 /* Lower vector operations to scalar operations.
2    Copyright (C) 2004-2017 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "tree-pass.h"
28 #include "ssa.h"
29 #include "expmed.h"
30 #include "optabs-tree.h"
31 #include "diagnostic.h"
32 #include "fold-const.h"
33 #include "stor-layout.h"
34 #include "langhooks.h"
35 #include "tree-eh.h"
36 #include "gimple-iterator.h"
37 #include "gimplify-me.h"
38 #include "gimplify.h"
39 #include "tree-cfg.h"
40
41
42 static void expand_vector_operations_1 (gimple_stmt_iterator *);
43
44
45 /* Build a constant of type TYPE, made of VALUE's bits replicated
46    every TYPE_SIZE (INNER_TYPE) bits to fit TYPE's precision.  */
47 static tree
48 build_replicated_const (tree type, tree inner_type, HOST_WIDE_INT value)
49 {
50   int width = tree_to_uhwi (TYPE_SIZE (inner_type));
51   int n = (TYPE_PRECISION (type) + HOST_BITS_PER_WIDE_INT - 1) 
52     / HOST_BITS_PER_WIDE_INT;
53   unsigned HOST_WIDE_INT low, mask;
54   HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
55   int i;
56
57   gcc_assert (n && n <= WIDE_INT_MAX_ELTS);
58
59   if (width == HOST_BITS_PER_WIDE_INT)
60     low = value;
61   else
62     {
63       mask = ((HOST_WIDE_INT)1 << width) - 1;
64       low = (unsigned HOST_WIDE_INT) ~0 / mask * (value & mask);
65     }
66
67   for (i = 0; i < n; i++)
68     a[i] = low;
69
70   gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT);
71   return wide_int_to_tree
72     (type, wide_int::from_array (a, n, TYPE_PRECISION (type)));
73 }
74
75 static GTY(()) tree vector_inner_type;
76 static GTY(()) tree vector_last_type;
77 static GTY(()) int vector_last_nunits;
78
79 /* Return a suitable vector types made of SUBPARTS units each of mode
80    "word_mode" (the global variable).  */
81 static tree
82 build_word_mode_vector_type (int nunits)
83 {
84   if (!vector_inner_type)
85     vector_inner_type = lang_hooks.types.type_for_mode (word_mode, 1);
86   else if (vector_last_nunits == nunits)
87     {
88       gcc_assert (TREE_CODE (vector_last_type) == VECTOR_TYPE);
89       return vector_last_type;
90     }
91
92   /* We build a new type, but we canonicalize it nevertheless,
93      because it still saves some memory.  */
94   vector_last_nunits = nunits;
95   vector_last_type = type_hash_canon (nunits,
96                                       build_vector_type (vector_inner_type,
97                                                          nunits));
98   return vector_last_type;
99 }
100
101 typedef tree (*elem_op_func) (gimple_stmt_iterator *,
102                               tree, tree, tree, tree, tree, enum tree_code,
103                               tree);
104
105 static inline tree
106 tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
107                   tree t, tree bitsize, tree bitpos)
108 {
109   if (TREE_CODE (t) == SSA_NAME)
110     {
111       gimple *def_stmt = SSA_NAME_DEF_STMT (t);
112       if (is_gimple_assign (def_stmt)
113           && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST
114               || (bitpos
115                   && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR)))
116         t = gimple_assign_rhs1 (def_stmt);
117     }
118   if (bitpos)
119     {
120       if (TREE_CODE (type) == BOOLEAN_TYPE)
121         {
122           tree itype
123             = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 0);
124           tree field = gimplify_build3 (gsi, BIT_FIELD_REF, itype, t,
125                                         bitsize, bitpos);
126           return gimplify_build2 (gsi, NE_EXPR, type, field,
127                                   build_zero_cst (itype));
128         }
129       else
130         return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
131     }
132   else
133     return gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
134 }
135
136 static tree
137 do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
138          tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
139          enum tree_code code, tree type ATTRIBUTE_UNUSED)
140 {
141   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
142   return gimplify_build1 (gsi, code, inner_type, a);
143 }
144
145 static tree
146 do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
147           tree bitpos, tree bitsize, enum tree_code code,
148           tree type ATTRIBUTE_UNUSED)
149 {
150   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
151     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
152   if (TREE_CODE (TREE_TYPE (b)) == VECTOR_TYPE)
153     b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
154   return gimplify_build2 (gsi, code, inner_type, a, b);
155 }
156
157 /* Construct expression (A[BITPOS] code B[BITPOS]) ? -1 : 0
158
159    INNER_TYPE is the type of A and B elements
160
161    returned expression is of signed integer type with the
162    size equal to the size of INNER_TYPE.  */
163 static tree
164 do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
165             tree bitpos, tree bitsize, enum tree_code code, tree type)
166 {
167   tree stype = TREE_TYPE (type);
168   tree cst_false = build_zero_cst (stype);
169   tree cst_true = build_all_ones_cst (stype);
170   tree cmp;
171
172   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
173   b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
174
175   cmp = build2 (code, boolean_type_node, a, b);
176   return gimplify_build3 (gsi, COND_EXPR, stype, cmp, cst_true, cst_false);
177 }
178
179 /* Expand vector addition to scalars.  This does bit twiddling
180    in order to increase parallelism:
181
182    a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
183            (a ^ b) & 0x80808080
184
185    a - b =  (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
186             (a ^ ~b) & 0x80808080
187
188    -b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
189
190    This optimization should be done only if 4 vector items or more
191    fit into a word.  */
192 static tree
193 do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
194                tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
195                enum tree_code code, tree type ATTRIBUTE_UNUSED)
196 {
197   tree inner_type = TREE_TYPE (TREE_TYPE (a));
198   unsigned HOST_WIDE_INT max;
199   tree low_bits, high_bits, a_low, b_low, result_low, signs;
200
201   max = GET_MODE_MASK (TYPE_MODE (inner_type));
202   low_bits = build_replicated_const (word_type, inner_type, max >> 1);
203   high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
204
205   a = tree_vec_extract (gsi, word_type, a, bitsize, bitpos);
206   b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
207
208   signs = gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, a, b);
209   b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
210   if (code == PLUS_EXPR)
211     a_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, a, low_bits);
212   else
213     {
214       a_low = gimplify_build2 (gsi, BIT_IOR_EXPR, word_type, a, high_bits);
215       signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, signs);
216     }
217
218   signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
219   result_low = gimplify_build2 (gsi, code, word_type, a_low, b_low);
220   return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
221 }
222
223 static tree
224 do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
225            tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
226            tree bitsize ATTRIBUTE_UNUSED,
227            enum tree_code code ATTRIBUTE_UNUSED,
228            tree type ATTRIBUTE_UNUSED)
229 {
230   tree inner_type = TREE_TYPE (TREE_TYPE (b));
231   HOST_WIDE_INT max;
232   tree low_bits, high_bits, b_low, result_low, signs;
233
234   max = GET_MODE_MASK (TYPE_MODE (inner_type));
235   low_bits = build_replicated_const (word_type, inner_type, max >> 1);
236   high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
237
238   b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
239
240   b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
241   signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, b);
242   signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
243   result_low = gimplify_build2 (gsi, MINUS_EXPR, word_type, high_bits, b_low);
244   return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
245 }
246
247 /* Expand a vector operation to scalars, by using many operations
248    whose type is the vector type's inner type.  */
249 static tree
250 expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
251                          tree type, tree inner_type,
252                          tree a, tree b, enum tree_code code)
253 {
254   vec<constructor_elt, va_gc> *v;
255   tree part_width = TYPE_SIZE (inner_type);
256   tree index = bitsize_int (0);
257   int nunits = TYPE_VECTOR_SUBPARTS (type);
258   int delta = tree_to_uhwi (part_width)
259               / tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)));
260   int i;
261   location_t loc = gimple_location (gsi_stmt (*gsi));
262
263   if (types_compatible_p (gimple_expr_type (gsi_stmt (*gsi)), type))
264     warning_at (loc, OPT_Wvector_operation_performance,
265                 "vector operation will be expanded piecewise");
266   else
267     warning_at (loc, OPT_Wvector_operation_performance,
268                 "vector operation will be expanded in parallel");
269
270   vec_alloc (v, (nunits + delta - 1) / delta);
271   for (i = 0; i < nunits;
272        i += delta, index = int_const_binop (PLUS_EXPR, index, part_width))
273     {
274       tree result = f (gsi, inner_type, a, b, index, part_width, code, type);
275       constructor_elt ce = {NULL_TREE, result};
276       v->quick_push (ce);
277     }
278
279   return build_constructor (type, v);
280 }
281
282 /* Expand a vector operation to scalars with the freedom to use
283    a scalar integer type, or to use a different size for the items
284    in the vector type.  */
285 static tree
286 expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type,
287                         tree a, tree b,
288                         enum tree_code code)
289 {
290   tree result, compute_type;
291   int n_words = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
292   location_t loc = gimple_location (gsi_stmt (*gsi));
293
294   /* We have three strategies.  If the type is already correct, just do
295      the operation an element at a time.  Else, if the vector is wider than
296      one word, do it a word at a time; finally, if the vector is smaller
297      than one word, do it as a scalar.  */
298   if (TYPE_MODE (TREE_TYPE (type)) == word_mode)
299      return expand_vector_piecewise (gsi, f,
300                                      type, TREE_TYPE (type),
301                                      a, b, code);
302   else if (n_words > 1)
303     {
304       tree word_type = build_word_mode_vector_type (n_words);
305       result = expand_vector_piecewise (gsi, f,
306                                         word_type, TREE_TYPE (word_type),
307                                         a, b, code);
308       result = force_gimple_operand_gsi (gsi, result, true, NULL, true,
309                                          GSI_SAME_STMT);
310     }
311   else
312     {
313       /* Use a single scalar operation with a mode no wider than word_mode.  */
314       scalar_int_mode mode
315         = int_mode_for_size (tree_to_uhwi (TYPE_SIZE (type)), 0).require ();
316       compute_type = lang_hooks.types.type_for_mode (mode, 1);
317       result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code, type);
318       warning_at (loc, OPT_Wvector_operation_performance,
319                   "vector operation will be expanded with a "
320                   "single scalar operation");
321     }
322
323   return result;
324 }
325
326 /* Expand a vector operation to scalars; for integer types we can use
327    special bit twiddling tricks to do the sums a word at a time, using
328    function F_PARALLEL instead of F.  These tricks are done only if
329    they can process at least four items, that is, only if the vector
330    holds at least four items and if a word can hold four items.  */
331 static tree
332 expand_vector_addition (gimple_stmt_iterator *gsi,
333                         elem_op_func f, elem_op_func f_parallel,
334                         tree type, tree a, tree b, enum tree_code code)
335 {
336   int parts_per_word = UNITS_PER_WORD
337                        / tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
338
339   if (INTEGRAL_TYPE_P (TREE_TYPE (type))
340       && parts_per_word >= 4
341       && TYPE_VECTOR_SUBPARTS (type) >= 4)
342     return expand_vector_parallel (gsi, f_parallel,
343                                    type, a, b, code);
344   else
345     return expand_vector_piecewise (gsi, f,
346                                     type, TREE_TYPE (type),
347                                     a, b, code);
348 }
349
350 /* Try to expand vector comparison expression OP0 CODE OP1 by
351    querying optab if the following expression:
352         VEC_COND_EXPR< OP0 CODE OP1, {-1,...}, {0,...}>
353    can be expanded.  */
354 static tree
355 expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
356                           tree op1, enum tree_code code)
357 {
358   tree t;
359   if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
360       && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
361     t = expand_vector_piecewise (gsi, do_compare, type,
362                                  TREE_TYPE (TREE_TYPE (op0)), op0, op1, code);
363   else
364     t = NULL_TREE;
365
366   return t;
367 }
368
369 /* Helper function of expand_vector_divmod.  Gimplify a RSHIFT_EXPR in type
370    of OP0 with shift counts in SHIFTCNTS array and return the temporary holding
371    the result if successful, otherwise return NULL_TREE.  */
372 static tree
373 add_rshift (gimple_stmt_iterator *gsi, tree type, tree op0, int *shiftcnts)
374 {
375   optab op;
376   unsigned int i, nunits = TYPE_VECTOR_SUBPARTS (type);
377   bool scalar_shift = true;
378
379   for (i = 1; i < nunits; i++)
380     {
381       if (shiftcnts[i] != shiftcnts[0])
382         scalar_shift = false;
383     }
384
385   if (scalar_shift && shiftcnts[0] == 0)
386     return op0;
387
388   if (scalar_shift)
389     {
390       op = optab_for_tree_code (RSHIFT_EXPR, type, optab_scalar);
391       if (op != unknown_optab
392           && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
393         return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0,
394                                 build_int_cst (NULL_TREE, shiftcnts[0]));
395     }
396
397   op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
398   if (op != unknown_optab
399       && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
400     {
401       tree *vec = XALLOCAVEC (tree, nunits);
402       for (i = 0; i < nunits; i++)
403         vec[i] = build_int_cst (TREE_TYPE (type), shiftcnts[i]);
404       return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0,
405                               build_vector (type, vec));
406     }
407
408   return NULL_TREE;
409 }
410
411 /* Try to expand integer vector division by constant using
412    widening multiply, shifts and additions.  */
413 static tree
414 expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
415                       tree op1, enum tree_code code)
416 {
417   bool use_pow2 = true;
418   bool has_vector_shift = true;
419   int mode = -1, this_mode;
420   int pre_shift = -1, post_shift;
421   unsigned int nunits = TYPE_VECTOR_SUBPARTS (type);
422   int *shifts = XALLOCAVEC (int, nunits * 4);
423   int *pre_shifts = shifts + nunits;
424   int *post_shifts = pre_shifts + nunits;
425   int *shift_temps = post_shifts + nunits;
426   unsigned HOST_WIDE_INT *mulc = XALLOCAVEC (unsigned HOST_WIDE_INT, nunits);
427   int prec = TYPE_PRECISION (TREE_TYPE (type));
428   int dummy_int;
429   unsigned int i;
430   signop sign_p = TYPE_SIGN (TREE_TYPE (type));
431   unsigned HOST_WIDE_INT mask = GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type)));
432   tree *vec;
433   tree cur_op, mulcst, tem;
434   optab op;
435
436   if (prec > HOST_BITS_PER_WIDE_INT)
437     return NULL_TREE;
438
439   op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
440   if (op == unknown_optab
441       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
442     has_vector_shift = false;
443
444   /* Analysis phase.  Determine if all op1 elements are either power
445      of two and it is possible to expand it using shifts (or for remainder
446      using masking).  Additionally compute the multiplicative constants
447      and pre and post shifts if the division is to be expanded using
448      widening or high part multiplication plus shifts.  */
449   for (i = 0; i < nunits; i++)
450     {
451       tree cst = VECTOR_CST_ELT (op1, i);
452       unsigned HOST_WIDE_INT ml;
453
454       if (TREE_CODE (cst) != INTEGER_CST || integer_zerop (cst))
455         return NULL_TREE;
456       pre_shifts[i] = 0;
457       post_shifts[i] = 0;
458       mulc[i] = 0;
459       if (use_pow2
460           && (!integer_pow2p (cst) || tree_int_cst_sgn (cst) != 1))
461         use_pow2 = false;
462       if (use_pow2)
463         {
464           shifts[i] = tree_log2 (cst);
465           if (shifts[i] != shifts[0]
466               && code == TRUNC_DIV_EXPR
467               && !has_vector_shift)
468             use_pow2 = false;
469         }
470       if (mode == -2)
471         continue;
472       if (sign_p == UNSIGNED)
473         {
474           unsigned HOST_WIDE_INT mh;
475           unsigned HOST_WIDE_INT d = TREE_INT_CST_LOW (cst) & mask;
476
477           if (d >= (HOST_WIDE_INT_1U << (prec - 1)))
478             /* FIXME: Can transform this into op0 >= op1 ? 1 : 0.  */
479             return NULL_TREE;
480
481           if (d <= 1)
482             {
483               mode = -2;
484               continue;
485             }
486
487           /* Find a suitable multiplier and right shift count
488              instead of multiplying with D.  */
489           mh = choose_multiplier (d, prec, prec, &ml, &post_shift, &dummy_int);
490
491           /* If the suggested multiplier is more than SIZE bits, we can
492              do better for even divisors, using an initial right shift.  */
493           if ((mh != 0 && (d & 1) == 0)
494               || (!has_vector_shift && pre_shift != -1))
495             {
496               if (has_vector_shift)
497                 pre_shift = ctz_or_zero (d);
498               else if (pre_shift == -1)
499                 {
500                   unsigned int j;
501                   for (j = 0; j < nunits; j++)
502                     {
503                       tree cst2 = VECTOR_CST_ELT (op1, j);
504                       unsigned HOST_WIDE_INT d2;
505                       int this_pre_shift;
506
507                       if (!tree_fits_uhwi_p (cst2))
508                         return NULL_TREE;
509                       d2 = tree_to_uhwi (cst2) & mask;
510                       if (d2 == 0)
511                         return NULL_TREE;
512                       this_pre_shift = floor_log2 (d2 & -d2);
513                       if (pre_shift == -1 || this_pre_shift < pre_shift)
514                         pre_shift = this_pre_shift;
515                     }
516                   if (i != 0 && pre_shift != 0)
517                     {
518                       /* Restart.  */
519                       i = -1U;
520                       mode = -1;
521                       continue;
522                     }
523                 }
524               if (pre_shift != 0)
525                 {
526                   if ((d >> pre_shift) <= 1)
527                     {
528                       mode = -2;
529                       continue;
530                     }
531                   mh = choose_multiplier (d >> pre_shift, prec,
532                                           prec - pre_shift,
533                                           &ml, &post_shift, &dummy_int);
534                   gcc_assert (!mh);
535                   pre_shifts[i] = pre_shift;
536                 }
537             }
538           if (!mh)
539             this_mode = 0;
540           else
541             this_mode = 1;
542         }
543       else
544         {
545           HOST_WIDE_INT d = TREE_INT_CST_LOW (cst);
546           unsigned HOST_WIDE_INT abs_d;
547
548           if (d == -1)
549             return NULL_TREE;
550
551           /* Since d might be INT_MIN, we have to cast to
552              unsigned HOST_WIDE_INT before negating to avoid
553              undefined signed overflow.  */
554           abs_d = (d >= 0
555                   ? (unsigned HOST_WIDE_INT) d
556                   : - (unsigned HOST_WIDE_INT) d);
557
558           /* n rem d = n rem -d */
559           if (code == TRUNC_MOD_EXPR && d < 0)
560             d = abs_d;
561           else if (abs_d == HOST_WIDE_INT_1U << (prec - 1))
562             {
563               /* This case is not handled correctly below.  */
564               mode = -2;
565               continue;
566             }
567           if (abs_d <= 1)
568             {
569               mode = -2;
570               continue;
571             }
572
573           choose_multiplier (abs_d, prec, prec - 1, &ml,
574                              &post_shift, &dummy_int);
575           if (ml >= HOST_WIDE_INT_1U << (prec - 1))
576             {
577               this_mode = 4 + (d < 0);
578               ml |= HOST_WIDE_INT_M1U << (prec - 1);
579             }
580           else
581             this_mode = 2 + (d < 0);
582         }
583       mulc[i] = ml;
584       post_shifts[i] = post_shift;
585       if ((i && !has_vector_shift && post_shifts[0] != post_shift)
586           || post_shift >= prec
587           || pre_shifts[i] >= prec)
588         this_mode = -2;
589
590       if (i == 0)
591         mode = this_mode;
592       else if (mode != this_mode)
593         mode = -2;
594     }
595
596   vec = XALLOCAVEC (tree, nunits);
597
598   if (use_pow2)
599     {
600       tree addend = NULL_TREE;
601       if (sign_p == SIGNED)
602         {
603           tree uns_type;
604
605           /* Both division and remainder sequences need
606              op0 < 0 ? mask : 0 computed.  It can be either computed as
607              (type) (((uns_type) (op0 >> (prec - 1))) >> (prec - shifts[i]))
608              if none of the shifts is 0, or as the conditional.  */
609           for (i = 0; i < nunits; i++)
610             if (shifts[i] == 0)
611               break;
612           uns_type
613             = build_vector_type (build_nonstandard_integer_type (prec, 1),
614                                  nunits);
615           if (i == nunits && TYPE_MODE (uns_type) == TYPE_MODE (type))
616             {
617               for (i = 0; i < nunits; i++)
618                 shift_temps[i] = prec - 1;
619               cur_op = add_rshift (gsi, type, op0, shift_temps);
620               if (cur_op != NULL_TREE)
621                 {
622                   cur_op = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
623                                             uns_type, cur_op);
624                   for (i = 0; i < nunits; i++)
625                     shift_temps[i] = prec - shifts[i];
626                   cur_op = add_rshift (gsi, uns_type, cur_op, shift_temps);
627                   if (cur_op != NULL_TREE)
628                     addend = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
629                                               type, cur_op);
630                 }
631             }
632           if (addend == NULL_TREE
633               && expand_vec_cond_expr_p (type, type, LT_EXPR))
634             {
635               tree zero, cst, cond, mask_type;
636               gimple *stmt;
637
638               mask_type = build_same_sized_truth_vector_type (type);
639               zero = build_zero_cst (type);
640               cond = build2 (LT_EXPR, mask_type, op0, zero);
641               for (i = 0; i < nunits; i++)
642                 vec[i] = build_int_cst (TREE_TYPE (type),
643                                         (HOST_WIDE_INT_1U
644                                          << shifts[i]) - 1);
645               cst = build_vector (type, vec);
646               addend = make_ssa_name (type);
647               stmt = gimple_build_assign (addend, VEC_COND_EXPR, cond,
648                                           cst, zero);
649               gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
650             }
651         }
652       if (code == TRUNC_DIV_EXPR)
653         {
654           if (sign_p == UNSIGNED)
655             {
656               /* q = op0 >> shift;  */
657               cur_op = add_rshift (gsi, type, op0, shifts);
658               if (cur_op != NULL_TREE)
659                 return cur_op;
660             }
661           else if (addend != NULL_TREE)
662             {
663               /* t1 = op0 + addend;
664                  q = t1 >> shift;  */
665               op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
666               if (op != unknown_optab
667                   && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
668                 {
669                   cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0, addend);
670                   cur_op = add_rshift (gsi, type, cur_op, shifts);
671                   if (cur_op != NULL_TREE)
672                     return cur_op;
673                 }
674             }
675         }
676       else
677         {
678           tree mask;
679           for (i = 0; i < nunits; i++)
680             vec[i] = build_int_cst (TREE_TYPE (type),
681                                     (HOST_WIDE_INT_1U
682                                      << shifts[i]) - 1);
683           mask = build_vector (type, vec);
684           op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default);
685           if (op != unknown_optab
686               && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
687             {
688               if (sign_p == UNSIGNED)
689                 /* r = op0 & mask;  */
690                 return gimplify_build2 (gsi, BIT_AND_EXPR, type, op0, mask);
691               else if (addend != NULL_TREE)
692                 {
693                   /* t1 = op0 + addend;
694                      t2 = t1 & mask;
695                      r = t2 - addend;  */
696                   op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
697                   if (op != unknown_optab
698                       && optab_handler (op, TYPE_MODE (type))
699                          != CODE_FOR_nothing)
700                     {
701                       cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0,
702                                                 addend);
703                       cur_op = gimplify_build2 (gsi, BIT_AND_EXPR, type,
704                                                 cur_op, mask);
705                       op = optab_for_tree_code (MINUS_EXPR, type,
706                                                 optab_default);
707                       if (op != unknown_optab
708                           && optab_handler (op, TYPE_MODE (type))
709                              != CODE_FOR_nothing)
710                         return gimplify_build2 (gsi, MINUS_EXPR, type,
711                                                 cur_op, addend);
712                     }
713                 }
714             }
715         }
716     }
717
718   if (mode == -2 || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
719     return NULL_TREE;
720
721   if (!can_mult_highpart_p (TYPE_MODE (type), TYPE_UNSIGNED (type)))
722     return NULL_TREE;
723
724   cur_op = op0;
725
726   switch (mode)
727     {
728     case 0:
729       gcc_assert (sign_p == UNSIGNED);
730       /* t1 = oprnd0 >> pre_shift;
731          t2 = t1 h* ml;
732          q = t2 >> post_shift;  */
733       cur_op = add_rshift (gsi, type, cur_op, pre_shifts);
734       if (cur_op == NULL_TREE)
735         return NULL_TREE;
736       break;
737     case 1:
738       gcc_assert (sign_p == UNSIGNED);
739       for (i = 0; i < nunits; i++)
740         {
741           shift_temps[i] = 1;
742           post_shifts[i]--;
743         }
744       break;
745     case 2:
746     case 3:
747     case 4:
748     case 5:
749       gcc_assert (sign_p == SIGNED);
750       for (i = 0; i < nunits; i++)
751         shift_temps[i] = prec - 1;
752       break;
753     default:
754       return NULL_TREE;
755     }
756
757   for (i = 0; i < nunits; i++)
758     vec[i] = build_int_cst (TREE_TYPE (type), mulc[i]);
759   mulcst = build_vector (type, vec);
760
761   cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst);
762
763   switch (mode)
764     {
765     case 0:
766       /* t1 = oprnd0 >> pre_shift;
767          t2 = t1 h* ml;
768          q = t2 >> post_shift;  */
769       cur_op = add_rshift (gsi, type, cur_op, post_shifts);
770       break;
771     case 1:
772       /* t1 = oprnd0 h* ml;
773          t2 = oprnd0 - t1;
774          t3 = t2 >> 1;
775          t4 = t1 + t3;
776          q = t4 >> (post_shift - 1);  */
777       op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
778       if (op == unknown_optab
779           || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
780         return NULL_TREE;
781       tem = gimplify_build2 (gsi, MINUS_EXPR, type, op0, cur_op);
782       tem = add_rshift (gsi, type, tem, shift_temps);
783       op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
784       if (op == unknown_optab
785           || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
786         return NULL_TREE;
787       tem = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, tem);
788       cur_op = add_rshift (gsi, type, tem, post_shifts);
789       if (cur_op == NULL_TREE)
790         return NULL_TREE;
791       break;
792     case 2:
793     case 3:
794     case 4:
795     case 5:
796       /* t1 = oprnd0 h* ml;
797          t2 = t1; [ iff (mode & 2) != 0 ]
798          t2 = t1 + oprnd0; [ iff (mode & 2) == 0 ]
799          t3 = t2 >> post_shift;
800          t4 = oprnd0 >> (prec - 1);
801          q = t3 - t4; [ iff (mode & 1) == 0 ]
802          q = t4 - t3; [ iff (mode & 1) != 0 ]  */
803       if ((mode & 2) == 0)
804         {
805           op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
806           if (op == unknown_optab
807               || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
808             return NULL_TREE;
809           cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, op0);
810         }
811       cur_op = add_rshift (gsi, type, cur_op, post_shifts);
812       if (cur_op == NULL_TREE)
813         return NULL_TREE;
814       tem = add_rshift (gsi, type, op0, shift_temps);
815       if (tem == NULL_TREE)
816         return NULL_TREE;
817       op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
818       if (op == unknown_optab
819           || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
820         return NULL_TREE;
821       if ((mode & 1) == 0)
822         cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, cur_op, tem);
823       else
824         cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, tem, cur_op);
825       break;
826     default:
827       gcc_unreachable ();
828     }
829
830   if (code == TRUNC_DIV_EXPR)
831     return cur_op;
832
833   /* We divided.  Now finish by:
834      t1 = q * oprnd1;
835      r = oprnd0 - t1;  */
836   op = optab_for_tree_code (MULT_EXPR, type, optab_default);
837   if (op == unknown_optab
838       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
839     return NULL_TREE;
840   tem = gimplify_build2 (gsi, MULT_EXPR, type, cur_op, op1);
841   op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
842   if (op == unknown_optab
843       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
844     return NULL_TREE;
845   return gimplify_build2 (gsi, MINUS_EXPR, type, op0, tem);
846 }
847
848 /* Expand a vector condition to scalars, by using many conditions
849    on the vector's elements.  */
850 static void
851 expand_vector_condition (gimple_stmt_iterator *gsi)
852 {
853   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
854   tree type = gimple_expr_type (stmt);
855   tree a = gimple_assign_rhs1 (stmt);
856   tree a1 = a;
857   tree a2 = NULL_TREE;
858   bool a_is_comparison = false;
859   tree b = gimple_assign_rhs2 (stmt);
860   tree c = gimple_assign_rhs3 (stmt);
861   vec<constructor_elt, va_gc> *v;
862   tree constr;
863   tree inner_type = TREE_TYPE (type);
864   tree cond_type = TREE_TYPE (TREE_TYPE (a));
865   tree comp_inner_type = cond_type;
866   tree width = TYPE_SIZE (inner_type);
867   tree index = bitsize_int (0);
868   tree comp_width = width;
869   tree comp_index = index;
870   int nunits = TYPE_VECTOR_SUBPARTS (type);
871   int i;
872   location_t loc = gimple_location (gsi_stmt (*gsi));
873
874   if (!is_gimple_val (a))
875     {
876       gcc_assert (COMPARISON_CLASS_P (a));
877       a_is_comparison = true;
878       a1 = TREE_OPERAND (a, 0);
879       a2 = TREE_OPERAND (a, 1);
880       comp_inner_type = TREE_TYPE (TREE_TYPE (a1));
881       comp_width = TYPE_SIZE (comp_inner_type);
882     }
883
884   if (expand_vec_cond_expr_p (type, TREE_TYPE (a1), TREE_CODE (a)))
885     return;
886
887   /* Handle vector boolean types with bitmasks.  If there is a comparison
888      and we can expand the comparison into the vector boolean bitmask,
889      or otherwise if it is compatible with type, we can transform
890       vbfld_1 = x_2 < y_3 ? vbfld_4 : vbfld_5;
891      into
892       tmp_6 = x_2 < y_3;
893       tmp_7 = tmp_6 & vbfld_4;
894       tmp_8 = ~tmp_6;
895       tmp_9 = tmp_8 & vbfld_5;
896       vbfld_1 = tmp_7 | tmp_9;
897      Similarly for vbfld_10 instead of x_2 < y_3.  */
898   if (VECTOR_BOOLEAN_TYPE_P (type)
899       && SCALAR_INT_MODE_P (TYPE_MODE (type))
900       && (GET_MODE_BITSIZE (TYPE_MODE (type))
901           < (TYPE_VECTOR_SUBPARTS (type)
902              * GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type)))))
903       && (a_is_comparison
904           ? useless_type_conversion_p (type, TREE_TYPE (a))
905           : expand_vec_cmp_expr_p (TREE_TYPE (a1), type, TREE_CODE (a))))
906     {
907       if (a_is_comparison)
908         a = gimplify_build2 (gsi, TREE_CODE (a), type, a1, a2);
909       a1 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a, b);
910       a2 = gimplify_build1 (gsi, BIT_NOT_EXPR, type, a);
911       a2 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a2, c);
912       a = gimplify_build2 (gsi, BIT_IOR_EXPR, type, a1, a2);
913       gimple_assign_set_rhs_from_tree (gsi, a);
914       update_stmt (gsi_stmt (*gsi));
915       return;
916     }
917
918   /* TODO: try and find a smaller vector type.  */
919
920   warning_at (loc, OPT_Wvector_operation_performance,
921               "vector condition will be expanded piecewise");
922
923   vec_alloc (v, nunits);
924   for (i = 0; i < nunits; i++)
925     {
926       tree aa, result;
927       tree bb = tree_vec_extract (gsi, inner_type, b, width, index);
928       tree cc = tree_vec_extract (gsi, inner_type, c, width, index);
929       if (a_is_comparison)
930         {
931           tree aa1 = tree_vec_extract (gsi, comp_inner_type, a1,
932                                        comp_width, comp_index);
933           tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2,
934                                        comp_width, comp_index);
935           aa = fold_build2 (TREE_CODE (a), cond_type, aa1, aa2);
936         }
937       else
938         aa = tree_vec_extract (gsi, cond_type, a, width, index);
939       result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
940       constructor_elt ce = {NULL_TREE, result};
941       v->quick_push (ce);
942       index = int_const_binop (PLUS_EXPR, index, width);
943       if (width == comp_width)
944         comp_index = index;
945       else
946         comp_index = int_const_binop (PLUS_EXPR, comp_index, comp_width);
947     }
948
949   constr = build_constructor (type, v);
950   gimple_assign_set_rhs_from_tree (gsi, constr);
951   update_stmt (gsi_stmt (*gsi));
952 }
953
954 static tree
955 expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
956                          gassign *assign, enum tree_code code)
957 {
958   machine_mode compute_mode = TYPE_MODE (compute_type);
959
960   /* If the compute mode is not a vector mode (hence we are not decomposing
961      a BLKmode vector to smaller, hardware-supported vectors), we may want
962      to expand the operations in parallel.  */
963   if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
964       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT
965       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT
966       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT
967       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM
968       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM)
969     switch (code)
970       {
971       case PLUS_EXPR:
972       case MINUS_EXPR:
973         if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
974           return expand_vector_addition (gsi, do_binop, do_plus_minus, type,
975                                          gimple_assign_rhs1 (assign),
976                                          gimple_assign_rhs2 (assign), code);
977         break;
978
979       case NEGATE_EXPR:
980         if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
981           return expand_vector_addition (gsi, do_unop, do_negate, type,
982                                          gimple_assign_rhs1 (assign),
983                                          NULL_TREE, code);
984         break;
985
986       case BIT_AND_EXPR:
987       case BIT_IOR_EXPR:
988       case BIT_XOR_EXPR:
989         return expand_vector_parallel (gsi, do_binop, type,
990                                        gimple_assign_rhs1 (assign),
991                                        gimple_assign_rhs2 (assign), code);
992
993       case BIT_NOT_EXPR:
994         return expand_vector_parallel (gsi, do_unop, type,
995                                        gimple_assign_rhs1 (assign),
996                                        NULL_TREE, code);
997       case EQ_EXPR:
998       case NE_EXPR:
999       case GT_EXPR:
1000       case LT_EXPR:
1001       case GE_EXPR:
1002       case LE_EXPR:
1003       case UNEQ_EXPR:
1004       case UNGT_EXPR:
1005       case UNLT_EXPR:
1006       case UNGE_EXPR:
1007       case UNLE_EXPR:
1008       case LTGT_EXPR:
1009       case ORDERED_EXPR:
1010       case UNORDERED_EXPR:
1011         {
1012           tree rhs1 = gimple_assign_rhs1 (assign);
1013           tree rhs2 = gimple_assign_rhs2 (assign);
1014
1015           return expand_vector_comparison (gsi, type, rhs1, rhs2, code);
1016         }
1017
1018       case TRUNC_DIV_EXPR:
1019       case TRUNC_MOD_EXPR:
1020         {
1021           tree rhs1 = gimple_assign_rhs1 (assign);
1022           tree rhs2 = gimple_assign_rhs2 (assign);
1023           tree ret;
1024
1025           if (!optimize
1026               || !VECTOR_INTEGER_TYPE_P (type)
1027               || TREE_CODE (rhs2) != VECTOR_CST
1028               || !VECTOR_MODE_P (TYPE_MODE (type)))
1029             break;
1030
1031           ret = expand_vector_divmod (gsi, type, rhs1, rhs2, code);
1032           if (ret != NULL_TREE)
1033             return ret;
1034           break;
1035         }
1036
1037       default:
1038         break;
1039       }
1040
1041   if (TREE_CODE_CLASS (code) == tcc_unary)
1042     return expand_vector_piecewise (gsi, do_unop, type, compute_type,
1043                                     gimple_assign_rhs1 (assign),
1044                                     NULL_TREE, code);
1045   else
1046     return expand_vector_piecewise (gsi, do_binop, type, compute_type,
1047                                     gimple_assign_rhs1 (assign),
1048                                     gimple_assign_rhs2 (assign), code);
1049 }
1050
1051 /* Try to optimize
1052    a_5 = { b_7, b_7 + 3, b_7 + 6, b_7 + 9 };
1053    style stmts into:
1054    _9 = { b_7, b_7, b_7, b_7 };
1055    a_5 = _9 + { 0, 3, 6, 9 };
1056    because vector splat operation is usually more efficient
1057    than piecewise initialization of the vector.  */
1058
1059 static void
1060 optimize_vector_constructor (gimple_stmt_iterator *gsi)
1061 {
1062   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1063   tree lhs = gimple_assign_lhs (stmt);
1064   tree rhs = gimple_assign_rhs1 (stmt);
1065   tree type = TREE_TYPE (rhs);
1066   unsigned int i, j, nelts = TYPE_VECTOR_SUBPARTS (type);
1067   bool all_same = true;
1068   constructor_elt *elt;
1069   tree *cst;
1070   gimple *g;
1071   tree base = NULL_TREE;
1072   optab op;
1073
1074   if (nelts <= 2 || CONSTRUCTOR_NELTS (rhs) != nelts)
1075     return;
1076   op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
1077   if (op == unknown_optab
1078       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
1079     return;
1080   FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs), i, elt)
1081     if (TREE_CODE (elt->value) != SSA_NAME
1082         || TREE_CODE (TREE_TYPE (elt->value)) == VECTOR_TYPE)
1083       return;
1084     else
1085       {
1086         tree this_base = elt->value;
1087         if (this_base != CONSTRUCTOR_ELT (rhs, 0)->value)
1088           all_same = false;
1089         for (j = 0; j < nelts + 1; j++)
1090           {
1091             g = SSA_NAME_DEF_STMT (this_base);
1092             if (is_gimple_assign (g)
1093                 && gimple_assign_rhs_code (g) == PLUS_EXPR
1094                 && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST
1095                 && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
1096                 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
1097               this_base = gimple_assign_rhs1 (g);
1098             else
1099               break;
1100           }
1101         if (i == 0)
1102           base = this_base;
1103         else if (this_base != base)
1104           return;
1105       }
1106   if (all_same)
1107     return;
1108   cst = XALLOCAVEC (tree, nelts);
1109   for (i = 0; i < nelts; i++)
1110     {
1111       tree this_base = CONSTRUCTOR_ELT (rhs, i)->value;;
1112       cst[i] = build_zero_cst (TREE_TYPE (base));
1113       while (this_base != base)
1114         {
1115           g = SSA_NAME_DEF_STMT (this_base);
1116           cst[i] = fold_binary (PLUS_EXPR, TREE_TYPE (base),
1117                                 cst[i], gimple_assign_rhs2 (g));
1118           if (cst[i] == NULL_TREE
1119               || TREE_CODE (cst[i]) != INTEGER_CST
1120               || TREE_OVERFLOW (cst[i]))
1121             return;
1122           this_base = gimple_assign_rhs1 (g);
1123         }
1124     }
1125   for (i = 0; i < nelts; i++)
1126     CONSTRUCTOR_ELT (rhs, i)->value = base;
1127   g = gimple_build_assign (make_ssa_name (type), rhs);
1128   gsi_insert_before (gsi, g, GSI_SAME_STMT);
1129   g = gimple_build_assign (lhs, PLUS_EXPR, gimple_assign_lhs (g),
1130                            build_vector (type, cst));
1131   gsi_replace (gsi, g, false);
1132 }
1133 \f
1134 /* Return a type for the widest vector mode whose components are of type
1135    TYPE, or NULL_TREE if none is found.  */
1136
1137 static tree
1138 type_for_widest_vector_mode (tree type, optab op)
1139 {
1140   machine_mode inner_mode = TYPE_MODE (type);
1141   machine_mode best_mode = VOIDmode, mode;
1142   int best_nunits = 0;
1143
1144   if (SCALAR_FLOAT_MODE_P (inner_mode))
1145     mode = MIN_MODE_VECTOR_FLOAT;
1146   else if (SCALAR_FRACT_MODE_P (inner_mode))
1147     mode = MIN_MODE_VECTOR_FRACT;
1148   else if (SCALAR_UFRACT_MODE_P (inner_mode))
1149     mode = MIN_MODE_VECTOR_UFRACT;
1150   else if (SCALAR_ACCUM_MODE_P (inner_mode))
1151     mode = MIN_MODE_VECTOR_ACCUM;
1152   else if (SCALAR_UACCUM_MODE_P (inner_mode))
1153     mode = MIN_MODE_VECTOR_UACCUM;
1154   else
1155     mode = MIN_MODE_VECTOR_INT;
1156
1157   FOR_EACH_MODE_FROM (mode, mode)
1158     if (GET_MODE_INNER (mode) == inner_mode
1159         && GET_MODE_NUNITS (mode) > best_nunits
1160         && optab_handler (op, mode) != CODE_FOR_nothing)
1161       best_mode = mode, best_nunits = GET_MODE_NUNITS (mode);
1162
1163   if (best_mode == VOIDmode)
1164     return NULL_TREE;
1165   else
1166     return build_vector_type_for_mode (type, best_mode);
1167 }
1168
1169
1170 /* Build a reference to the element of the vector VECT.  Function
1171    returns either the element itself, either BIT_FIELD_REF, or an
1172    ARRAY_REF expression.
1173
1174    GSI is required to insert temporary variables while building a
1175    refernece to the element of the vector VECT.
1176
1177    PTMPVEC is a pointer to the temporary variable for caching
1178    purposes.  In case when PTMPVEC is NULL new temporary variable
1179    will be created.  */
1180 static tree
1181 vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec)
1182 {
1183   tree vect_type, vect_elt_type;
1184   gimple *asgn;
1185   tree tmpvec;
1186   tree arraytype;
1187   bool need_asgn = true;
1188   unsigned int elements;
1189
1190   vect_type = TREE_TYPE (vect);
1191   vect_elt_type = TREE_TYPE (vect_type);
1192   elements = TYPE_VECTOR_SUBPARTS (vect_type);
1193
1194   if (TREE_CODE (idx) == INTEGER_CST)
1195     {
1196       unsigned HOST_WIDE_INT index;
1197
1198       /* Given that we're about to compute a binary modulus,
1199          we don't care about the high bits of the value.  */
1200       index = TREE_INT_CST_LOW (idx);
1201       if (!tree_fits_uhwi_p (idx) || index >= elements)
1202         {
1203           index &= elements - 1;
1204           idx = build_int_cst (TREE_TYPE (idx), index);
1205         }
1206
1207       /* When lowering a vector statement sequence do some easy
1208          simplification by looking through intermediate vector results.  */
1209       if (TREE_CODE (vect) == SSA_NAME)
1210         {
1211           gimple *def_stmt = SSA_NAME_DEF_STMT (vect);
1212           if (is_gimple_assign (def_stmt)
1213               && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST
1214                   || gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR))
1215             vect = gimple_assign_rhs1 (def_stmt);
1216         }
1217
1218       if (TREE_CODE (vect) == VECTOR_CST)
1219         return VECTOR_CST_ELT (vect, index);
1220       else if (TREE_CODE (vect) == CONSTRUCTOR
1221                && (CONSTRUCTOR_NELTS (vect) == 0
1222                    || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect, 0)->value))
1223                       != VECTOR_TYPE))
1224         {
1225           if (index < CONSTRUCTOR_NELTS (vect))
1226             return CONSTRUCTOR_ELT (vect, index)->value;
1227           return build_zero_cst (vect_elt_type);
1228         }
1229       else
1230         {
1231           tree size = TYPE_SIZE (vect_elt_type);
1232           tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (index),
1233                                   size);
1234           return fold_build3 (BIT_FIELD_REF, vect_elt_type, vect, size, pos);
1235         }
1236     }
1237
1238   if (!ptmpvec)
1239     tmpvec = create_tmp_var (vect_type, "vectmp");
1240   else if (!*ptmpvec)
1241     tmpvec = *ptmpvec = create_tmp_var (vect_type, "vectmp");
1242   else
1243     {
1244       tmpvec = *ptmpvec;
1245       need_asgn = false;
1246     }
1247
1248   if (need_asgn)
1249     {
1250       TREE_ADDRESSABLE (tmpvec) = 1;
1251       asgn = gimple_build_assign (tmpvec, vect);
1252       gsi_insert_before (gsi, asgn, GSI_SAME_STMT);
1253     }
1254
1255   arraytype = build_array_type_nelts (vect_elt_type, elements);
1256   return build4 (ARRAY_REF, vect_elt_type,
1257                  build1 (VIEW_CONVERT_EXPR, arraytype, tmpvec),
1258                  idx, NULL_TREE, NULL_TREE);
1259 }
1260
1261 /* Check if VEC_PERM_EXPR within the given setting is supported
1262    by hardware, or lower it piecewise.
1263
1264    When VEC_PERM_EXPR has the same first and second operands:
1265    VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
1266    {v0[mask[0]], v0[mask[1]], ...}
1267    MASK and V0 must have the same number of elements.
1268
1269    Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
1270    {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
1271    V0 and V1 must have the same type.  MASK, V0, V1 must have the
1272    same number of arguments.  */
1273
1274 static void
1275 lower_vec_perm (gimple_stmt_iterator *gsi)
1276 {
1277   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1278   tree mask = gimple_assign_rhs3 (stmt);
1279   tree vec0 = gimple_assign_rhs1 (stmt);
1280   tree vec1 = gimple_assign_rhs2 (stmt);
1281   tree vect_type = TREE_TYPE (vec0);
1282   tree mask_type = TREE_TYPE (mask);
1283   tree vect_elt_type = TREE_TYPE (vect_type);
1284   tree mask_elt_type = TREE_TYPE (mask_type);
1285   unsigned int elements = TYPE_VECTOR_SUBPARTS (vect_type);
1286   vec<constructor_elt, va_gc> *v;
1287   tree constr, t, si, i_val;
1288   tree vec0tmp = NULL_TREE, vec1tmp = NULL_TREE, masktmp = NULL_TREE;
1289   bool two_operand_p = !operand_equal_p (vec0, vec1, 0);
1290   location_t loc = gimple_location (gsi_stmt (*gsi));
1291   unsigned i;
1292
1293   if (TREE_CODE (mask) == SSA_NAME)
1294     {
1295       gimple *def_stmt = SSA_NAME_DEF_STMT (mask);
1296       if (is_gimple_assign (def_stmt)
1297           && gimple_assign_rhs_code (def_stmt) == VECTOR_CST)
1298         mask = gimple_assign_rhs1 (def_stmt);
1299     }
1300
1301   if (TREE_CODE (mask) == VECTOR_CST)
1302     {
1303       unsigned char *sel_int = XALLOCAVEC (unsigned char, elements);
1304
1305       for (i = 0; i < elements; ++i)
1306         sel_int[i] = (TREE_INT_CST_LOW (VECTOR_CST_ELT (mask, i))
1307                       & (2 * elements - 1));
1308
1309       if (can_vec_perm_p (TYPE_MODE (vect_type), false, sel_int))
1310         {
1311           gimple_assign_set_rhs3 (stmt, mask);
1312           update_stmt (stmt);
1313           return;
1314         }
1315       /* Also detect vec_shr pattern - VEC_PERM_EXPR with zero
1316          vector as VEC1 and a right element shift MASK.  */
1317       if (optab_handler (vec_shr_optab, TYPE_MODE (vect_type))
1318           != CODE_FOR_nothing
1319           && TREE_CODE (vec1) == VECTOR_CST
1320           && initializer_zerop (vec1)
1321           && sel_int[0]
1322           && sel_int[0] < elements)
1323         {
1324           for (i = 1; i < elements; ++i)
1325             {
1326               unsigned int expected = i + sel_int[0];
1327               /* Indices into the second vector are all equivalent.  */
1328               if (MIN (elements, (unsigned) sel_int[i])
1329                   != MIN (elements, expected))
1330                 break;
1331             }
1332           if (i == elements)
1333             {
1334               gimple_assign_set_rhs3 (stmt, mask);
1335               update_stmt (stmt);
1336               return;
1337             }
1338         }
1339     }
1340   else if (can_vec_perm_p (TYPE_MODE (vect_type), true, NULL))
1341     return;
1342   
1343   warning_at (loc, OPT_Wvector_operation_performance,
1344               "vector shuffling operation will be expanded piecewise");
1345
1346   vec_alloc (v, elements);
1347   for (i = 0; i < elements; i++)
1348     {
1349       si = size_int (i);
1350       i_val = vector_element (gsi, mask, si, &masktmp);
1351
1352       if (TREE_CODE (i_val) == INTEGER_CST)
1353         {
1354           unsigned HOST_WIDE_INT index;
1355
1356           index = TREE_INT_CST_LOW (i_val);
1357           if (!tree_fits_uhwi_p (i_val) || index >= elements)
1358             i_val = build_int_cst (mask_elt_type, index & (elements - 1));
1359
1360           if (two_operand_p && (index & elements) != 0)
1361             t = vector_element (gsi, vec1, i_val, &vec1tmp);
1362           else
1363             t = vector_element (gsi, vec0, i_val, &vec0tmp);
1364
1365           t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE,
1366                                         true, GSI_SAME_STMT);
1367         }
1368       else
1369         {
1370           tree cond = NULL_TREE, v0_val;
1371
1372           if (two_operand_p)
1373             {
1374               cond = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,
1375                                   build_int_cst (mask_elt_type, elements));
1376               cond = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE,
1377                                                true, GSI_SAME_STMT);
1378             }
1379
1380           i_val = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,
1381                                build_int_cst (mask_elt_type, elements - 1));
1382           i_val = force_gimple_operand_gsi (gsi, i_val, true, NULL_TREE,
1383                                             true, GSI_SAME_STMT);
1384
1385           v0_val = vector_element (gsi, vec0, i_val, &vec0tmp);
1386           v0_val = force_gimple_operand_gsi (gsi, v0_val, true, NULL_TREE,
1387                                              true, GSI_SAME_STMT);
1388
1389           if (two_operand_p)
1390             {
1391               tree v1_val;
1392
1393               v1_val = vector_element (gsi, vec1, i_val, &vec1tmp);
1394               v1_val = force_gimple_operand_gsi (gsi, v1_val, true, NULL_TREE,
1395                                                  true, GSI_SAME_STMT);
1396
1397               cond = fold_build2 (EQ_EXPR, boolean_type_node,
1398                                   cond, build_zero_cst (mask_elt_type));
1399               cond = fold_build3 (COND_EXPR, vect_elt_type,
1400                                   cond, v0_val, v1_val);
1401               t = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE,
1402                                             true, GSI_SAME_STMT);
1403             }
1404           else
1405             t = v0_val;
1406         }
1407
1408       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
1409     }
1410
1411   constr = build_constructor (vect_type, v);
1412   gimple_assign_set_rhs_from_tree (gsi, constr);
1413   update_stmt (gsi_stmt (*gsi));
1414 }
1415
1416 /* If OP is a uniform vector return the element it is a splat from.  */
1417
1418 static tree
1419 ssa_uniform_vector_p (tree op)
1420 {
1421   if (TREE_CODE (op) == VECTOR_CST
1422       || TREE_CODE (op) == CONSTRUCTOR)
1423     return uniform_vector_p (op);
1424   if (TREE_CODE (op) == SSA_NAME)
1425     {
1426       gimple *def_stmt = SSA_NAME_DEF_STMT (op);
1427       if (gimple_assign_single_p (def_stmt))
1428         return uniform_vector_p (gimple_assign_rhs1 (def_stmt));
1429     }
1430   return NULL_TREE;
1431 }
1432
1433 /* Return type in which CODE operation with optab OP can be
1434    computed.  */
1435
1436 static tree
1437 get_compute_type (enum tree_code code, optab op, tree type)
1438 {
1439   /* For very wide vectors, try using a smaller vector mode.  */
1440   tree compute_type = type;
1441   if (op
1442       && (!VECTOR_MODE_P (TYPE_MODE (type))
1443           || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing))
1444     {
1445       tree vector_compute_type
1446         = type_for_widest_vector_mode (TREE_TYPE (type), op);
1447       if (vector_compute_type != NULL_TREE
1448           && (TYPE_VECTOR_SUBPARTS (vector_compute_type)
1449               < TYPE_VECTOR_SUBPARTS (compute_type))
1450           && TYPE_VECTOR_SUBPARTS (vector_compute_type) > 1
1451           && (optab_handler (op, TYPE_MODE (vector_compute_type))
1452               != CODE_FOR_nothing))
1453         compute_type = vector_compute_type;
1454     }
1455
1456   /* If we are breaking a BLKmode vector into smaller pieces,
1457      type_for_widest_vector_mode has already looked into the optab,
1458      so skip these checks.  */
1459   if (compute_type == type)
1460     {
1461       machine_mode compute_mode = TYPE_MODE (compute_type);
1462       if (VECTOR_MODE_P (compute_mode))
1463         {
1464           if (op && optab_handler (op, compute_mode) != CODE_FOR_nothing)
1465             return compute_type;
1466           if (code == MULT_HIGHPART_EXPR
1467               && can_mult_highpart_p (compute_mode,
1468                                       TYPE_UNSIGNED (compute_type)))
1469             return compute_type;
1470         }
1471       /* There is no operation in hardware, so fall back to scalars.  */
1472       compute_type = TREE_TYPE (type);
1473     }
1474
1475   return compute_type;
1476 }
1477
1478 /* Helper function of expand_vector_operations_1.  Return number of
1479    vector elements for vector types or 1 for other types.  */
1480
1481 static inline int
1482 count_type_subparts (tree type)
1483 {
1484   return VECTOR_TYPE_P (type) ? TYPE_VECTOR_SUBPARTS (type) : 1;
1485 }
1486
1487 static tree
1488 do_cond (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
1489          tree bitpos, tree bitsize, enum tree_code code,
1490          tree type ATTRIBUTE_UNUSED)
1491 {
1492   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
1493     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
1494   if (TREE_CODE (TREE_TYPE (b)) == VECTOR_TYPE)
1495     b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
1496   tree cond = gimple_assign_rhs1 (gsi_stmt (*gsi));
1497   return gimplify_build3 (gsi, code, inner_type, unshare_expr (cond), a, b);
1498 }
1499
1500 /* Expand a vector COND_EXPR to scalars, piecewise.  */
1501 static void
1502 expand_vector_scalar_condition (gimple_stmt_iterator *gsi)
1503 {
1504   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
1505   tree type = gimple_expr_type (stmt);
1506   tree compute_type = get_compute_type (COND_EXPR, mov_optab, type);
1507   machine_mode compute_mode = TYPE_MODE (compute_type);
1508   gcc_assert (compute_mode != BLKmode);
1509   tree lhs = gimple_assign_lhs (stmt);
1510   tree rhs2 = gimple_assign_rhs2 (stmt);
1511   tree rhs3 = gimple_assign_rhs3 (stmt);
1512   tree new_rhs;
1513
1514   /* If the compute mode is not a vector mode (hence we are not decomposing
1515      a BLKmode vector to smaller, hardware-supported vectors), we may want
1516      to expand the operations in parallel.  */
1517   if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
1518       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT
1519       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT
1520       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT
1521       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM
1522       && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM)
1523     new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3,
1524                                       COND_EXPR);
1525   else
1526     new_rhs = expand_vector_piecewise (gsi, do_cond, type, compute_type,
1527                                        rhs2, rhs3, COND_EXPR);
1528   if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
1529     new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
1530                                new_rhs);
1531
1532   /* NOTE:  We should avoid using gimple_assign_set_rhs_from_tree. One
1533      way to do it is change expand_vector_operation and its callees to
1534      return a tree_code, RHS1 and RHS2 instead of a tree. */
1535   gimple_assign_set_rhs_from_tree (gsi, new_rhs);
1536   update_stmt (gsi_stmt (*gsi));
1537 }
1538
1539 /* Process one statement.  If we identify a vector operation, expand it.  */
1540
1541 static void
1542 expand_vector_operations_1 (gimple_stmt_iterator *gsi)
1543 {
1544   tree lhs, rhs1, rhs2 = NULL, type, compute_type = NULL_TREE;
1545   enum tree_code code;
1546   optab op = unknown_optab;
1547   enum gimple_rhs_class rhs_class;
1548   tree new_rhs;
1549
1550   /* Only consider code == GIMPLE_ASSIGN. */
1551   gassign *stmt = dyn_cast <gassign *> (gsi_stmt (*gsi));
1552   if (!stmt)
1553     return;
1554
1555   code = gimple_assign_rhs_code (stmt);
1556   rhs_class = get_gimple_rhs_class (code);
1557   lhs = gimple_assign_lhs (stmt);
1558
1559   if (code == VEC_PERM_EXPR)
1560     {
1561       lower_vec_perm (gsi);
1562       return;
1563     }
1564
1565   if (code == VEC_COND_EXPR)
1566     {
1567       expand_vector_condition (gsi);
1568       return;
1569     }
1570
1571   if (code == COND_EXPR
1572       && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt))) == VECTOR_TYPE
1573       && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode)
1574     {
1575       expand_vector_scalar_condition (gsi);
1576       return;
1577     }
1578
1579   if (code == CONSTRUCTOR
1580       && TREE_CODE (lhs) == SSA_NAME
1581       && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))
1582       && !gimple_clobber_p (stmt)
1583       && optimize)
1584     {
1585       optimize_vector_constructor (gsi);
1586       return;
1587     }
1588
1589   if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
1590     return;
1591
1592   rhs1 = gimple_assign_rhs1 (stmt);
1593   type = gimple_expr_type (stmt);
1594   if (rhs_class == GIMPLE_BINARY_RHS)
1595     rhs2 = gimple_assign_rhs2 (stmt);
1596
1597   if (TREE_CODE (type) != VECTOR_TYPE)
1598     return;
1599
1600   /* If the vector operation is operating on all same vector elements
1601      implement it with a scalar operation and a splat if the target
1602      supports the scalar operation.  */
1603   tree srhs1, srhs2 = NULL_TREE;
1604   if ((srhs1 = ssa_uniform_vector_p (rhs1)) != NULL_TREE
1605       && (rhs2 == NULL_TREE
1606           || (! VECTOR_TYPE_P (TREE_TYPE (rhs2))
1607               && (srhs2 = rhs2))
1608           || (srhs2 = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
1609       /* As we query direct optabs restrict to non-convert operations.  */
1610       && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (TREE_TYPE (srhs1)))
1611     {
1612       op = optab_for_tree_code (code, TREE_TYPE (type), optab_scalar);
1613       if (op >= FIRST_NORM_OPTAB && op <= LAST_NORM_OPTAB
1614           && optab_handler (op, TYPE_MODE (TREE_TYPE (type))) != CODE_FOR_nothing)
1615         {
1616           tree slhs = make_ssa_name (TREE_TYPE (srhs1));
1617           gimple *repl = gimple_build_assign (slhs, code, srhs1, srhs2);
1618           gsi_insert_before (gsi, repl, GSI_SAME_STMT);
1619           gimple_assign_set_rhs_from_tree (gsi,
1620                                            build_vector_from_val (type, slhs));
1621           update_stmt (stmt);
1622           return;
1623         }
1624     }
1625  
1626   /* A scalar operation pretending to be a vector one.  */
1627   if (VECTOR_BOOLEAN_TYPE_P (type)
1628       && !VECTOR_MODE_P (TYPE_MODE (type))
1629       && TYPE_MODE (type) != BLKmode)
1630     return;
1631
1632   if (CONVERT_EXPR_CODE_P (code)
1633       || code == FLOAT_EXPR
1634       || code == FIX_TRUNC_EXPR
1635       || code == VIEW_CONVERT_EXPR)
1636     return;
1637
1638   /* The signedness is determined from input argument.  */
1639   if (code == VEC_UNPACK_FLOAT_HI_EXPR
1640       || code == VEC_UNPACK_FLOAT_LO_EXPR)
1641     {
1642       type = TREE_TYPE (rhs1);
1643       /* We do not know how to scalarize those.  */
1644       return;
1645     }
1646
1647   /* For widening/narrowing vector operations, the relevant type is of the
1648      arguments, not the widened result.  VEC_UNPACK_FLOAT_*_EXPR is
1649      calculated in the same way above.  */
1650   if (code == WIDEN_SUM_EXPR
1651       || code == VEC_WIDEN_MULT_HI_EXPR
1652       || code == VEC_WIDEN_MULT_LO_EXPR
1653       || code == VEC_WIDEN_MULT_EVEN_EXPR
1654       || code == VEC_WIDEN_MULT_ODD_EXPR
1655       || code == VEC_UNPACK_HI_EXPR
1656       || code == VEC_UNPACK_LO_EXPR
1657       || code == VEC_PACK_TRUNC_EXPR
1658       || code == VEC_PACK_SAT_EXPR
1659       || code == VEC_PACK_FIX_TRUNC_EXPR
1660       || code == VEC_WIDEN_LSHIFT_HI_EXPR
1661       || code == VEC_WIDEN_LSHIFT_LO_EXPR)
1662     {
1663       type = TREE_TYPE (rhs1);
1664       /* We do not know how to scalarize those.  */
1665       return;
1666     }
1667
1668   /* Choose between vector shift/rotate by vector and vector shift/rotate by
1669      scalar */
1670   if (code == LSHIFT_EXPR
1671       || code == RSHIFT_EXPR
1672       || code == LROTATE_EXPR
1673       || code == RROTATE_EXPR)
1674     {
1675       optab opv;
1676
1677       /* Check whether we have vector <op> {x,x,x,x} where x
1678          could be a scalar variable or a constant.  Transform
1679          vector <op> {x,x,x,x} ==> vector <op> scalar.  */
1680       if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
1681         {
1682           tree first;
1683
1684           if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
1685             {
1686               gimple_assign_set_rhs2 (stmt, first);
1687               update_stmt (stmt);
1688               rhs2 = first;
1689             }
1690         }
1691
1692       opv = optab_for_tree_code (code, type, optab_vector);
1693       if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
1694         op = opv;
1695       else
1696         {
1697           op = optab_for_tree_code (code, type, optab_scalar);
1698
1699           compute_type = get_compute_type (code, op, type);
1700           if (compute_type == type)
1701             return;
1702           /* The rtl expander will expand vector/scalar as vector/vector
1703              if necessary.  Pick one with wider vector type.  */
1704           tree compute_vtype = get_compute_type (code, opv, type);
1705           if (count_type_subparts (compute_vtype)
1706               > count_type_subparts (compute_type))
1707             {
1708               compute_type = compute_vtype;
1709               op = opv;
1710             }
1711         }
1712
1713       if (code == LROTATE_EXPR || code == RROTATE_EXPR)
1714         {
1715           if (compute_type == NULL_TREE)
1716             compute_type = get_compute_type (code, op, type);
1717           if (compute_type == type)
1718             return;
1719           /* Before splitting vector rotates into scalar rotates,
1720              see if we can't use vector shifts and BIT_IOR_EXPR
1721              instead.  For vector by vector rotates we'd also
1722              need to check BIT_AND_EXPR and NEGATE_EXPR, punt there
1723              for now, fold doesn't seem to create such rotates anyway.  */
1724           if (compute_type == TREE_TYPE (type)
1725               && !VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
1726             {
1727               optab oplv = vashl_optab, opl = ashl_optab;
1728               optab oprv = vlshr_optab, opr = lshr_optab, opo = ior_optab;
1729               tree compute_lvtype = get_compute_type (LSHIFT_EXPR, oplv, type);
1730               tree compute_rvtype = get_compute_type (RSHIFT_EXPR, oprv, type);
1731               tree compute_otype = get_compute_type (BIT_IOR_EXPR, opo, type);
1732               tree compute_ltype = get_compute_type (LSHIFT_EXPR, opl, type);
1733               tree compute_rtype = get_compute_type (RSHIFT_EXPR, opr, type);
1734               /* The rtl expander will expand vector/scalar as vector/vector
1735                  if necessary.  Pick one with wider vector type.  */
1736               if (count_type_subparts (compute_lvtype)
1737                   > count_type_subparts (compute_ltype))
1738                 {
1739                   compute_ltype = compute_lvtype;
1740                   opl = oplv;
1741                 }
1742               if (count_type_subparts (compute_rvtype)
1743                   > count_type_subparts (compute_rtype))
1744                 {
1745                   compute_rtype = compute_rvtype;
1746                   opr = oprv;
1747                 }
1748               /* Pick the narrowest type from LSHIFT_EXPR, RSHIFT_EXPR and
1749                  BIT_IOR_EXPR.  */
1750               compute_type = compute_ltype;
1751               if (count_type_subparts (compute_type)
1752                   > count_type_subparts (compute_rtype))
1753                 compute_type = compute_rtype;
1754               if (count_type_subparts (compute_type)
1755                   > count_type_subparts (compute_otype))
1756                 compute_type = compute_otype;
1757               /* Verify all 3 operations can be performed in that type.  */
1758               if (compute_type != TREE_TYPE (type))
1759                 {
1760                   if (optab_handler (opl, TYPE_MODE (compute_type))
1761                       == CODE_FOR_nothing
1762                       || optab_handler (opr, TYPE_MODE (compute_type))
1763                          == CODE_FOR_nothing
1764                       || optab_handler (opo, TYPE_MODE (compute_type))
1765                          == CODE_FOR_nothing)
1766                     compute_type = TREE_TYPE (type);
1767                 }
1768             }
1769         }
1770     }
1771   else
1772     op = optab_for_tree_code (code, type, optab_default);
1773
1774   /* Optabs will try converting a negation into a subtraction, so
1775      look for it as well.  TODO: negation of floating-point vectors
1776      might be turned into an exclusive OR toggling the sign bit.  */
1777   if (op == unknown_optab
1778       && code == NEGATE_EXPR
1779       && INTEGRAL_TYPE_P (TREE_TYPE (type)))
1780     op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
1781
1782   if (compute_type == NULL_TREE)
1783     compute_type = get_compute_type (code, op, type);
1784   if (compute_type == type)
1785     return;
1786
1787   new_rhs = expand_vector_operation (gsi, type, compute_type, stmt, code);
1788
1789   /* Leave expression untouched for later expansion.  */
1790   if (new_rhs == NULL_TREE)
1791     return;
1792
1793   if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
1794     new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
1795                                new_rhs);
1796
1797   /* NOTE:  We should avoid using gimple_assign_set_rhs_from_tree. One
1798      way to do it is change expand_vector_operation and its callees to
1799      return a tree_code, RHS1 and RHS2 instead of a tree. */
1800   gimple_assign_set_rhs_from_tree (gsi, new_rhs);
1801   update_stmt (gsi_stmt (*gsi));
1802 }
1803 \f
1804 /* Use this to lower vector operations introduced by the vectorizer,
1805    if it may need the bit-twiddling tricks implemented in this file.  */
1806
1807 static unsigned int
1808 expand_vector_operations (void)
1809 {
1810   gimple_stmt_iterator gsi;
1811   basic_block bb;
1812   bool cfg_changed = false;
1813
1814   FOR_EACH_BB_FN (bb, cfun)
1815     {
1816       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1817         {
1818           expand_vector_operations_1 (&gsi);
1819           /* ???  If we do not cleanup EH then we will ICE in
1820              verification.  But in reality we have created wrong-code
1821              as we did not properly transition EH info and edges to
1822              the piecewise computations.  */
1823           if (maybe_clean_eh_stmt (gsi_stmt (gsi))
1824               && gimple_purge_dead_eh_edges (bb))
1825             cfg_changed = true;
1826         }
1827     }
1828
1829   return cfg_changed ? TODO_cleanup_cfg : 0;
1830 }
1831
1832 namespace {
1833
1834 const pass_data pass_data_lower_vector =
1835 {
1836   GIMPLE_PASS, /* type */
1837   "veclower", /* name */
1838   OPTGROUP_VEC, /* optinfo_flags */
1839   TV_NONE, /* tv_id */
1840   PROP_cfg, /* properties_required */
1841   PROP_gimple_lvec, /* properties_provided */
1842   0, /* properties_destroyed */
1843   0, /* todo_flags_start */
1844   TODO_update_ssa, /* todo_flags_finish */
1845 };
1846
1847 class pass_lower_vector : public gimple_opt_pass
1848 {
1849 public:
1850   pass_lower_vector (gcc::context *ctxt)
1851     : gimple_opt_pass (pass_data_lower_vector, ctxt)
1852   {}
1853
1854   /* opt_pass methods: */
1855   virtual bool gate (function *fun)
1856     {
1857       return !(fun->curr_properties & PROP_gimple_lvec);
1858     }
1859
1860   virtual unsigned int execute (function *)
1861     {
1862       return expand_vector_operations ();
1863     }
1864
1865 }; // class pass_lower_vector
1866
1867 } // anon namespace
1868
1869 gimple_opt_pass *
1870 make_pass_lower_vector (gcc::context *ctxt)
1871 {
1872   return new pass_lower_vector (ctxt);
1873 }
1874
1875 namespace {
1876
1877 const pass_data pass_data_lower_vector_ssa =
1878 {
1879   GIMPLE_PASS, /* type */
1880   "veclower2", /* name */
1881   OPTGROUP_VEC, /* optinfo_flags */
1882   TV_NONE, /* tv_id */
1883   PROP_cfg, /* properties_required */
1884   PROP_gimple_lvec, /* properties_provided */
1885   0, /* properties_destroyed */
1886   0, /* todo_flags_start */
1887   ( TODO_update_ssa
1888     | TODO_cleanup_cfg ), /* todo_flags_finish */
1889 };
1890
1891 class pass_lower_vector_ssa : public gimple_opt_pass
1892 {
1893 public:
1894   pass_lower_vector_ssa (gcc::context *ctxt)
1895     : gimple_opt_pass (pass_data_lower_vector_ssa, ctxt)
1896   {}
1897
1898   /* opt_pass methods: */
1899   opt_pass * clone () { return new pass_lower_vector_ssa (m_ctxt); }
1900   virtual unsigned int execute (function *)
1901     {
1902       return expand_vector_operations ();
1903     }
1904
1905 }; // class pass_lower_vector_ssa
1906
1907 } // anon namespace
1908
1909 gimple_opt_pass *
1910 make_pass_lower_vector_ssa (gcc::context *ctxt)
1911 {
1912   return new pass_lower_vector_ssa (ctxt);
1913 }
1914
1915 #include "gt-tree-vect-generic.h"