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