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