Set the call nothrow flag more often
[platform/upstream/gcc.git] / gcc / tree-vect-stmts.c
1 /* Statement Analysis and Transformation for Vectorization
2    Copyright (C) 2003-2017 Free Software Foundation, Inc.
3    Contributed by Dorit Naishlos <dorit@il.ibm.com>
4    and Ira Rosen <irar@il.ibm.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "target.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "gimple.h"
30 #include "ssa.h"
31 #include "optabs-tree.h"
32 #include "insn-config.h"
33 #include "recog.h"              /* FIXME: for insn_data */
34 #include "cgraph.h"
35 #include "dumpfile.h"
36 #include "alias.h"
37 #include "fold-const.h"
38 #include "stor-layout.h"
39 #include "tree-eh.h"
40 #include "gimplify.h"
41 #include "gimple-iterator.h"
42 #include "gimplify-me.h"
43 #include "tree-cfg.h"
44 #include "tree-ssa-loop-manip.h"
45 #include "cfgloop.h"
46 #include "tree-ssa-loop.h"
47 #include "tree-scalar-evolution.h"
48 #include "tree-vectorizer.h"
49 #include "builtins.h"
50 #include "internal-fn.h"
51
52 /* For lang_hooks.types.type_for_mode.  */
53 #include "langhooks.h"
54
55 /* Says whether a statement is a load, a store of a vectorized statement
56    result, or a store of an invariant value.  */
57 enum vec_load_store_type {
58   VLS_LOAD,
59   VLS_STORE,
60   VLS_STORE_INVARIANT
61 };
62
63 /* Return the vectorized type for the given statement.  */
64
65 tree
66 stmt_vectype (struct _stmt_vec_info *stmt_info)
67 {
68   return STMT_VINFO_VECTYPE (stmt_info);
69 }
70
71 /* Return TRUE iff the given statement is in an inner loop relative to
72    the loop being vectorized.  */
73 bool
74 stmt_in_inner_loop_p (struct _stmt_vec_info *stmt_info)
75 {
76   gimple *stmt = STMT_VINFO_STMT (stmt_info);
77   basic_block bb = gimple_bb (stmt);
78   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
79   struct loop* loop;
80
81   if (!loop_vinfo)
82     return false;
83
84   loop = LOOP_VINFO_LOOP (loop_vinfo);
85
86   return (bb->loop_father == loop->inner);
87 }
88
89 /* Record the cost of a statement, either by directly informing the 
90    target model or by saving it in a vector for later processing.
91    Return a preliminary estimate of the statement's cost.  */
92
93 unsigned
94 record_stmt_cost (stmt_vector_for_cost *body_cost_vec, int count,
95                   enum vect_cost_for_stmt kind, stmt_vec_info stmt_info,
96                   int misalign, enum vect_cost_model_location where)
97 {
98   if (body_cost_vec)
99     {
100       tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
101       stmt_info_for_cost si = { count, kind,
102                                 stmt_info ? STMT_VINFO_STMT (stmt_info) : NULL,
103                                 misalign };
104       body_cost_vec->safe_push (si);
105       return (unsigned)
106         (builtin_vectorization_cost (kind, vectype, misalign) * count);
107     }
108   else
109     return add_stmt_cost (stmt_info->vinfo->target_cost_data,
110                           count, kind, stmt_info, misalign, where);
111 }
112
113 /* Return a variable of type ELEM_TYPE[NELEMS].  */
114
115 static tree
116 create_vector_array (tree elem_type, unsigned HOST_WIDE_INT nelems)
117 {
118   return create_tmp_var (build_array_type_nelts (elem_type, nelems),
119                          "vect_array");
120 }
121
122 /* ARRAY is an array of vectors created by create_vector_array.
123    Return an SSA_NAME for the vector in index N.  The reference
124    is part of the vectorization of STMT and the vector is associated
125    with scalar destination SCALAR_DEST.  */
126
127 static tree
128 read_vector_array (gimple *stmt, gimple_stmt_iterator *gsi, tree scalar_dest,
129                    tree array, unsigned HOST_WIDE_INT n)
130 {
131   tree vect_type, vect, vect_name, array_ref;
132   gimple *new_stmt;
133
134   gcc_assert (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE);
135   vect_type = TREE_TYPE (TREE_TYPE (array));
136   vect = vect_create_destination_var (scalar_dest, vect_type);
137   array_ref = build4 (ARRAY_REF, vect_type, array,
138                       build_int_cst (size_type_node, n),
139                       NULL_TREE, NULL_TREE);
140
141   new_stmt = gimple_build_assign (vect, array_ref);
142   vect_name = make_ssa_name (vect, new_stmt);
143   gimple_assign_set_lhs (new_stmt, vect_name);
144   vect_finish_stmt_generation (stmt, new_stmt, gsi);
145
146   return vect_name;
147 }
148
149 /* ARRAY is an array of vectors created by create_vector_array.
150    Emit code to store SSA_NAME VECT in index N of the array.
151    The store is part of the vectorization of STMT.  */
152
153 static void
154 write_vector_array (gimple *stmt, gimple_stmt_iterator *gsi, tree vect,
155                     tree array, unsigned HOST_WIDE_INT n)
156 {
157   tree array_ref;
158   gimple *new_stmt;
159
160   array_ref = build4 (ARRAY_REF, TREE_TYPE (vect), array,
161                       build_int_cst (size_type_node, n),
162                       NULL_TREE, NULL_TREE);
163
164   new_stmt = gimple_build_assign (array_ref, vect);
165   vect_finish_stmt_generation (stmt, new_stmt, gsi);
166 }
167
168 /* PTR is a pointer to an array of type TYPE.  Return a representation
169    of *PTR.  The memory reference replaces those in FIRST_DR
170    (and its group).  */
171
172 static tree
173 create_array_ref (tree type, tree ptr, tree alias_ptr_type)
174 {
175   tree mem_ref;
176
177   mem_ref = build2 (MEM_REF, type, ptr, build_int_cst (alias_ptr_type, 0));
178   /* Arrays have the same alignment as their type.  */
179   set_ptr_info_alignment (get_ptr_info (ptr), TYPE_ALIGN_UNIT (type), 0);
180   return mem_ref;
181 }
182
183 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
184
185 /* Function vect_mark_relevant.
186
187    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
188
189 static void
190 vect_mark_relevant (vec<gimple *> *worklist, gimple *stmt,
191                     enum vect_relevant relevant, bool live_p)
192 {
193   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
194   enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info);
195   bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
196   gimple *pattern_stmt;
197
198   if (dump_enabled_p ())
199     {
200       dump_printf_loc (MSG_NOTE, vect_location,
201                        "mark relevant %d, live %d: ", relevant, live_p);
202       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
203     }
204
205   /* If this stmt is an original stmt in a pattern, we might need to mark its
206      related pattern stmt instead of the original stmt.  However, such stmts
207      may have their own uses that are not in any pattern, in such cases the
208      stmt itself should be marked.  */
209   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
210     {
211       /* This is the last stmt in a sequence that was detected as a
212          pattern that can potentially be vectorized.  Don't mark the stmt
213          as relevant/live because it's not going to be vectorized.
214          Instead mark the pattern-stmt that replaces it.  */
215
216       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
217
218       if (dump_enabled_p ())
219         dump_printf_loc (MSG_NOTE, vect_location,
220                          "last stmt in pattern. don't mark"
221                          " relevant/live.\n");
222       stmt_info = vinfo_for_stmt (pattern_stmt);
223       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
224       save_relevant = STMT_VINFO_RELEVANT (stmt_info);
225       save_live_p = STMT_VINFO_LIVE_P (stmt_info);
226       stmt = pattern_stmt;
227     }
228
229   STMT_VINFO_LIVE_P (stmt_info) |= live_p;
230   if (relevant > STMT_VINFO_RELEVANT (stmt_info))
231     STMT_VINFO_RELEVANT (stmt_info) = relevant;
232
233   if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
234       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
235     {
236       if (dump_enabled_p ())
237         dump_printf_loc (MSG_NOTE, vect_location,
238                          "already marked relevant/live.\n");
239       return;
240     }
241
242   worklist->safe_push (stmt);
243 }
244
245
246 /* Function is_simple_and_all_uses_invariant
247
248    Return true if STMT is simple and all uses of it are invariant.  */
249
250 bool
251 is_simple_and_all_uses_invariant (gimple *stmt, loop_vec_info loop_vinfo)
252 {
253   tree op;
254   gimple *def_stmt;
255   ssa_op_iter iter;
256
257   if (!is_gimple_assign (stmt))
258     return false;
259
260   FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
261     {
262       enum vect_def_type dt = vect_uninitialized_def;
263
264       if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt))
265         {
266           if (dump_enabled_p ())
267             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
268                              "use not simple.\n");
269           return false;
270         }
271
272       if (dt != vect_external_def && dt != vect_constant_def)
273         return false;
274     }
275   return true;
276 }
277
278 /* Function vect_stmt_relevant_p.
279
280    Return true if STMT in loop that is represented by LOOP_VINFO is
281    "relevant for vectorization".
282
283    A stmt is considered "relevant for vectorization" if:
284    - it has uses outside the loop.
285    - it has vdefs (it alters memory).
286    - control stmts in the loop (except for the exit condition).
287
288    CHECKME: what other side effects would the vectorizer allow?  */
289
290 static bool
291 vect_stmt_relevant_p (gimple *stmt, loop_vec_info loop_vinfo,
292                       enum vect_relevant *relevant, bool *live_p)
293 {
294   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
295   ssa_op_iter op_iter;
296   imm_use_iterator imm_iter;
297   use_operand_p use_p;
298   def_operand_p def_p;
299
300   *relevant = vect_unused_in_scope;
301   *live_p = false;
302
303   /* cond stmt other than loop exit cond.  */
304   if (is_ctrl_stmt (stmt)
305       && STMT_VINFO_TYPE (vinfo_for_stmt (stmt))
306          != loop_exit_ctrl_vec_info_type)
307     *relevant = vect_used_in_scope;
308
309   /* changing memory.  */
310   if (gimple_code (stmt) != GIMPLE_PHI)
311     if (gimple_vdef (stmt)
312         && !gimple_clobber_p (stmt))
313       {
314         if (dump_enabled_p ())
315           dump_printf_loc (MSG_NOTE, vect_location,
316                            "vec_stmt_relevant_p: stmt has vdefs.\n");
317         *relevant = vect_used_in_scope;
318       }
319
320   /* uses outside the loop.  */
321   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
322     {
323       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
324         {
325           basic_block bb = gimple_bb (USE_STMT (use_p));
326           if (!flow_bb_inside_loop_p (loop, bb))
327             {
328               if (dump_enabled_p ())
329                 dump_printf_loc (MSG_NOTE, vect_location,
330                                  "vec_stmt_relevant_p: used out of loop.\n");
331
332               if (is_gimple_debug (USE_STMT (use_p)))
333                 continue;
334
335               /* We expect all such uses to be in the loop exit phis
336                  (because of loop closed form)   */
337               gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI);
338               gcc_assert (bb == single_exit (loop)->dest);
339
340               *live_p = true;
341             }
342         }
343     }
344
345   if (*live_p && *relevant == vect_unused_in_scope
346       && !is_simple_and_all_uses_invariant (stmt, loop_vinfo))
347     {
348       if (dump_enabled_p ())
349         dump_printf_loc (MSG_NOTE, vect_location,
350                          "vec_stmt_relevant_p: stmt live but not relevant.\n");
351       *relevant = vect_used_only_live;
352     }
353
354   return (*live_p || *relevant);
355 }
356
357
358 /* Function exist_non_indexing_operands_for_use_p
359
360    USE is one of the uses attached to STMT.  Check if USE is
361    used in STMT for anything other than indexing an array.  */
362
363 static bool
364 exist_non_indexing_operands_for_use_p (tree use, gimple *stmt)
365 {
366   tree operand;
367   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
368
369   /* USE corresponds to some operand in STMT.  If there is no data
370      reference in STMT, then any operand that corresponds to USE
371      is not indexing an array.  */
372   if (!STMT_VINFO_DATA_REF (stmt_info))
373     return true;
374
375   /* STMT has a data_ref. FORNOW this means that its of one of
376      the following forms:
377      -1- ARRAY_REF = var
378      -2- var = ARRAY_REF
379      (This should have been verified in analyze_data_refs).
380
381      'var' in the second case corresponds to a def, not a use,
382      so USE cannot correspond to any operands that are not used
383      for array indexing.
384
385      Therefore, all we need to check is if STMT falls into the
386      first case, and whether var corresponds to USE.  */
387
388   if (!gimple_assign_copy_p (stmt))
389     {
390       if (is_gimple_call (stmt)
391           && gimple_call_internal_p (stmt))
392         switch (gimple_call_internal_fn (stmt))
393           {
394           case IFN_MASK_STORE:
395             operand = gimple_call_arg (stmt, 3);
396             if (operand == use)
397               return true;
398             /* FALLTHRU */
399           case IFN_MASK_LOAD:
400             operand = gimple_call_arg (stmt, 2);
401             if (operand == use)
402               return true;
403             break;
404           default:
405             break;
406           }
407       return false;
408     }
409
410   if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
411     return false;
412   operand = gimple_assign_rhs1 (stmt);
413   if (TREE_CODE (operand) != SSA_NAME)
414     return false;
415
416   if (operand == use)
417     return true;
418
419   return false;
420 }
421
422
423 /*
424    Function process_use.
425
426    Inputs:
427    - a USE in STMT in a loop represented by LOOP_VINFO
428    - RELEVANT - enum value to be set in the STMT_VINFO of the stmt
429      that defined USE.  This is done by calling mark_relevant and passing it
430      the WORKLIST (to add DEF_STMT to the WORKLIST in case it is relevant).
431    - FORCE is true if exist_non_indexing_operands_for_use_p check shouldn't
432      be performed.
433
434    Outputs:
435    Generally, LIVE_P and RELEVANT are used to define the liveness and
436    relevance info of the DEF_STMT of this USE:
437        STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
438        STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant
439    Exceptions:
440    - case 1: If USE is used only for address computations (e.g. array indexing),
441    which does not need to be directly vectorized, then the liveness/relevance
442    of the respective DEF_STMT is left unchanged.
443    - case 2: If STMT is a reduction phi and DEF_STMT is a reduction stmt, we
444    skip DEF_STMT cause it had already been processed.
445    - case 3: If DEF_STMT and STMT are in different nests, then  "relevant" will
446    be modified accordingly.
447
448    Return true if everything is as expected. Return false otherwise.  */
449
450 static bool
451 process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
452              enum vect_relevant relevant, vec<gimple *> *worklist,
453              bool force)
454 {
455   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
456   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
457   stmt_vec_info dstmt_vinfo;
458   basic_block bb, def_bb;
459   gimple *def_stmt;
460   enum vect_def_type dt;
461
462   /* case 1: we are only interested in uses that need to be vectorized.  Uses
463      that are used for address computation are not considered relevant.  */
464   if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
465      return true;
466
467   if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &dt))
468     {
469       if (dump_enabled_p ())
470         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
471                          "not vectorized: unsupported use in stmt.\n");
472       return false;
473     }
474
475   if (!def_stmt || gimple_nop_p (def_stmt))
476     return true;
477
478   def_bb = gimple_bb (def_stmt);
479   if (!flow_bb_inside_loop_p (loop, def_bb))
480     {
481       if (dump_enabled_p ())
482         dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n");
483       return true;
484     }
485
486   /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
487      DEF_STMT must have already been processed, because this should be the
488      only way that STMT, which is a reduction-phi, was put in the worklist,
489      as there should be no other uses for DEF_STMT in the loop.  So we just
490      check that everything is as expected, and we are done.  */
491   dstmt_vinfo = vinfo_for_stmt (def_stmt);
492   bb = gimple_bb (stmt);
493   if (gimple_code (stmt) == GIMPLE_PHI
494       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
495       && gimple_code (def_stmt) != GIMPLE_PHI
496       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
497       && bb->loop_father == def_bb->loop_father)
498     {
499       if (dump_enabled_p ())
500         dump_printf_loc (MSG_NOTE, vect_location,
501                          "reduc-stmt defining reduc-phi in the same nest.\n");
502       if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo))
503         dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo));
504       gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction);
505       gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo)
506                   || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_scope);
507       return true;
508     }
509
510   /* case 3a: outer-loop stmt defining an inner-loop stmt:
511         outer-loop-header-bb:
512                 d = def_stmt
513         inner-loop:
514                 stmt # use (d)
515         outer-loop-tail-bb:
516                 ...               */
517   if (flow_loop_nested_p (def_bb->loop_father, bb->loop_father))
518     {
519       if (dump_enabled_p ())
520         dump_printf_loc (MSG_NOTE, vect_location,
521                          "outer-loop def-stmt defining inner-loop stmt.\n");
522
523       switch (relevant)
524         {
525         case vect_unused_in_scope:
526           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_nested_cycle) ?
527                       vect_used_in_scope : vect_unused_in_scope;
528           break;
529
530         case vect_used_in_outer_by_reduction:
531           gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
532           relevant = vect_used_by_reduction;
533           break;
534
535         case vect_used_in_outer:
536           gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
537           relevant = vect_used_in_scope;
538           break;
539
540         case vect_used_in_scope:
541           break;
542
543         default:
544           gcc_unreachable ();
545         }
546     }
547
548   /* case 3b: inner-loop stmt defining an outer-loop stmt:
549         outer-loop-header-bb:
550                 ...
551         inner-loop:
552                 d = def_stmt
553         outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
554                 stmt # use (d)          */
555   else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
556     {
557       if (dump_enabled_p ())
558         dump_printf_loc (MSG_NOTE, vect_location,
559                          "inner-loop def-stmt defining outer-loop stmt.\n");
560
561       switch (relevant)
562         {
563         case vect_unused_in_scope:
564           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
565             || STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_double_reduction_def) ?
566                       vect_used_in_outer_by_reduction : vect_unused_in_scope;
567           break;
568
569         case vect_used_by_reduction:
570         case vect_used_only_live:
571           relevant = vect_used_in_outer_by_reduction;
572           break;
573
574         case vect_used_in_scope:
575           relevant = vect_used_in_outer;
576           break;
577
578         default:
579           gcc_unreachable ();
580         }
581     }
582   /* We are also not interested in uses on loop PHI backedges that are
583      inductions.  Otherwise we'll needlessly vectorize the IV increment
584      and cause hybrid SLP for SLP inductions.  Unless the PHI is live
585      of course.  */
586   else if (gimple_code (stmt) == GIMPLE_PHI
587            && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_induction_def
588            && ! STMT_VINFO_LIVE_P (stmt_vinfo)
589            && (PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (bb->loop_father))
590                == use))
591     {
592       if (dump_enabled_p ())
593         dump_printf_loc (MSG_NOTE, vect_location,
594                          "induction value on backedge.\n");
595       return true;
596     }
597
598
599   vect_mark_relevant (worklist, def_stmt, relevant, false);
600   return true;
601 }
602
603
604 /* Function vect_mark_stmts_to_be_vectorized.
605
606    Not all stmts in the loop need to be vectorized. For example:
607
608      for i...
609        for j...
610    1.    T0 = i + j
611    2.    T1 = a[T0]
612
613    3.    j = j + 1
614
615    Stmt 1 and 3 do not need to be vectorized, because loop control and
616    addressing of vectorized data-refs are handled differently.
617
618    This pass detects such stmts.  */
619
620 bool
621 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
622 {
623   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
624   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
625   unsigned int nbbs = loop->num_nodes;
626   gimple_stmt_iterator si;
627   gimple *stmt;
628   unsigned int i;
629   stmt_vec_info stmt_vinfo;
630   basic_block bb;
631   gimple *phi;
632   bool live_p;
633   enum vect_relevant relevant;
634
635   if (dump_enabled_p ())
636     dump_printf_loc (MSG_NOTE, vect_location,
637                      "=== vect_mark_stmts_to_be_vectorized ===\n");
638
639   auto_vec<gimple *, 64> worklist;
640
641   /* 1. Init worklist.  */
642   for (i = 0; i < nbbs; i++)
643     {
644       bb = bbs[i];
645       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
646         {
647           phi = gsi_stmt (si);
648           if (dump_enabled_p ())
649             {
650               dump_printf_loc (MSG_NOTE, vect_location, "init: phi relevant? ");
651               dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
652             }
653
654           if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
655             vect_mark_relevant (&worklist, phi, relevant, live_p);
656         }
657       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
658         {
659           stmt = gsi_stmt (si);
660           if (dump_enabled_p ())
661             {
662               dump_printf_loc (MSG_NOTE, vect_location, "init: stmt relevant? ");
663               dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
664             }
665
666           if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
667             vect_mark_relevant (&worklist, stmt, relevant, live_p);
668         }
669     }
670
671   /* 2. Process_worklist */
672   while (worklist.length () > 0)
673     {
674       use_operand_p use_p;
675       ssa_op_iter iter;
676
677       stmt = worklist.pop ();
678       if (dump_enabled_p ())
679         {
680           dump_printf_loc (MSG_NOTE, vect_location, "worklist: examine stmt: ");
681           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
682         }
683
684       /* Examine the USEs of STMT. For each USE, mark the stmt that defines it
685          (DEF_STMT) as relevant/irrelevant according to the relevance property
686          of STMT.  */
687       stmt_vinfo = vinfo_for_stmt (stmt);
688       relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
689
690       /* Generally, the relevance property of STMT (in STMT_VINFO_RELEVANT) is
691          propagated as is to the DEF_STMTs of its USEs.
692
693          One exception is when STMT has been identified as defining a reduction
694          variable; in this case we set the relevance to vect_used_by_reduction.
695          This is because we distinguish between two kinds of relevant stmts -
696          those that are used by a reduction computation, and those that are
697          (also) used by a regular computation.  This allows us later on to
698          identify stmts that are used solely by a reduction, and therefore the
699          order of the results that they produce does not have to be kept.  */
700
701       switch (STMT_VINFO_DEF_TYPE (stmt_vinfo))
702         {
703           case vect_reduction_def:
704             gcc_assert (relevant != vect_unused_in_scope);
705             if (relevant != vect_unused_in_scope
706                 && relevant != vect_used_in_scope
707                 && relevant != vect_used_by_reduction
708                 && relevant != vect_used_only_live)
709               {
710                 if (dump_enabled_p ())
711                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
712                                    "unsupported use of reduction.\n");
713                 return false;
714               }
715             break;
716
717           case vect_nested_cycle:
718             if (relevant != vect_unused_in_scope
719                 && relevant != vect_used_in_outer_by_reduction
720                 && relevant != vect_used_in_outer)
721               {
722                 if (dump_enabled_p ())
723                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
724                                    "unsupported use of nested cycle.\n");
725
726                 return false;
727               }
728             break;
729
730           case vect_double_reduction_def:
731             if (relevant != vect_unused_in_scope
732                 && relevant != vect_used_by_reduction
733                 && relevant != vect_used_only_live)
734               {
735                 if (dump_enabled_p ())
736                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
737                                    "unsupported use of double reduction.\n");
738
739                 return false;
740               }
741             break;
742
743           default:
744             break;
745         }
746
747       if (is_pattern_stmt_p (stmt_vinfo))
748         {
749           /* Pattern statements are not inserted into the code, so
750              FOR_EACH_PHI_OR_STMT_USE optimizes their operands out, and we
751              have to scan the RHS or function arguments instead.  */
752           if (is_gimple_assign (stmt))
753             {
754               enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
755               tree op = gimple_assign_rhs1 (stmt);
756
757               i = 1;
758               if (rhs_code == COND_EXPR && COMPARISON_CLASS_P (op))
759                 {
760                   if (!process_use (stmt, TREE_OPERAND (op, 0), loop_vinfo,
761                                     relevant, &worklist, false)
762                       || !process_use (stmt, TREE_OPERAND (op, 1), loop_vinfo,
763                                        relevant, &worklist, false))
764                     return false;
765                   i = 2;
766                 }
767               for (; i < gimple_num_ops (stmt); i++)
768                 {
769                   op = gimple_op (stmt, i);
770                   if (TREE_CODE (op) == SSA_NAME
771                       && !process_use (stmt, op, loop_vinfo, relevant,
772                                        &worklist, false))
773                     return false;
774                  }
775             }
776           else if (is_gimple_call (stmt))
777             {
778               for (i = 0; i < gimple_call_num_args (stmt); i++)
779                 {
780                   tree arg = gimple_call_arg (stmt, i);
781                   if (!process_use (stmt, arg, loop_vinfo, relevant,
782                                     &worklist, false))
783                     return false;
784                 }
785             }
786         }
787       else
788         FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
789           {
790             tree op = USE_FROM_PTR (use_p);
791             if (!process_use (stmt, op, loop_vinfo, relevant,
792                               &worklist, false))
793               return false;
794           }
795
796       if (STMT_VINFO_GATHER_SCATTER_P (stmt_vinfo))
797         {
798           gather_scatter_info gs_info;
799           if (!vect_check_gather_scatter (stmt, loop_vinfo, &gs_info))
800             gcc_unreachable ();
801           if (!process_use (stmt, gs_info.offset, loop_vinfo, relevant,
802                             &worklist, true))
803             return false;
804         }
805     } /* while worklist */
806
807   return true;
808 }
809
810
811 /* Function vect_model_simple_cost.
812
813    Models cost for simple operations, i.e. those that only emit ncopies of a
814    single op.  Right now, this does not account for multiple insns that could
815    be generated for the single vector op.  We will handle that shortly.  */
816
817 void
818 vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
819                         enum vect_def_type *dt,
820                         int ndts,
821                         stmt_vector_for_cost *prologue_cost_vec,
822                         stmt_vector_for_cost *body_cost_vec)
823 {
824   int i;
825   int inside_cost = 0, prologue_cost = 0;
826
827   /* The SLP costs were already calculated during SLP tree build.  */
828   if (PURE_SLP_STMT (stmt_info))
829     return;
830
831   /* Cost the "broadcast" of a scalar operand in to a vector operand.
832      Use scalar_to_vec to cost the broadcast, as elsewhere in the vector
833      cost model.  */
834   for (i = 0; i < ndts; i++)
835     if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
836       prologue_cost += record_stmt_cost (prologue_cost_vec, 1, scalar_to_vec,
837                                          stmt_info, 0, vect_prologue);
838
839   /* Pass the inside-of-loop statements to the target-specific cost model.  */
840   inside_cost = record_stmt_cost (body_cost_vec, ncopies, vector_stmt,
841                                   stmt_info, 0, vect_body);
842
843   if (dump_enabled_p ())
844     dump_printf_loc (MSG_NOTE, vect_location,
845                      "vect_model_simple_cost: inside_cost = %d, "
846                      "prologue_cost = %d .\n", inside_cost, prologue_cost);
847 }
848
849
850 /* Model cost for type demotion and promotion operations.  PWR is normally
851    zero for single-step promotions and demotions.  It will be one if 
852    two-step promotion/demotion is required, and so on.  Each additional
853    step doubles the number of instructions required.  */
854
855 static void
856 vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
857                                     enum vect_def_type *dt, int pwr)
858 {
859   int i, tmp;
860   int inside_cost = 0, prologue_cost = 0;
861   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
862   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
863   void *target_cost_data;
864
865   /* The SLP costs were already calculated during SLP tree build.  */
866   if (PURE_SLP_STMT (stmt_info))
867     return;
868
869   if (loop_vinfo)
870     target_cost_data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo);
871   else
872     target_cost_data = BB_VINFO_TARGET_COST_DATA (bb_vinfo);
873
874   for (i = 0; i < pwr + 1; i++)
875     {
876       tmp = (STMT_VINFO_TYPE (stmt_info) == type_promotion_vec_info_type) ?
877         (i + 1) : i;
878       inside_cost += add_stmt_cost (target_cost_data, vect_pow2 (tmp),
879                                     vec_promote_demote, stmt_info, 0,
880                                     vect_body);
881     }
882
883   /* FORNOW: Assuming maximum 2 args per stmts.  */
884   for (i = 0; i < 2; i++)
885     if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
886       prologue_cost += add_stmt_cost (target_cost_data, 1, vector_stmt,
887                                       stmt_info, 0, vect_prologue);
888
889   if (dump_enabled_p ())
890     dump_printf_loc (MSG_NOTE, vect_location,
891                      "vect_model_promotion_demotion_cost: inside_cost = %d, "
892                      "prologue_cost = %d .\n", inside_cost, prologue_cost);
893 }
894
895 /* Function vect_model_store_cost
896
897    Models cost for stores.  In the case of grouped accesses, one access
898    has the overhead of the grouped access attributed to it.  */
899
900 void
901 vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
902                        vect_memory_access_type memory_access_type,
903                        enum vect_def_type dt, slp_tree slp_node,
904                        stmt_vector_for_cost *prologue_cost_vec,
905                        stmt_vector_for_cost *body_cost_vec)
906 {
907   unsigned int inside_cost = 0, prologue_cost = 0;
908   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
909   gimple *first_stmt = STMT_VINFO_STMT (stmt_info);
910   bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info);
911
912   if (dt == vect_constant_def || dt == vect_external_def)
913     prologue_cost += record_stmt_cost (prologue_cost_vec, 1, scalar_to_vec,
914                                        stmt_info, 0, vect_prologue);
915
916   /* Grouped stores update all elements in the group at once,
917      so we want the DR for the first statement.  */
918   if (!slp_node && grouped_access_p)
919     {
920       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
921       dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
922     }
923
924   /* True if we should include any once-per-group costs as well as
925      the cost of the statement itself.  For SLP we only get called
926      once per group anyhow.  */
927   bool first_stmt_p = (first_stmt == STMT_VINFO_STMT (stmt_info));
928
929   /* We assume that the cost of a single store-lanes instruction is
930      equivalent to the cost of GROUP_SIZE separate stores.  If a grouped
931      access is instead being provided by a permute-and-store operation,
932      include the cost of the permutes.  */
933   if (first_stmt_p
934       && memory_access_type == VMAT_CONTIGUOUS_PERMUTE)
935     {
936       /* Uses a high and low interleave or shuffle operations for each
937          needed permute.  */
938       int group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
939       int nstmts = ncopies * ceil_log2 (group_size) * group_size;
940       inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm,
941                                       stmt_info, 0, vect_body);
942
943       if (dump_enabled_p ())
944         dump_printf_loc (MSG_NOTE, vect_location,
945                          "vect_model_store_cost: strided group_size = %d .\n",
946                          group_size);
947     }
948
949   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
950   /* Costs of the stores.  */
951   if (memory_access_type == VMAT_ELEMENTWISE
952       || memory_access_type == VMAT_GATHER_SCATTER)
953     /* N scalar stores plus extracting the elements.  */
954     inside_cost += record_stmt_cost (body_cost_vec,
955                                      ncopies * TYPE_VECTOR_SUBPARTS (vectype),
956                                      scalar_store, stmt_info, 0, vect_body);
957   else
958     vect_get_store_cost (dr, ncopies, &inside_cost, body_cost_vec);
959
960   if (memory_access_type == VMAT_ELEMENTWISE
961       || memory_access_type == VMAT_STRIDED_SLP)
962     inside_cost += record_stmt_cost (body_cost_vec,
963                                      ncopies * TYPE_VECTOR_SUBPARTS (vectype),
964                                      vec_to_scalar, stmt_info, 0, vect_body);
965
966   if (dump_enabled_p ())
967     dump_printf_loc (MSG_NOTE, vect_location,
968                      "vect_model_store_cost: inside_cost = %d, "
969                      "prologue_cost = %d .\n", inside_cost, prologue_cost);
970 }
971
972
973 /* Calculate cost of DR's memory access.  */
974 void
975 vect_get_store_cost (struct data_reference *dr, int ncopies,
976                      unsigned int *inside_cost,
977                      stmt_vector_for_cost *body_cost_vec)
978 {
979   int alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
980   gimple *stmt = DR_STMT (dr);
981   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
982
983   switch (alignment_support_scheme)
984     {
985     case dr_aligned:
986       {
987         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
988                                           vector_store, stmt_info, 0,
989                                           vect_body);
990
991         if (dump_enabled_p ())
992           dump_printf_loc (MSG_NOTE, vect_location,
993                            "vect_model_store_cost: aligned.\n");
994         break;
995       }
996
997     case dr_unaligned_supported:
998       {
999         /* Here, we assign an additional cost for the unaligned store.  */
1000         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
1001                                           unaligned_store, stmt_info,
1002                                           DR_MISALIGNMENT (dr), vect_body);
1003         if (dump_enabled_p ())
1004           dump_printf_loc (MSG_NOTE, vect_location,
1005                            "vect_model_store_cost: unaligned supported by "
1006                            "hardware.\n");
1007         break;
1008       }
1009
1010     case dr_unaligned_unsupported:
1011       {
1012         *inside_cost = VECT_MAX_COST;
1013
1014         if (dump_enabled_p ())
1015           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1016                            "vect_model_store_cost: unsupported access.\n");
1017         break;
1018       }
1019
1020     default:
1021       gcc_unreachable ();
1022     }
1023 }
1024
1025
1026 /* Function vect_model_load_cost
1027
1028    Models cost for loads.  In the case of grouped accesses, one access has
1029    the overhead of the grouped access attributed to it.  Since unaligned
1030    accesses are supported for loads, we also account for the costs of the
1031    access scheme chosen.  */
1032
1033 void
1034 vect_model_load_cost (stmt_vec_info stmt_info, int ncopies,
1035                       vect_memory_access_type memory_access_type,
1036                       slp_tree slp_node,
1037                       stmt_vector_for_cost *prologue_cost_vec,
1038                       stmt_vector_for_cost *body_cost_vec)
1039 {
1040   gimple *first_stmt = STMT_VINFO_STMT (stmt_info);
1041   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1042   unsigned int inside_cost = 0, prologue_cost = 0;
1043   bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info);
1044
1045   /* Grouped loads read all elements in the group at once,
1046      so we want the DR for the first statement.  */
1047   if (!slp_node && grouped_access_p)
1048     {
1049       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
1050       dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
1051     }
1052
1053   /* True if we should include any once-per-group costs as well as
1054      the cost of the statement itself.  For SLP we only get called
1055      once per group anyhow.  */
1056   bool first_stmt_p = (first_stmt == STMT_VINFO_STMT (stmt_info));
1057
1058   /* We assume that the cost of a single load-lanes instruction is
1059      equivalent to the cost of GROUP_SIZE separate loads.  If a grouped
1060      access is instead being provided by a load-and-permute operation,
1061      include the cost of the permutes.  */
1062   if (first_stmt_p
1063       && memory_access_type == VMAT_CONTIGUOUS_PERMUTE)
1064     {
1065       /* Uses an even and odd extract operations or shuffle operations
1066          for each needed permute.  */
1067       int group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
1068       int nstmts = ncopies * ceil_log2 (group_size) * group_size;
1069       inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm,
1070                                       stmt_info, 0, vect_body);
1071
1072       if (dump_enabled_p ())
1073         dump_printf_loc (MSG_NOTE, vect_location,
1074                          "vect_model_load_cost: strided group_size = %d .\n",
1075                          group_size);
1076     }
1077
1078   /* The loads themselves.  */
1079   if (memory_access_type == VMAT_ELEMENTWISE
1080       || memory_access_type == VMAT_GATHER_SCATTER)
1081     {
1082       /* N scalar loads plus gathering them into a vector.  */
1083       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1084       inside_cost += record_stmt_cost (body_cost_vec,
1085                                        ncopies * TYPE_VECTOR_SUBPARTS (vectype),
1086                                        scalar_load, stmt_info, 0, vect_body);
1087     }
1088   else
1089     vect_get_load_cost (dr, ncopies, first_stmt_p,
1090                         &inside_cost, &prologue_cost, 
1091                         prologue_cost_vec, body_cost_vec, true);
1092   if (memory_access_type == VMAT_ELEMENTWISE
1093       || memory_access_type == VMAT_STRIDED_SLP)
1094     inside_cost += record_stmt_cost (body_cost_vec, ncopies, vec_construct,
1095                                      stmt_info, 0, vect_body);
1096
1097   if (dump_enabled_p ())
1098     dump_printf_loc (MSG_NOTE, vect_location,
1099                      "vect_model_load_cost: inside_cost = %d, "
1100                      "prologue_cost = %d .\n", inside_cost, prologue_cost);
1101 }
1102
1103
1104 /* Calculate cost of DR's memory access.  */
1105 void
1106 vect_get_load_cost (struct data_reference *dr, int ncopies,
1107                     bool add_realign_cost, unsigned int *inside_cost,
1108                     unsigned int *prologue_cost,
1109                     stmt_vector_for_cost *prologue_cost_vec,
1110                     stmt_vector_for_cost *body_cost_vec,
1111                     bool record_prologue_costs)
1112 {
1113   int alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
1114   gimple *stmt = DR_STMT (dr);
1115   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1116
1117   switch (alignment_support_scheme)
1118     {
1119     case dr_aligned:
1120       {
1121         *inside_cost += record_stmt_cost (body_cost_vec, ncopies, vector_load,
1122                                           stmt_info, 0, vect_body);
1123
1124         if (dump_enabled_p ())
1125           dump_printf_loc (MSG_NOTE, vect_location,
1126                            "vect_model_load_cost: aligned.\n");
1127
1128         break;
1129       }
1130     case dr_unaligned_supported:
1131       {
1132         /* Here, we assign an additional cost for the unaligned load.  */
1133         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
1134                                           unaligned_load, stmt_info,
1135                                           DR_MISALIGNMENT (dr), vect_body);
1136
1137         if (dump_enabled_p ())
1138           dump_printf_loc (MSG_NOTE, vect_location,
1139                            "vect_model_load_cost: unaligned supported by "
1140                            "hardware.\n");
1141
1142         break;
1143       }
1144     case dr_explicit_realign:
1145       {
1146         *inside_cost += record_stmt_cost (body_cost_vec, ncopies * 2,
1147                                           vector_load, stmt_info, 0, vect_body);
1148         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
1149                                           vec_perm, stmt_info, 0, vect_body);
1150
1151         /* FIXME: If the misalignment remains fixed across the iterations of
1152            the containing loop, the following cost should be added to the
1153            prologue costs.  */
1154         if (targetm.vectorize.builtin_mask_for_load)
1155           *inside_cost += record_stmt_cost (body_cost_vec, 1, vector_stmt,
1156                                             stmt_info, 0, vect_body);
1157
1158         if (dump_enabled_p ())
1159           dump_printf_loc (MSG_NOTE, vect_location,
1160                            "vect_model_load_cost: explicit realign\n");
1161
1162         break;
1163       }
1164     case dr_explicit_realign_optimized:
1165       {
1166         if (dump_enabled_p ())
1167           dump_printf_loc (MSG_NOTE, vect_location,
1168                            "vect_model_load_cost: unaligned software "
1169                            "pipelined.\n");
1170
1171         /* Unaligned software pipeline has a load of an address, an initial
1172            load, and possibly a mask operation to "prime" the loop.  However,
1173            if this is an access in a group of loads, which provide grouped
1174            access, then the above cost should only be considered for one
1175            access in the group.  Inside the loop, there is a load op
1176            and a realignment op.  */
1177
1178         if (add_realign_cost && record_prologue_costs)
1179           {
1180             *prologue_cost += record_stmt_cost (prologue_cost_vec, 2,
1181                                                 vector_stmt, stmt_info,
1182                                                 0, vect_prologue);
1183             if (targetm.vectorize.builtin_mask_for_load)
1184               *prologue_cost += record_stmt_cost (prologue_cost_vec, 1,
1185                                                   vector_stmt, stmt_info,
1186                                                   0, vect_prologue);
1187           }
1188
1189         *inside_cost += record_stmt_cost (body_cost_vec, ncopies, vector_load,
1190                                           stmt_info, 0, vect_body);
1191         *inside_cost += record_stmt_cost (body_cost_vec, ncopies, vec_perm,
1192                                           stmt_info, 0, vect_body);
1193
1194         if (dump_enabled_p ())
1195           dump_printf_loc (MSG_NOTE, vect_location,
1196                            "vect_model_load_cost: explicit realign optimized"
1197                            "\n");
1198
1199         break;
1200       }
1201
1202     case dr_unaligned_unsupported:
1203       {
1204         *inside_cost = VECT_MAX_COST;
1205
1206         if (dump_enabled_p ())
1207           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1208                            "vect_model_load_cost: unsupported access.\n");
1209         break;
1210       }
1211
1212     default:
1213       gcc_unreachable ();
1214     }
1215 }
1216
1217 /* Insert the new stmt NEW_STMT at *GSI or at the appropriate place in
1218    the loop preheader for the vectorized stmt STMT.  */
1219
1220 static void
1221 vect_init_vector_1 (gimple *stmt, gimple *new_stmt, gimple_stmt_iterator *gsi)
1222 {
1223   if (gsi)
1224     vect_finish_stmt_generation (stmt, new_stmt, gsi);
1225   else
1226     {
1227       stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
1228       loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
1229
1230       if (loop_vinfo)
1231         {
1232           struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1233           basic_block new_bb;
1234           edge pe;
1235
1236           if (nested_in_vect_loop_p (loop, stmt))
1237             loop = loop->inner;
1238
1239           pe = loop_preheader_edge (loop);
1240           new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
1241           gcc_assert (!new_bb);
1242         }
1243       else
1244        {
1245           bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
1246           basic_block bb;
1247           gimple_stmt_iterator gsi_bb_start;
1248
1249           gcc_assert (bb_vinfo);
1250           bb = BB_VINFO_BB (bb_vinfo);
1251           gsi_bb_start = gsi_after_labels (bb);
1252           gsi_insert_before (&gsi_bb_start, new_stmt, GSI_SAME_STMT);
1253        }
1254     }
1255
1256   if (dump_enabled_p ())
1257     {
1258       dump_printf_loc (MSG_NOTE, vect_location,
1259                        "created new init_stmt: ");
1260       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, new_stmt, 0);
1261     }
1262 }
1263
1264 /* Function vect_init_vector.
1265
1266    Insert a new stmt (INIT_STMT) that initializes a new variable of type
1267    TYPE with the value VAL.  If TYPE is a vector type and VAL does not have
1268    vector type a vector with all elements equal to VAL is created first.
1269    Place the initialization at BSI if it is not NULL.  Otherwise, place the
1270    initialization at the loop preheader.
1271    Return the DEF of INIT_STMT.
1272    It will be used in the vectorization of STMT.  */
1273
1274 tree
1275 vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator *gsi)
1276 {
1277   gimple *init_stmt;
1278   tree new_temp;
1279
1280   /* We abuse this function to push sth to a SSA name with initial 'val'.  */
1281   if (! useless_type_conversion_p (type, TREE_TYPE (val)))
1282     {
1283       gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
1284       if (! types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
1285         {
1286           /* Scalar boolean value should be transformed into
1287              all zeros or all ones value before building a vector.  */
1288           if (VECTOR_BOOLEAN_TYPE_P (type))
1289             {
1290               tree true_val = build_all_ones_cst (TREE_TYPE (type));
1291               tree false_val = build_zero_cst (TREE_TYPE (type));
1292
1293               if (CONSTANT_CLASS_P (val))
1294                 val = integer_zerop (val) ? false_val : true_val;
1295               else
1296                 {
1297                   new_temp = make_ssa_name (TREE_TYPE (type));
1298                   init_stmt = gimple_build_assign (new_temp, COND_EXPR,
1299                                                    val, true_val, false_val);
1300                   vect_init_vector_1 (stmt, init_stmt, gsi);
1301                   val = new_temp;
1302                 }
1303             }
1304           else if (CONSTANT_CLASS_P (val))
1305             val = fold_convert (TREE_TYPE (type), val);
1306           else
1307             {
1308               new_temp = make_ssa_name (TREE_TYPE (type));
1309               if (! INTEGRAL_TYPE_P (TREE_TYPE (val)))
1310                 init_stmt = gimple_build_assign (new_temp,
1311                                                  fold_build1 (VIEW_CONVERT_EXPR,
1312                                                               TREE_TYPE (type),
1313                                                               val));
1314               else
1315                 init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
1316               vect_init_vector_1 (stmt, init_stmt, gsi);
1317               val = new_temp;
1318             }
1319         }
1320       val = build_vector_from_val (type, val);
1321     }
1322
1323   new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_");
1324   init_stmt = gimple_build_assign  (new_temp, val);
1325   vect_init_vector_1 (stmt, init_stmt, gsi);
1326   return new_temp;
1327 }
1328
1329 /* Function vect_get_vec_def_for_operand_1.
1330
1331    For a defining stmt DEF_STMT of a scalar stmt, return a vector def with type
1332    DT that will be used in the vectorized stmt.  */
1333
1334 tree
1335 vect_get_vec_def_for_operand_1 (gimple *def_stmt, enum vect_def_type dt)
1336 {
1337   tree vec_oprnd;
1338   gimple *vec_stmt;
1339   stmt_vec_info def_stmt_info = NULL;
1340
1341   switch (dt)
1342     {
1343     /* operand is a constant or a loop invariant.  */
1344     case vect_constant_def:
1345     case vect_external_def:
1346       /* Code should use vect_get_vec_def_for_operand.  */
1347       gcc_unreachable ();
1348
1349     /* operand is defined inside the loop.  */
1350     case vect_internal_def:
1351       {
1352         /* Get the def from the vectorized stmt.  */
1353         def_stmt_info = vinfo_for_stmt (def_stmt);
1354
1355         vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
1356         /* Get vectorized pattern statement.  */
1357         if (!vec_stmt
1358             && STMT_VINFO_IN_PATTERN_P (def_stmt_info)
1359             && !STMT_VINFO_RELEVANT (def_stmt_info))
1360           vec_stmt = STMT_VINFO_VEC_STMT (vinfo_for_stmt (
1361                        STMT_VINFO_RELATED_STMT (def_stmt_info)));
1362         gcc_assert (vec_stmt);
1363         if (gimple_code (vec_stmt) == GIMPLE_PHI)
1364           vec_oprnd = PHI_RESULT (vec_stmt);
1365         else if (is_gimple_call (vec_stmt))
1366           vec_oprnd = gimple_call_lhs (vec_stmt);
1367         else
1368           vec_oprnd = gimple_assign_lhs (vec_stmt);
1369         return vec_oprnd;
1370       }
1371
1372     /* operand is defined by a loop header phi.  */
1373     case vect_reduction_def:
1374     case vect_double_reduction_def:
1375     case vect_nested_cycle:
1376     case vect_induction_def:
1377       {
1378         gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
1379
1380         /* Get the def from the vectorized stmt.  */
1381         def_stmt_info = vinfo_for_stmt (def_stmt);
1382         vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
1383         if (gimple_code (vec_stmt) == GIMPLE_PHI)
1384           vec_oprnd = PHI_RESULT (vec_stmt);
1385         else
1386           vec_oprnd = gimple_get_lhs (vec_stmt);
1387         return vec_oprnd;
1388       }
1389
1390     default:
1391       gcc_unreachable ();
1392     }
1393 }
1394
1395
1396 /* Function vect_get_vec_def_for_operand.
1397
1398    OP is an operand in STMT.  This function returns a (vector) def that will be
1399    used in the vectorized stmt for STMT.
1400
1401    In the case that OP is an SSA_NAME which is defined in the loop, then
1402    STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
1403
1404    In case OP is an invariant or constant, a new stmt that creates a vector def
1405    needs to be introduced.  VECTYPE may be used to specify a required type for
1406    vector invariant.  */
1407
1408 tree
1409 vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype)
1410 {
1411   gimple *def_stmt;
1412   enum vect_def_type dt;
1413   bool is_simple_use;
1414   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
1415   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
1416
1417   if (dump_enabled_p ())
1418     {
1419       dump_printf_loc (MSG_NOTE, vect_location,
1420                        "vect_get_vec_def_for_operand: ");
1421       dump_generic_expr (MSG_NOTE, TDF_SLIM, op);
1422       dump_printf (MSG_NOTE, "\n");
1423     }
1424
1425   is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt);
1426   gcc_assert (is_simple_use);
1427   if (def_stmt && dump_enabled_p ())
1428     {
1429       dump_printf_loc (MSG_NOTE, vect_location, "  def_stmt =  ");
1430       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0);
1431     }
1432
1433   if (dt == vect_constant_def || dt == vect_external_def)
1434     {
1435       tree stmt_vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
1436       tree vector_type;
1437
1438       if (vectype)
1439         vector_type = vectype;
1440       else if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
1441                && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
1442         vector_type = build_same_sized_truth_vector_type (stmt_vectype);
1443       else
1444         vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
1445
1446       gcc_assert (vector_type);
1447       return vect_init_vector (stmt, op, vector_type, NULL);
1448     }
1449   else
1450     return vect_get_vec_def_for_operand_1 (def_stmt, dt);
1451 }
1452
1453
1454 /* Function vect_get_vec_def_for_stmt_copy
1455
1456    Return a vector-def for an operand.  This function is used when the
1457    vectorized stmt to be created (by the caller to this function) is a "copy"
1458    created in case the vectorized result cannot fit in one vector, and several
1459    copies of the vector-stmt are required.  In this case the vector-def is
1460    retrieved from the vector stmt recorded in the STMT_VINFO_RELATED_STMT field
1461    of the stmt that defines VEC_OPRND.
1462    DT is the type of the vector def VEC_OPRND.
1463
1464    Context:
1465         In case the vectorization factor (VF) is bigger than the number
1466    of elements that can fit in a vectype (nunits), we have to generate
1467    more than one vector stmt to vectorize the scalar stmt.  This situation
1468    arises when there are multiple data-types operated upon in the loop; the
1469    smallest data-type determines the VF, and as a result, when vectorizing
1470    stmts operating on wider types we need to create 'VF/nunits' "copies" of the
1471    vector stmt (each computing a vector of 'nunits' results, and together
1472    computing 'VF' results in each iteration).  This function is called when
1473    vectorizing such a stmt (e.g. vectorizing S2 in the illustration below, in
1474    which VF=16 and nunits=4, so the number of copies required is 4):
1475
1476    scalar stmt:         vectorized into:        STMT_VINFO_RELATED_STMT
1477
1478    S1: x = load         VS1.0:  vx.0 = memref0      VS1.1
1479                         VS1.1:  vx.1 = memref1      VS1.2
1480                         VS1.2:  vx.2 = memref2      VS1.3
1481                         VS1.3:  vx.3 = memref3
1482
1483    S2: z = x + ...      VSnew.0:  vz0 = vx.0 + ...  VSnew.1
1484                         VSnew.1:  vz1 = vx.1 + ...  VSnew.2
1485                         VSnew.2:  vz2 = vx.2 + ...  VSnew.3
1486                         VSnew.3:  vz3 = vx.3 + ...
1487
1488    The vectorization of S1 is explained in vectorizable_load.
1489    The vectorization of S2:
1490         To create the first vector-stmt out of the 4 copies - VSnew.0 -
1491    the function 'vect_get_vec_def_for_operand' is called to
1492    get the relevant vector-def for each operand of S2.  For operand x it
1493    returns  the vector-def 'vx.0'.
1494
1495         To create the remaining copies of the vector-stmt (VSnew.j), this
1496    function is called to get the relevant vector-def for each operand.  It is
1497    obtained from the respective VS1.j stmt, which is recorded in the
1498    STMT_VINFO_RELATED_STMT field of the stmt that defines VEC_OPRND.
1499
1500         For example, to obtain the vector-def 'vx.1' in order to create the
1501    vector stmt 'VSnew.1', this function is called with VEC_OPRND='vx.0'.
1502    Given 'vx0' we obtain the stmt that defines it ('VS1.0'); from the
1503    STMT_VINFO_RELATED_STMT field of 'VS1.0' we obtain the next copy - 'VS1.1',
1504    and return its def ('vx.1').
1505    Overall, to create the above sequence this function will be called 3 times:
1506         vx.1 = vect_get_vec_def_for_stmt_copy (dt, vx.0);
1507         vx.2 = vect_get_vec_def_for_stmt_copy (dt, vx.1);
1508         vx.3 = vect_get_vec_def_for_stmt_copy (dt, vx.2);  */
1509
1510 tree
1511 vect_get_vec_def_for_stmt_copy (enum vect_def_type dt, tree vec_oprnd)
1512 {
1513   gimple *vec_stmt_for_operand;
1514   stmt_vec_info def_stmt_info;
1515
1516   /* Do nothing; can reuse same def.  */
1517   if (dt == vect_external_def || dt == vect_constant_def )
1518     return vec_oprnd;
1519
1520   vec_stmt_for_operand = SSA_NAME_DEF_STMT (vec_oprnd);
1521   def_stmt_info = vinfo_for_stmt (vec_stmt_for_operand);
1522   gcc_assert (def_stmt_info);
1523   vec_stmt_for_operand = STMT_VINFO_RELATED_STMT (def_stmt_info);
1524   gcc_assert (vec_stmt_for_operand);
1525   if (gimple_code (vec_stmt_for_operand) == GIMPLE_PHI)
1526     vec_oprnd = PHI_RESULT (vec_stmt_for_operand);
1527   else
1528     vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
1529   return vec_oprnd;
1530 }
1531
1532
1533 /* Get vectorized definitions for the operands to create a copy of an original
1534    stmt.  See vect_get_vec_def_for_stmt_copy () for details.  */
1535
1536 void
1537 vect_get_vec_defs_for_stmt_copy (enum vect_def_type *dt,
1538                                  vec<tree> *vec_oprnds0,
1539                                  vec<tree> *vec_oprnds1)
1540 {
1541   tree vec_oprnd = vec_oprnds0->pop ();
1542
1543   vec_oprnd = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd);
1544   vec_oprnds0->quick_push (vec_oprnd);
1545
1546   if (vec_oprnds1 && vec_oprnds1->length ())
1547     {
1548       vec_oprnd = vec_oprnds1->pop ();
1549       vec_oprnd = vect_get_vec_def_for_stmt_copy (dt[1], vec_oprnd);
1550       vec_oprnds1->quick_push (vec_oprnd);
1551     }
1552 }
1553
1554
1555 /* Get vectorized definitions for OP0 and OP1.  */
1556
1557 void
1558 vect_get_vec_defs (tree op0, tree op1, gimple *stmt,
1559                    vec<tree> *vec_oprnds0,
1560                    vec<tree> *vec_oprnds1,
1561                    slp_tree slp_node)
1562 {
1563   if (slp_node)
1564     {
1565       int nops = (op1 == NULL_TREE) ? 1 : 2;
1566       auto_vec<tree> ops (nops);
1567       auto_vec<vec<tree> > vec_defs (nops);
1568
1569       ops.quick_push (op0);
1570       if (op1)
1571         ops.quick_push (op1);
1572
1573       vect_get_slp_defs (ops, slp_node, &vec_defs);
1574
1575       *vec_oprnds0 = vec_defs[0];
1576       if (op1)
1577         *vec_oprnds1 = vec_defs[1];
1578     }
1579   else
1580     {
1581       tree vec_oprnd;
1582
1583       vec_oprnds0->create (1);
1584       vec_oprnd = vect_get_vec_def_for_operand (op0, stmt);
1585       vec_oprnds0->quick_push (vec_oprnd);
1586
1587       if (op1)
1588         {
1589           vec_oprnds1->create (1);
1590           vec_oprnd = vect_get_vec_def_for_operand (op1, stmt);
1591           vec_oprnds1->quick_push (vec_oprnd);
1592         }
1593     }
1594 }
1595
1596
1597 /* Function vect_finish_stmt_generation.
1598
1599    Insert a new stmt.  */
1600
1601 void
1602 vect_finish_stmt_generation (gimple *stmt, gimple *vec_stmt,
1603                              gimple_stmt_iterator *gsi)
1604 {
1605   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1606   vec_info *vinfo = stmt_info->vinfo;
1607
1608   gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
1609
1610   if (!gsi_end_p (*gsi)
1611       && gimple_has_mem_ops (vec_stmt))
1612     {
1613       gimple *at_stmt = gsi_stmt (*gsi);
1614       tree vuse = gimple_vuse (at_stmt);
1615       if (vuse && TREE_CODE (vuse) == SSA_NAME)
1616         {
1617           tree vdef = gimple_vdef (at_stmt);
1618           gimple_set_vuse (vec_stmt, gimple_vuse (at_stmt));
1619           /* If we have an SSA vuse and insert a store, update virtual
1620              SSA form to avoid triggering the renamer.  Do so only
1621              if we can easily see all uses - which is what almost always
1622              happens with the way vectorized stmts are inserted.  */
1623           if ((vdef && TREE_CODE (vdef) == SSA_NAME)
1624               && ((is_gimple_assign (vec_stmt)
1625                    && !is_gimple_reg (gimple_assign_lhs (vec_stmt)))
1626                   || (is_gimple_call (vec_stmt)
1627                       && !(gimple_call_flags (vec_stmt)
1628                            & (ECF_CONST|ECF_PURE|ECF_NOVOPS)))))
1629             {
1630               tree new_vdef = copy_ssa_name (vuse, vec_stmt);
1631               gimple_set_vdef (vec_stmt, new_vdef);
1632               SET_USE (gimple_vuse_op (at_stmt), new_vdef);
1633             }
1634         }
1635     }
1636   gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
1637
1638   set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, vinfo));
1639
1640   if (dump_enabled_p ())
1641     {
1642       dump_printf_loc (MSG_NOTE, vect_location, "add new stmt: ");
1643       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, vec_stmt, 0);
1644     }
1645
1646   gimple_set_location (vec_stmt, gimple_location (stmt));
1647
1648   /* While EH edges will generally prevent vectorization, stmt might
1649      e.g. be in a must-not-throw region.  Ensure newly created stmts
1650      that could throw are part of the same region.  */
1651   int lp_nr = lookup_stmt_eh_lp (stmt);
1652   if (lp_nr != 0 && stmt_could_throw_p (vec_stmt))
1653     add_stmt_to_eh_lp (vec_stmt, lp_nr);
1654 }
1655
1656 /* We want to vectorize a call to combined function CFN with function
1657    decl FNDECL, using VECTYPE_OUT as the type of the output and VECTYPE_IN
1658    as the types of all inputs.  Check whether this is possible using
1659    an internal function, returning its code if so or IFN_LAST if not.  */
1660
1661 static internal_fn
1662 vectorizable_internal_function (combined_fn cfn, tree fndecl,
1663                                 tree vectype_out, tree vectype_in)
1664 {
1665   internal_fn ifn;
1666   if (internal_fn_p (cfn))
1667     ifn = as_internal_fn (cfn);
1668   else
1669     ifn = associated_internal_fn (fndecl);
1670   if (ifn != IFN_LAST && direct_internal_fn_p (ifn))
1671     {
1672       const direct_internal_fn_info &info = direct_internal_fn (ifn);
1673       if (info.vectorizable)
1674         {
1675           tree type0 = (info.type0 < 0 ? vectype_out : vectype_in);
1676           tree type1 = (info.type1 < 0 ? vectype_out : vectype_in);
1677           if (direct_internal_fn_supported_p (ifn, tree_pair (type0, type1),
1678                                               OPTIMIZE_FOR_SPEED))
1679             return ifn;
1680         }
1681     }
1682   return IFN_LAST;
1683 }
1684
1685
1686 static tree permute_vec_elements (tree, tree, tree, gimple *,
1687                                   gimple_stmt_iterator *);
1688
1689 /* STMT is a non-strided load or store, meaning that it accesses
1690    elements with a known constant step.  Return -1 if that step
1691    is negative, 0 if it is zero, and 1 if it is greater than zero.  */
1692
1693 static int
1694 compare_step_with_zero (gimple *stmt)
1695 {
1696   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1697   data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1698   return tree_int_cst_compare (vect_dr_behavior (dr)->step,
1699                                size_zero_node);
1700 }
1701
1702 /* If the target supports a permute mask that reverses the elements in
1703    a vector of type VECTYPE, return that mask, otherwise return null.  */
1704
1705 static tree
1706 perm_mask_for_reverse (tree vectype)
1707 {
1708   int i, nunits;
1709   unsigned char *sel;
1710
1711   nunits = TYPE_VECTOR_SUBPARTS (vectype);
1712   sel = XALLOCAVEC (unsigned char, nunits);
1713
1714   for (i = 0; i < nunits; ++i)
1715     sel[i] = nunits - 1 - i;
1716
1717   if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
1718     return NULL_TREE;
1719   return vect_gen_perm_mask_checked (vectype, sel);
1720 }
1721
1722 /* A subroutine of get_load_store_type, with a subset of the same
1723    arguments.  Handle the case where STMT is part of a grouped load
1724    or store.
1725
1726    For stores, the statements in the group are all consecutive
1727    and there is no gap at the end.  For loads, the statements in the
1728    group might not be consecutive; there can be gaps between statements
1729    as well as at the end.  */
1730
1731 static bool
1732 get_group_load_store_type (gimple *stmt, tree vectype, bool slp,
1733                            vec_load_store_type vls_type,
1734                            vect_memory_access_type *memory_access_type)
1735 {
1736   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1737   vec_info *vinfo = stmt_info->vinfo;
1738   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1739   struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
1740   gimple *first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
1741   unsigned int group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
1742   bool single_element_p = (stmt == first_stmt
1743                            && !GROUP_NEXT_ELEMENT (stmt_info));
1744   unsigned HOST_WIDE_INT gap = GROUP_GAP (vinfo_for_stmt (first_stmt));
1745   unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype);
1746
1747   /* True if the vectorized statements would access beyond the last
1748      statement in the group.  */
1749   bool overrun_p = false;
1750
1751   /* True if we can cope with such overrun by peeling for gaps, so that
1752      there is at least one final scalar iteration after the vector loop.  */
1753   bool can_overrun_p = (vls_type == VLS_LOAD && loop_vinfo && !loop->inner);
1754
1755   /* There can only be a gap at the end of the group if the stride is
1756      known at compile time.  */
1757   gcc_assert (!STMT_VINFO_STRIDED_P (stmt_info) || gap == 0);
1758
1759   /* Stores can't yet have gaps.  */
1760   gcc_assert (slp || vls_type == VLS_LOAD || gap == 0);
1761
1762   if (slp)
1763     {
1764       if (STMT_VINFO_STRIDED_P (stmt_info))
1765         {
1766           /* Try to use consecutive accesses of GROUP_SIZE elements,
1767              separated by the stride, until we have a complete vector.
1768              Fall back to scalar accesses if that isn't possible.  */
1769           if (nunits % group_size == 0)
1770             *memory_access_type = VMAT_STRIDED_SLP;
1771           else
1772             *memory_access_type = VMAT_ELEMENTWISE;
1773         }
1774       else
1775         {
1776           overrun_p = loop_vinfo && gap != 0;
1777           if (overrun_p && vls_type != VLS_LOAD)
1778             {
1779               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1780                                "Grouped store with gaps requires"
1781                                " non-consecutive accesses\n");
1782               return false;
1783             }
1784           /* If the access is aligned an overrun is fine.  */
1785           if (overrun_p
1786               && aligned_access_p
1787                    (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt))))
1788             overrun_p = false;
1789           if (overrun_p && !can_overrun_p)
1790             {
1791               if (dump_enabled_p ())
1792                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1793                                  "Peeling for outer loop is not supported\n");
1794               return false;
1795             }
1796           *memory_access_type = VMAT_CONTIGUOUS;
1797         }
1798     }
1799   else
1800     {
1801       /* We can always handle this case using elementwise accesses,
1802          but see if something more efficient is available.  */
1803       *memory_access_type = VMAT_ELEMENTWISE;
1804
1805       /* If there is a gap at the end of the group then these optimizations
1806          would access excess elements in the last iteration.  */
1807       bool would_overrun_p = (gap != 0);
1808       /* If the access is aligned an overrun is fine, but only if the
1809          overrun is not inside an unused vector (if the gap is as large
1810          or larger than a vector).  */
1811       if (would_overrun_p
1812           && gap < nunits
1813           && aligned_access_p
1814                 (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt))))
1815         would_overrun_p = false;
1816       if (!STMT_VINFO_STRIDED_P (stmt_info)
1817           && (can_overrun_p || !would_overrun_p)
1818           && compare_step_with_zero (stmt) > 0)
1819         {
1820           /* First try using LOAD/STORE_LANES.  */
1821           if (vls_type == VLS_LOAD
1822               ? vect_load_lanes_supported (vectype, group_size)
1823               : vect_store_lanes_supported (vectype, group_size))
1824             {
1825               *memory_access_type = VMAT_LOAD_STORE_LANES;
1826               overrun_p = would_overrun_p;
1827             }
1828
1829           /* If that fails, try using permuting loads.  */
1830           if (*memory_access_type == VMAT_ELEMENTWISE
1831               && (vls_type == VLS_LOAD
1832                   ? vect_grouped_load_supported (vectype, single_element_p,
1833                                                  group_size)
1834                   : vect_grouped_store_supported (vectype, group_size)))
1835             {
1836               *memory_access_type = VMAT_CONTIGUOUS_PERMUTE;
1837               overrun_p = would_overrun_p;
1838             }
1839         }
1840     }
1841
1842   if (vls_type != VLS_LOAD && first_stmt == stmt)
1843     {
1844       /* STMT is the leader of the group. Check the operands of all the
1845          stmts of the group.  */
1846       gimple *next_stmt = GROUP_NEXT_ELEMENT (stmt_info);
1847       while (next_stmt)
1848         {
1849           gcc_assert (gimple_assign_single_p (next_stmt));
1850           tree op = gimple_assign_rhs1 (next_stmt);
1851           gimple *def_stmt;
1852           enum vect_def_type dt;
1853           if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt))
1854             {
1855               if (dump_enabled_p ())
1856                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1857                                  "use not simple.\n");
1858               return false;
1859             }
1860           next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
1861         }
1862     }
1863
1864   if (overrun_p)
1865     {
1866       gcc_assert (can_overrun_p);
1867       if (dump_enabled_p ())
1868         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1869                          "Data access with gaps requires scalar "
1870                          "epilogue loop\n");
1871       LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
1872     }
1873
1874   return true;
1875 }
1876
1877 /* A subroutine of get_load_store_type, with a subset of the same
1878    arguments.  Handle the case where STMT is a load or store that
1879    accesses consecutive elements with a negative step.  */
1880
1881 static vect_memory_access_type
1882 get_negative_load_store_type (gimple *stmt, tree vectype,
1883                               vec_load_store_type vls_type,
1884                               unsigned int ncopies)
1885 {
1886   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1887   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1888   dr_alignment_support alignment_support_scheme;
1889
1890   if (ncopies > 1)
1891     {
1892       if (dump_enabled_p ())
1893         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1894                          "multiple types with negative step.\n");
1895       return VMAT_ELEMENTWISE;
1896     }
1897
1898   alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
1899   if (alignment_support_scheme != dr_aligned
1900       && alignment_support_scheme != dr_unaligned_supported)
1901     {
1902       if (dump_enabled_p ())
1903         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1904                          "negative step but alignment required.\n");
1905       return VMAT_ELEMENTWISE;
1906     }
1907
1908   if (vls_type == VLS_STORE_INVARIANT)
1909     {
1910       if (dump_enabled_p ())
1911         dump_printf_loc (MSG_NOTE, vect_location,
1912                          "negative step with invariant source;"
1913                          " no permute needed.\n");
1914       return VMAT_CONTIGUOUS_DOWN;
1915     }
1916
1917   if (!perm_mask_for_reverse (vectype))
1918     {
1919       if (dump_enabled_p ())
1920         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1921                          "negative step and reversing not supported.\n");
1922       return VMAT_ELEMENTWISE;
1923     }
1924
1925   return VMAT_CONTIGUOUS_REVERSE;
1926 }
1927
1928 /* Analyze load or store statement STMT of type VLS_TYPE.  Return true
1929    if there is a memory access type that the vectorized form can use,
1930    storing it in *MEMORY_ACCESS_TYPE if so.  If we decide to use gathers
1931    or scatters, fill in GS_INFO accordingly.
1932
1933    SLP says whether we're performing SLP rather than loop vectorization.
1934    VECTYPE is the vector type that the vectorized statements will use.
1935    NCOPIES is the number of vector statements that will be needed.  */
1936
1937 static bool
1938 get_load_store_type (gimple *stmt, tree vectype, bool slp,
1939                      vec_load_store_type vls_type, unsigned int ncopies,
1940                      vect_memory_access_type *memory_access_type,
1941                      gather_scatter_info *gs_info)
1942 {
1943   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1944   vec_info *vinfo = stmt_info->vinfo;
1945   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1946   if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
1947     {
1948       *memory_access_type = VMAT_GATHER_SCATTER;
1949       gimple *def_stmt;
1950       if (!vect_check_gather_scatter (stmt, loop_vinfo, gs_info))
1951         gcc_unreachable ();
1952       else if (!vect_is_simple_use (gs_info->offset, vinfo, &def_stmt,
1953                                     &gs_info->offset_dt,
1954                                     &gs_info->offset_vectype))
1955         {
1956           if (dump_enabled_p ())
1957             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1958                              "%s index use not simple.\n",
1959                              vls_type == VLS_LOAD ? "gather" : "scatter");
1960           return false;
1961         }
1962     }
1963   else if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
1964     {
1965       if (!get_group_load_store_type (stmt, vectype, slp, vls_type,
1966                                       memory_access_type))
1967         return false;
1968     }
1969   else if (STMT_VINFO_STRIDED_P (stmt_info))
1970     {
1971       gcc_assert (!slp);
1972       *memory_access_type = VMAT_ELEMENTWISE;
1973     }
1974   else
1975     {
1976       int cmp = compare_step_with_zero (stmt);
1977       if (cmp < 0)
1978         *memory_access_type = get_negative_load_store_type
1979           (stmt, vectype, vls_type, ncopies);
1980       else if (cmp == 0)
1981         {
1982           gcc_assert (vls_type == VLS_LOAD);
1983           *memory_access_type = VMAT_INVARIANT;
1984         }
1985       else
1986         *memory_access_type = VMAT_CONTIGUOUS;
1987     }
1988
1989   /* FIXME: At the moment the cost model seems to underestimate the
1990      cost of using elementwise accesses.  This check preserves the
1991      traditional behavior until that can be fixed.  */
1992   if (*memory_access_type == VMAT_ELEMENTWISE
1993       && !STMT_VINFO_STRIDED_P (stmt_info))
1994     {
1995       if (dump_enabled_p ())
1996         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1997                          "not falling back to elementwise accesses\n");
1998       return false;
1999     }
2000   return true;
2001 }
2002
2003 /* Function vectorizable_mask_load_store.
2004
2005    Check if STMT performs a conditional load or store that can be vectorized.
2006    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
2007    stmt to replace it, put it in VEC_STMT, and insert it at GSI.
2008    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2009
2010 static bool
2011 vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
2012                               gimple **vec_stmt, slp_tree slp_node)
2013 {
2014   tree vec_dest = NULL;
2015   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2016   stmt_vec_info prev_stmt_info;
2017   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2018   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2019   bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
2020   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2021   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2022   tree rhs_vectype = NULL_TREE;
2023   tree mask_vectype;
2024   tree elem_type;
2025   gimple *new_stmt;
2026   tree dummy;
2027   tree dataref_ptr = NULL_TREE;
2028   gimple *ptr_incr;
2029   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
2030   int ncopies;
2031   int i, j;
2032   bool inv_p;
2033   gather_scatter_info gs_info;
2034   vec_load_store_type vls_type;
2035   tree mask;
2036   gimple *def_stmt;
2037   enum vect_def_type dt;
2038
2039   if (slp_node != NULL)
2040     return false;
2041
2042   ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
2043   gcc_assert (ncopies >= 1);
2044
2045   mask = gimple_call_arg (stmt, 2);
2046
2047   if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask)))
2048     return false;
2049
2050   /* FORNOW. This restriction should be relaxed.  */
2051   if (nested_in_vect_loop && ncopies > 1)
2052     {
2053       if (dump_enabled_p ())
2054         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2055                          "multiple types in nested loop.");
2056       return false;
2057     }
2058
2059   if (!STMT_VINFO_RELEVANT_P (stmt_info))
2060     return false;
2061
2062   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
2063       && ! vec_stmt)
2064     return false;
2065
2066   if (!STMT_VINFO_DATA_REF (stmt_info))
2067     return false;
2068
2069   elem_type = TREE_TYPE (vectype);
2070
2071   if (TREE_CODE (mask) != SSA_NAME)
2072     return false;
2073
2074   if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt, &mask_vectype))
2075     return false;
2076
2077   if (!mask_vectype)
2078     mask_vectype = get_mask_type_for_scalar_type (TREE_TYPE (vectype));
2079
2080   if (!mask_vectype || !VECTOR_BOOLEAN_TYPE_P (mask_vectype)
2081       || TYPE_VECTOR_SUBPARTS (mask_vectype) != TYPE_VECTOR_SUBPARTS (vectype))
2082     return false;
2083
2084   if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE)
2085     {
2086       tree rhs = gimple_call_arg (stmt, 3);
2087       if (!vect_is_simple_use (rhs, loop_vinfo, &def_stmt, &dt, &rhs_vectype))
2088         return false;
2089       if (dt == vect_constant_def || dt == vect_external_def)
2090         vls_type = VLS_STORE_INVARIANT;
2091       else
2092         vls_type = VLS_STORE;
2093     }
2094   else
2095     vls_type = VLS_LOAD;
2096
2097   vect_memory_access_type memory_access_type;
2098   if (!get_load_store_type (stmt, vectype, false, vls_type, ncopies,
2099                             &memory_access_type, &gs_info))
2100     return false;
2101
2102   if (memory_access_type == VMAT_GATHER_SCATTER)
2103     {
2104       tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gs_info.decl));
2105       tree masktype
2106         = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
2107       if (TREE_CODE (masktype) == INTEGER_TYPE)
2108         {
2109           if (dump_enabled_p ())
2110             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2111                              "masked gather with integer mask not supported.");
2112           return false;
2113         }
2114     }
2115   else if (memory_access_type != VMAT_CONTIGUOUS)
2116     {
2117       if (dump_enabled_p ())
2118         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2119                          "unsupported access type for masked %s.\n",
2120                          vls_type == VLS_LOAD ? "load" : "store");
2121       return false;
2122     }
2123   else if (!VECTOR_MODE_P (TYPE_MODE (vectype))
2124            || !can_vec_mask_load_store_p (TYPE_MODE (vectype),
2125                                           TYPE_MODE (mask_vectype),
2126                                           vls_type == VLS_LOAD)
2127            || (rhs_vectype
2128                && !useless_type_conversion_p (vectype, rhs_vectype)))
2129     return false;
2130
2131   if (!vec_stmt) /* transformation not required.  */
2132     {
2133       STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) = memory_access_type;
2134       STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
2135       if (vls_type == VLS_LOAD)
2136         vect_model_load_cost (stmt_info, ncopies, memory_access_type,
2137                               NULL, NULL, NULL);
2138       else
2139         vect_model_store_cost (stmt_info, ncopies, memory_access_type,
2140                                dt, NULL, NULL, NULL);
2141       return true;
2142     }
2143   gcc_assert (memory_access_type == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info));
2144
2145   /* Transform.  */
2146
2147   if (memory_access_type == VMAT_GATHER_SCATTER)
2148     {
2149       tree vec_oprnd0 = NULL_TREE, op;
2150       tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gs_info.decl));
2151       tree rettype, srctype, ptrtype, idxtype, masktype, scaletype;
2152       tree ptr, vec_mask = NULL_TREE, mask_op = NULL_TREE, var, scale;
2153       tree perm_mask = NULL_TREE, prev_res = NULL_TREE;
2154       tree mask_perm_mask = NULL_TREE;
2155       edge pe = loop_preheader_edge (loop);
2156       gimple_seq seq;
2157       basic_block new_bb;
2158       enum { NARROW, NONE, WIDEN } modifier;
2159       int gather_off_nunits = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype);
2160
2161       rettype = TREE_TYPE (TREE_TYPE (gs_info.decl));
2162       srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
2163       ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
2164       idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
2165       masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
2166       scaletype = TREE_VALUE (arglist);
2167       gcc_checking_assert (types_compatible_p (srctype, rettype)
2168                            && types_compatible_p (srctype, masktype));
2169
2170       if (nunits == gather_off_nunits)
2171         modifier = NONE;
2172       else if (nunits == gather_off_nunits / 2)
2173         {
2174           unsigned char *sel = XALLOCAVEC (unsigned char, gather_off_nunits);
2175           modifier = WIDEN;
2176
2177           for (i = 0; i < gather_off_nunits; ++i)
2178             sel[i] = i | nunits;
2179
2180           perm_mask = vect_gen_perm_mask_checked (gs_info.offset_vectype, sel);
2181         }
2182       else if (nunits == gather_off_nunits * 2)
2183         {
2184           unsigned char *sel = XALLOCAVEC (unsigned char, nunits);
2185           modifier = NARROW;
2186
2187           for (i = 0; i < nunits; ++i)
2188             sel[i] = i < gather_off_nunits
2189                      ? i : i + nunits - gather_off_nunits;
2190
2191           perm_mask = vect_gen_perm_mask_checked (vectype, sel);
2192           ncopies *= 2;
2193           for (i = 0; i < nunits; ++i)
2194             sel[i] = i | gather_off_nunits;
2195           mask_perm_mask = vect_gen_perm_mask_checked (masktype, sel);
2196         }
2197       else
2198         gcc_unreachable ();
2199
2200       vec_dest = vect_create_destination_var (gimple_call_lhs (stmt), vectype);
2201
2202       ptr = fold_convert (ptrtype, gs_info.base);
2203       if (!is_gimple_min_invariant (ptr))
2204         {
2205           ptr = force_gimple_operand (ptr, &seq, true, NULL_TREE);
2206           new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
2207           gcc_assert (!new_bb);
2208         }
2209
2210       scale = build_int_cst (scaletype, gs_info.scale);
2211
2212       prev_stmt_info = NULL;
2213       for (j = 0; j < ncopies; ++j)
2214         {
2215           if (modifier == WIDEN && (j & 1))
2216             op = permute_vec_elements (vec_oprnd0, vec_oprnd0,
2217                                        perm_mask, stmt, gsi);
2218           else if (j == 0)
2219             op = vec_oprnd0
2220               = vect_get_vec_def_for_operand (gs_info.offset, stmt);
2221           else
2222             op = vec_oprnd0
2223               = vect_get_vec_def_for_stmt_copy (gs_info.offset_dt, vec_oprnd0);
2224
2225           if (!useless_type_conversion_p (idxtype, TREE_TYPE (op)))
2226             {
2227               gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
2228                           == TYPE_VECTOR_SUBPARTS (idxtype));
2229               var = vect_get_new_ssa_name (idxtype, vect_simple_var);
2230               op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
2231               new_stmt
2232                 = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
2233               vect_finish_stmt_generation (stmt, new_stmt, gsi);
2234               op = var;
2235             }
2236
2237           if (mask_perm_mask && (j & 1))
2238             mask_op = permute_vec_elements (mask_op, mask_op,
2239                                             mask_perm_mask, stmt, gsi);
2240           else
2241             {
2242               if (j == 0)
2243                 vec_mask = vect_get_vec_def_for_operand (mask, stmt);
2244               else
2245                 {
2246                   vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
2247                   vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
2248                 }
2249
2250               mask_op = vec_mask;
2251               if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask)))
2252                 {
2253                   gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
2254                               == TYPE_VECTOR_SUBPARTS (masktype));
2255                   var = vect_get_new_ssa_name (masktype, vect_simple_var);
2256                   mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
2257                   new_stmt
2258                     = gimple_build_assign (var, VIEW_CONVERT_EXPR, mask_op);
2259                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
2260                   mask_op = var;
2261                 }
2262             }
2263
2264           new_stmt
2265             = gimple_build_call (gs_info.decl, 5, mask_op, ptr, op, mask_op,
2266                                  scale);
2267
2268           if (!useless_type_conversion_p (vectype, rettype))
2269             {
2270               gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
2271                           == TYPE_VECTOR_SUBPARTS (rettype));
2272               op = vect_get_new_ssa_name (rettype, vect_simple_var);
2273               gimple_call_set_lhs (new_stmt, op);
2274               vect_finish_stmt_generation (stmt, new_stmt, gsi);
2275               var = make_ssa_name (vec_dest);
2276               op = build1 (VIEW_CONVERT_EXPR, vectype, op);
2277               new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
2278             }
2279           else
2280             {
2281               var = make_ssa_name (vec_dest, new_stmt);
2282               gimple_call_set_lhs (new_stmt, var);
2283             }
2284
2285           vect_finish_stmt_generation (stmt, new_stmt, gsi);
2286
2287           if (modifier == NARROW)
2288             {
2289               if ((j & 1) == 0)
2290                 {
2291                   prev_res = var;
2292                   continue;
2293                 }
2294               var = permute_vec_elements (prev_res, var,
2295                                           perm_mask, stmt, gsi);
2296               new_stmt = SSA_NAME_DEF_STMT (var);
2297             }
2298
2299           if (prev_stmt_info == NULL)
2300             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2301           else
2302             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2303           prev_stmt_info = vinfo_for_stmt (new_stmt);
2304         }
2305
2306       /* Ensure that even with -fno-tree-dce the scalar MASK_LOAD is removed
2307          from the IL.  */
2308       if (STMT_VINFO_RELATED_STMT (stmt_info))
2309         {
2310           stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2311           stmt_info = vinfo_for_stmt (stmt);
2312         }
2313       tree lhs = gimple_call_lhs (stmt);
2314       new_stmt = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
2315       set_vinfo_for_stmt (new_stmt, stmt_info);
2316       set_vinfo_for_stmt (stmt, NULL);
2317       STMT_VINFO_STMT (stmt_info) = new_stmt;
2318       gsi_replace (gsi, new_stmt, true);
2319       return true;
2320     }
2321   else if (vls_type != VLS_LOAD)
2322     {
2323       tree vec_rhs = NULL_TREE, vec_mask = NULL_TREE;
2324       prev_stmt_info = NULL;
2325       LOOP_VINFO_HAS_MASK_STORE (loop_vinfo) = true;
2326       for (i = 0; i < ncopies; i++)
2327         {
2328           unsigned align, misalign;
2329
2330           if (i == 0)
2331             {
2332               tree rhs = gimple_call_arg (stmt, 3);
2333               vec_rhs = vect_get_vec_def_for_operand (rhs, stmt);
2334               vec_mask = vect_get_vec_def_for_operand (mask, stmt);
2335               /* We should have catched mismatched types earlier.  */
2336               gcc_assert (useless_type_conversion_p (vectype,
2337                                                      TREE_TYPE (vec_rhs)));
2338               dataref_ptr = vect_create_data_ref_ptr (stmt, vectype, NULL,
2339                                                       NULL_TREE, &dummy, gsi,
2340                                                       &ptr_incr, false, &inv_p);
2341               gcc_assert (!inv_p);
2342             }
2343           else
2344             {
2345               vect_is_simple_use (vec_rhs, loop_vinfo, &def_stmt, &dt);
2346               vec_rhs = vect_get_vec_def_for_stmt_copy (dt, vec_rhs);
2347               vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
2348               vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
2349               dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
2350                                              TYPE_SIZE_UNIT (vectype));
2351             }
2352
2353           align = TYPE_ALIGN_UNIT (vectype);
2354           if (aligned_access_p (dr))
2355             misalign = 0;
2356           else if (DR_MISALIGNMENT (dr) == -1)
2357             {
2358               align = TYPE_ALIGN_UNIT (elem_type);
2359               misalign = 0;
2360             }
2361           else
2362             misalign = DR_MISALIGNMENT (dr);
2363           set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
2364                                   misalign);
2365           tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
2366                                     misalign ? least_bit_hwi (misalign) : align);
2367           gcall *call
2368             = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr,
2369                                           ptr, vec_mask, vec_rhs);
2370           gimple_call_set_nothrow (call, true);
2371           new_stmt = call;
2372           vect_finish_stmt_generation (stmt, new_stmt, gsi);
2373           if (i == 0)
2374             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2375           else
2376             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2377           prev_stmt_info = vinfo_for_stmt (new_stmt);
2378         }
2379     }
2380   else
2381     {
2382       tree vec_mask = NULL_TREE;
2383       prev_stmt_info = NULL;
2384       vec_dest = vect_create_destination_var (gimple_call_lhs (stmt), vectype);
2385       for (i = 0; i < ncopies; i++)
2386         {
2387           unsigned align, misalign;
2388
2389           if (i == 0)
2390             {
2391               vec_mask = vect_get_vec_def_for_operand (mask, stmt);
2392               dataref_ptr = vect_create_data_ref_ptr (stmt, vectype, NULL,
2393                                                       NULL_TREE, &dummy, gsi,
2394                                                       &ptr_incr, false, &inv_p);
2395               gcc_assert (!inv_p);
2396             }
2397           else
2398             {
2399               vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
2400               vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
2401               dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
2402                                              TYPE_SIZE_UNIT (vectype));
2403             }
2404
2405           align = TYPE_ALIGN_UNIT (vectype);
2406           if (aligned_access_p (dr))
2407             misalign = 0;
2408           else if (DR_MISALIGNMENT (dr) == -1)
2409             {
2410               align = TYPE_ALIGN_UNIT (elem_type);
2411               misalign = 0;
2412             }
2413           else
2414             misalign = DR_MISALIGNMENT (dr);
2415           set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
2416                                   misalign);
2417           tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
2418                                     misalign ? least_bit_hwi (misalign) : align);
2419           gcall *call
2420             = gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr,
2421                                           ptr, vec_mask);
2422           gimple_call_set_lhs (call, make_ssa_name (vec_dest));
2423           gimple_call_set_nothrow (call, true);
2424           vect_finish_stmt_generation (stmt, call, gsi);
2425           if (i == 0)
2426             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = call;
2427           else
2428             STMT_VINFO_RELATED_STMT (prev_stmt_info) = call;
2429           prev_stmt_info = vinfo_for_stmt (call);
2430         }
2431     }
2432
2433   if (vls_type == VLS_LOAD)
2434     {
2435       /* Ensure that even with -fno-tree-dce the scalar MASK_LOAD is removed
2436          from the IL.  */
2437       if (STMT_VINFO_RELATED_STMT (stmt_info))
2438         {
2439           stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2440           stmt_info = vinfo_for_stmt (stmt);
2441         }
2442       tree lhs = gimple_call_lhs (stmt);
2443       new_stmt = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
2444       set_vinfo_for_stmt (new_stmt, stmt_info);
2445       set_vinfo_for_stmt (stmt, NULL);
2446       STMT_VINFO_STMT (stmt_info) = new_stmt;
2447       gsi_replace (gsi, new_stmt, true);
2448     }
2449
2450   return true;
2451 }
2452
2453 /* Check and perform vectorization of BUILT_IN_BSWAP{16,32,64}.  */
2454
2455 static bool
2456 vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi,
2457                     gimple **vec_stmt, slp_tree slp_node,
2458                     tree vectype_in, enum vect_def_type *dt)
2459 {
2460   tree op, vectype;
2461   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2462   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2463   unsigned ncopies, nunits;
2464
2465   op = gimple_call_arg (stmt, 0);
2466   vectype = STMT_VINFO_VECTYPE (stmt_info);
2467   nunits = TYPE_VECTOR_SUBPARTS (vectype);
2468
2469   /* Multiple types in SLP are handled by creating the appropriate number of
2470      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
2471      case of SLP.  */
2472   if (slp_node)
2473     ncopies = 1;
2474   else
2475     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
2476
2477   gcc_assert (ncopies >= 1);
2478
2479   tree char_vectype = get_same_sized_vectype (char_type_node, vectype_in);
2480   if (! char_vectype)
2481     return false;
2482
2483   unsigned char *elts
2484     = XALLOCAVEC (unsigned char, TYPE_VECTOR_SUBPARTS (char_vectype));
2485   unsigned char *elt = elts;
2486   unsigned word_bytes = TYPE_VECTOR_SUBPARTS (char_vectype) / nunits;
2487   for (unsigned i = 0; i < nunits; ++i)
2488     for (unsigned j = 0; j < word_bytes; ++j)
2489       *elt++ = (i + 1) * word_bytes - j - 1;
2490
2491   if (! can_vec_perm_p (TYPE_MODE (char_vectype), false, elts))
2492     return false;
2493
2494   if (! vec_stmt)
2495     {
2496       STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
2497       if (dump_enabled_p ())
2498         dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_bswap ==="
2499                          "\n");
2500       if (! PURE_SLP_STMT (stmt_info))
2501         {
2502           add_stmt_cost (stmt_info->vinfo->target_cost_data,
2503                          1, vector_stmt, stmt_info, 0, vect_prologue);
2504           add_stmt_cost (stmt_info->vinfo->target_cost_data,
2505                          ncopies, vec_perm, stmt_info, 0, vect_body);
2506         }
2507       return true;
2508     }
2509
2510   tree *telts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (char_vectype));
2511   for (unsigned i = 0; i < TYPE_VECTOR_SUBPARTS (char_vectype); ++i)
2512     telts[i] = build_int_cst (char_type_node, elts[i]);
2513   tree bswap_vconst = build_vector (char_vectype, telts);
2514
2515   /* Transform.  */
2516   vec<tree> vec_oprnds = vNULL;
2517   gimple *new_stmt = NULL;
2518   stmt_vec_info prev_stmt_info = NULL;
2519   for (unsigned j = 0; j < ncopies; j++)
2520     {
2521       /* Handle uses.  */
2522       if (j == 0)
2523         vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
2524       else
2525         vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
2526
2527       /* Arguments are ready. create the new vector stmt.  */
2528       unsigned i;
2529       tree vop;
2530       FOR_EACH_VEC_ELT (vec_oprnds, i, vop)
2531        {
2532          tree tem = make_ssa_name (char_vectype);
2533          new_stmt = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR,
2534                                                       char_vectype, vop));
2535          vect_finish_stmt_generation (stmt, new_stmt, gsi);
2536          tree tem2 = make_ssa_name (char_vectype);
2537          new_stmt = gimple_build_assign (tem2, VEC_PERM_EXPR,
2538                                          tem, tem, bswap_vconst);
2539          vect_finish_stmt_generation (stmt, new_stmt, gsi);
2540          tem = make_ssa_name (vectype);
2541          new_stmt = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR,
2542                                                       vectype, tem2));
2543          vect_finish_stmt_generation (stmt, new_stmt, gsi);
2544          if (slp_node)
2545            SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
2546        }
2547
2548       if (slp_node)
2549         continue;
2550
2551       if (j == 0)
2552         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2553       else
2554         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2555
2556       prev_stmt_info = vinfo_for_stmt (new_stmt);
2557     }
2558
2559   vec_oprnds.release ();
2560   return true;
2561 }
2562
2563 /* Return true if vector types VECTYPE_IN and VECTYPE_OUT have
2564    integer elements and if we can narrow VECTYPE_IN to VECTYPE_OUT
2565    in a single step.  On success, store the binary pack code in
2566    *CONVERT_CODE.  */
2567
2568 static bool
2569 simple_integer_narrowing (tree vectype_out, tree vectype_in,
2570                           tree_code *convert_code)
2571 {
2572   if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype_out))
2573       || !INTEGRAL_TYPE_P (TREE_TYPE (vectype_in)))
2574     return false;
2575
2576   tree_code code;
2577   int multi_step_cvt = 0;
2578   auto_vec <tree, 8> interm_types;
2579   if (!supportable_narrowing_operation (NOP_EXPR, vectype_out, vectype_in,
2580                                         &code, &multi_step_cvt,
2581                                         &interm_types)
2582       || multi_step_cvt)
2583     return false;
2584
2585   *convert_code = code;
2586   return true;
2587 }
2588
2589 /* Function vectorizable_call.
2590
2591    Check if GS performs a function call that can be vectorized.
2592    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
2593    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2594    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2595
2596 static bool
2597 vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
2598                    slp_tree slp_node)
2599 {
2600   gcall *stmt;
2601   tree vec_dest;
2602   tree scalar_dest;
2603   tree op, type;
2604   tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
2605   stmt_vec_info stmt_info = vinfo_for_stmt (gs), prev_stmt_info;
2606   tree vectype_out, vectype_in;
2607   int nunits_in;
2608   int nunits_out;
2609   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2610   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
2611   vec_info *vinfo = stmt_info->vinfo;
2612   tree fndecl, new_temp, rhs_type;
2613   gimple *def_stmt;
2614   enum vect_def_type dt[3]
2615     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
2616   int ndts = 3;
2617   gimple *new_stmt = NULL;
2618   int ncopies, j;
2619   vec<tree> vargs = vNULL;
2620   enum { NARROW, NONE, WIDEN } modifier;
2621   size_t i, nargs;
2622   tree lhs;
2623
2624   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
2625     return false;
2626
2627   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
2628       && ! vec_stmt)
2629     return false;
2630
2631   /* Is GS a vectorizable call?   */
2632   stmt = dyn_cast <gcall *> (gs);
2633   if (!stmt)
2634     return false;
2635
2636   if (gimple_call_internal_p (stmt)
2637       && (gimple_call_internal_fn (stmt) == IFN_MASK_LOAD
2638           || gimple_call_internal_fn (stmt) == IFN_MASK_STORE))
2639     return vectorizable_mask_load_store (stmt, gsi, vec_stmt,
2640                                          slp_node);
2641
2642   if (gimple_call_lhs (stmt) == NULL_TREE
2643       || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
2644     return false;
2645
2646   gcc_checking_assert (!stmt_can_throw_internal (stmt));
2647
2648   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
2649
2650   /* Process function arguments.  */
2651   rhs_type = NULL_TREE;
2652   vectype_in = NULL_TREE;
2653   nargs = gimple_call_num_args (stmt);
2654
2655   /* Bail out if the function has more than three arguments, we do not have
2656      interesting builtin functions to vectorize with more than two arguments
2657      except for fma.  No arguments is also not good.  */
2658   if (nargs == 0 || nargs > 3)
2659     return false;
2660
2661   /* Ignore the argument of IFN_GOMP_SIMD_LANE, it is magic.  */
2662   if (gimple_call_internal_p (stmt)
2663       && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
2664     {
2665       nargs = 0;
2666       rhs_type = unsigned_type_node;
2667     }
2668
2669   for (i = 0; i < nargs; i++)
2670     {
2671       tree opvectype;
2672
2673       op = gimple_call_arg (stmt, i);
2674
2675       /* We can only handle calls with arguments of the same type.  */
2676       if (rhs_type
2677           && !types_compatible_p (rhs_type, TREE_TYPE (op)))
2678         {
2679           if (dump_enabled_p ())
2680             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2681                              "argument types differ.\n");
2682           return false;
2683         }
2684       if (!rhs_type)
2685         rhs_type = TREE_TYPE (op);
2686
2687       if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[i], &opvectype))
2688         {
2689           if (dump_enabled_p ())
2690             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2691                              "use not simple.\n");
2692           return false;
2693         }
2694
2695       if (!vectype_in)
2696         vectype_in = opvectype;
2697       else if (opvectype
2698                && opvectype != vectype_in)
2699         {
2700           if (dump_enabled_p ())
2701             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2702                              "argument vector types differ.\n");
2703           return false;
2704         }
2705     }
2706   /* If all arguments are external or constant defs use a vector type with
2707      the same size as the output vector type.  */
2708   if (!vectype_in)
2709     vectype_in = get_same_sized_vectype (rhs_type, vectype_out);
2710   if (vec_stmt)
2711     gcc_assert (vectype_in);
2712   if (!vectype_in)
2713     {
2714       if (dump_enabled_p ())
2715         {
2716           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2717                            "no vectype for scalar type ");
2718           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type);
2719           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
2720         }
2721
2722       return false;
2723     }
2724
2725   /* FORNOW */
2726   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
2727   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
2728   if (nunits_in == nunits_out / 2)
2729     modifier = NARROW;
2730   else if (nunits_out == nunits_in)
2731     modifier = NONE;
2732   else if (nunits_out == nunits_in / 2)
2733     modifier = WIDEN;
2734   else
2735     return false;
2736
2737   /* We only handle functions that do not read or clobber memory.  */
2738   if (gimple_vuse (stmt))
2739     {
2740       if (dump_enabled_p ())
2741         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2742                          "function reads from or writes to memory.\n");
2743       return false;
2744     }
2745
2746   /* For now, we only vectorize functions if a target specific builtin
2747      is available.  TODO -- in some cases, it might be profitable to
2748      insert the calls for pieces of the vector, in order to be able
2749      to vectorize other operations in the loop.  */
2750   fndecl = NULL_TREE;
2751   internal_fn ifn = IFN_LAST;
2752   combined_fn cfn = gimple_call_combined_fn (stmt);
2753   tree callee = gimple_call_fndecl (stmt);
2754
2755   /* First try using an internal function.  */
2756   tree_code convert_code = ERROR_MARK;
2757   if (cfn != CFN_LAST
2758       && (modifier == NONE
2759           || (modifier == NARROW
2760               && simple_integer_narrowing (vectype_out, vectype_in,
2761                                            &convert_code))))
2762     ifn = vectorizable_internal_function (cfn, callee, vectype_out,
2763                                           vectype_in);
2764
2765   /* If that fails, try asking for a target-specific built-in function.  */
2766   if (ifn == IFN_LAST)
2767     {
2768       if (cfn != CFN_LAST)
2769         fndecl = targetm.vectorize.builtin_vectorized_function
2770           (cfn, vectype_out, vectype_in);
2771       else
2772         fndecl = targetm.vectorize.builtin_md_vectorized_function
2773           (callee, vectype_out, vectype_in);
2774     }
2775
2776   if (ifn == IFN_LAST && !fndecl)
2777     {
2778       if (cfn == CFN_GOMP_SIMD_LANE
2779           && !slp_node
2780           && loop_vinfo
2781           && LOOP_VINFO_LOOP (loop_vinfo)->simduid
2782           && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
2783           && LOOP_VINFO_LOOP (loop_vinfo)->simduid
2784              == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))
2785         {
2786           /* We can handle IFN_GOMP_SIMD_LANE by returning a
2787              { 0, 1, 2, ... vf - 1 } vector.  */
2788           gcc_assert (nargs == 0);
2789         }
2790       else if (modifier == NONE
2791                && (gimple_call_builtin_p (stmt, BUILT_IN_BSWAP16)
2792                    || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP32)
2793                    || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP64)))
2794         return vectorizable_bswap (stmt, gsi, vec_stmt, slp_node,
2795                                    vectype_in, dt);
2796       else
2797         {
2798           if (dump_enabled_p ())
2799             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2800                              "function is not vectorizable.\n");
2801           return false;
2802         }
2803     }
2804
2805   if (slp_node)
2806     ncopies = 1;
2807   else if (modifier == NARROW && ifn == IFN_LAST)
2808     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
2809   else
2810     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
2811
2812   /* Sanity check: make sure that at least one copy of the vectorized stmt
2813      needs to be generated.  */
2814   gcc_assert (ncopies >= 1);
2815
2816   if (!vec_stmt) /* transformation not required.  */
2817     {
2818       STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
2819       if (dump_enabled_p ())
2820         dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_call ==="
2821                          "\n");
2822       vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
2823       if (ifn != IFN_LAST && modifier == NARROW && !slp_node)
2824         add_stmt_cost (stmt_info->vinfo->target_cost_data, ncopies / 2,
2825                        vec_promote_demote, stmt_info, 0, vect_body);
2826
2827       return true;
2828     }
2829
2830   /* Transform.  */
2831
2832   if (dump_enabled_p ())
2833     dump_printf_loc (MSG_NOTE, vect_location, "transform call.\n");
2834
2835   /* Handle def.  */
2836   scalar_dest = gimple_call_lhs (stmt);
2837   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
2838
2839   prev_stmt_info = NULL;
2840   if (modifier == NONE || ifn != IFN_LAST)
2841     {
2842       tree prev_res = NULL_TREE;
2843       for (j = 0; j < ncopies; ++j)
2844         {
2845           /* Build argument list for the vectorized call.  */
2846           if (j == 0)
2847             vargs.create (nargs);
2848           else
2849             vargs.truncate (0);
2850
2851           if (slp_node)
2852             {
2853               auto_vec<vec<tree> > vec_defs (nargs);
2854               vec<tree> vec_oprnds0;
2855
2856               for (i = 0; i < nargs; i++)
2857                 vargs.quick_push (gimple_call_arg (stmt, i));
2858               vect_get_slp_defs (vargs, slp_node, &vec_defs);
2859               vec_oprnds0 = vec_defs[0];
2860
2861               /* Arguments are ready.  Create the new vector stmt.  */
2862               FOR_EACH_VEC_ELT (vec_oprnds0, i, vec_oprnd0)
2863                 {
2864                   size_t k;
2865                   for (k = 0; k < nargs; k++)
2866                     {
2867                       vec<tree> vec_oprndsk = vec_defs[k];
2868                       vargs[k] = vec_oprndsk[i];
2869                     }
2870                   if (modifier == NARROW)
2871                     {
2872                       tree half_res = make_ssa_name (vectype_in);
2873                       gcall *call
2874                         = gimple_build_call_internal_vec (ifn, vargs);
2875                       gimple_call_set_lhs (call, half_res);
2876                       gimple_call_set_nothrow (call, true);
2877                       new_stmt = call;
2878                       vect_finish_stmt_generation (stmt, new_stmt, gsi);
2879                       if ((i & 1) == 0)
2880                         {
2881                           prev_res = half_res;
2882                           continue;
2883                         }
2884                       new_temp = make_ssa_name (vec_dest);
2885                       new_stmt = gimple_build_assign (new_temp, convert_code,
2886                                                       prev_res, half_res);
2887                     }
2888                   else
2889                     {
2890                       gcall *call;
2891                       if (ifn != IFN_LAST)
2892                         call = gimple_build_call_internal_vec (ifn, vargs);
2893                       else
2894                         call = gimple_build_call_vec (fndecl, vargs);
2895                       new_temp = make_ssa_name (vec_dest, call);
2896                       gimple_call_set_lhs (call, new_temp);
2897                       gimple_call_set_nothrow (call, true);
2898                       new_stmt = call;
2899                     }
2900                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
2901                   SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
2902                 }
2903
2904               for (i = 0; i < nargs; i++)
2905                 {
2906                   vec<tree> vec_oprndsi = vec_defs[i];
2907                   vec_oprndsi.release ();
2908                 }
2909               continue;
2910             }
2911
2912           for (i = 0; i < nargs; i++)
2913             {
2914               op = gimple_call_arg (stmt, i);
2915               if (j == 0)
2916                 vec_oprnd0
2917                   = vect_get_vec_def_for_operand (op, stmt);
2918               else
2919                 {
2920                   vec_oprnd0 = gimple_call_arg (new_stmt, i);
2921                   vec_oprnd0
2922                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
2923                 }
2924
2925               vargs.quick_push (vec_oprnd0);
2926             }
2927
2928           if (gimple_call_internal_p (stmt)
2929               && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
2930             {
2931               tree *v = XALLOCAVEC (tree, nunits_out);
2932               int k;
2933               for (k = 0; k < nunits_out; ++k)
2934                 v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k);
2935               tree cst = build_vector (vectype_out, v);
2936               tree new_var
2937                 = vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_");
2938               gimple *init_stmt = gimple_build_assign (new_var, cst);
2939               vect_init_vector_1 (stmt, init_stmt, NULL);
2940               new_temp = make_ssa_name (vec_dest);
2941               new_stmt = gimple_build_assign (new_temp, new_var);
2942             }
2943           else if (modifier == NARROW)
2944             {
2945               tree half_res = make_ssa_name (vectype_in);
2946               gcall *call = gimple_build_call_internal_vec (ifn, vargs);
2947               gimple_call_set_lhs (call, half_res);
2948               gimple_call_set_nothrow (call, true);
2949               new_stmt = call;
2950               vect_finish_stmt_generation (stmt, new_stmt, gsi);
2951               if ((j & 1) == 0)
2952                 {
2953                   prev_res = half_res;
2954                   continue;
2955                 }
2956               new_temp = make_ssa_name (vec_dest);
2957               new_stmt = gimple_build_assign (new_temp, convert_code,
2958                                               prev_res, half_res);
2959             }
2960           else
2961             {
2962               gcall *call;
2963               if (ifn != IFN_LAST)
2964                 call = gimple_build_call_internal_vec (ifn, vargs);
2965               else
2966                 call = gimple_build_call_vec (fndecl, vargs);
2967               new_temp = make_ssa_name (vec_dest, new_stmt);
2968               gimple_call_set_lhs (call, new_temp);
2969               gimple_call_set_nothrow (call, true);
2970               new_stmt = call;
2971             }
2972           vect_finish_stmt_generation (stmt, new_stmt, gsi);
2973
2974           if (j == (modifier == NARROW ? 1 : 0))
2975             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2976           else
2977             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2978
2979           prev_stmt_info = vinfo_for_stmt (new_stmt);
2980         }
2981     }
2982   else if (modifier == NARROW)
2983     {
2984       for (j = 0; j < ncopies; ++j)
2985         {
2986           /* Build argument list for the vectorized call.  */
2987           if (j == 0)
2988             vargs.create (nargs * 2);
2989           else
2990             vargs.truncate (0);
2991
2992           if (slp_node)
2993             {
2994               auto_vec<vec<tree> > vec_defs (nargs);
2995               vec<tree> vec_oprnds0;
2996
2997               for (i = 0; i < nargs; i++)
2998                 vargs.quick_push (gimple_call_arg (stmt, i));
2999               vect_get_slp_defs (vargs, slp_node, &vec_defs);
3000               vec_oprnds0 = vec_defs[0];
3001
3002               /* Arguments are ready.  Create the new vector stmt.  */
3003               for (i = 0; vec_oprnds0.iterate (i, &vec_oprnd0); i += 2)
3004                 {
3005                   size_t k;
3006                   vargs.truncate (0);
3007                   for (k = 0; k < nargs; k++)
3008                     {
3009                       vec<tree> vec_oprndsk = vec_defs[k];
3010                       vargs.quick_push (vec_oprndsk[i]);
3011                       vargs.quick_push (vec_oprndsk[i + 1]);
3012                     }
3013                   gcall *call;
3014                   if (ifn != IFN_LAST)
3015                     call = gimple_build_call_internal_vec (ifn, vargs);
3016                   else
3017                     call = gimple_build_call_vec (fndecl, vargs);
3018                   new_temp = make_ssa_name (vec_dest, call);
3019                   gimple_call_set_lhs (call, new_temp);
3020                   gimple_call_set_nothrow (call, true);
3021                   new_stmt = call;
3022                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3023                   SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
3024                 }
3025
3026               for (i = 0; i < nargs; i++)
3027                 {
3028                   vec<tree> vec_oprndsi = vec_defs[i];
3029                   vec_oprndsi.release ();
3030                 }
3031               continue;
3032             }
3033
3034           for (i = 0; i < nargs; i++)
3035             {
3036               op = gimple_call_arg (stmt, i);
3037               if (j == 0)
3038                 {
3039                   vec_oprnd0
3040                     = vect_get_vec_def_for_operand (op, stmt);
3041                   vec_oprnd1
3042                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
3043                 }
3044               else
3045                 {
3046                   vec_oprnd1 = gimple_call_arg (new_stmt, 2*i + 1);
3047                   vec_oprnd0
3048                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd1);
3049                   vec_oprnd1
3050                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
3051                 }
3052
3053               vargs.quick_push (vec_oprnd0);
3054               vargs.quick_push (vec_oprnd1);
3055             }
3056
3057           new_stmt = gimple_build_call_vec (fndecl, vargs);
3058           new_temp = make_ssa_name (vec_dest, new_stmt);
3059           gimple_call_set_lhs (new_stmt, new_temp);
3060           vect_finish_stmt_generation (stmt, new_stmt, gsi);
3061
3062           if (j == 0)
3063             STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
3064           else
3065             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3066
3067           prev_stmt_info = vinfo_for_stmt (new_stmt);
3068         }
3069
3070       *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
3071     }
3072   else
3073     /* No current target implements this case.  */
3074     return false;
3075
3076   vargs.release ();
3077
3078   /* The call in STMT might prevent it from being removed in dce.
3079      We however cannot remove it here, due to the way the ssa name
3080      it defines is mapped to the new definition.  So just replace
3081      rhs of the statement with something harmless.  */
3082
3083   if (slp_node)
3084     return true;
3085
3086   type = TREE_TYPE (scalar_dest);
3087   if (is_pattern_stmt_p (stmt_info))
3088     lhs = gimple_call_lhs (STMT_VINFO_RELATED_STMT (stmt_info));
3089   else
3090     lhs = gimple_call_lhs (stmt);
3091
3092   new_stmt = gimple_build_assign (lhs, build_zero_cst (type));
3093   set_vinfo_for_stmt (new_stmt, stmt_info);
3094   set_vinfo_for_stmt (stmt, NULL);
3095   STMT_VINFO_STMT (stmt_info) = new_stmt;
3096   gsi_replace (gsi, new_stmt, false);
3097
3098   return true;
3099 }
3100
3101
3102 struct simd_call_arg_info
3103 {
3104   tree vectype;
3105   tree op;
3106   HOST_WIDE_INT linear_step;
3107   enum vect_def_type dt;
3108   unsigned int align;
3109   bool simd_lane_linear;
3110 };
3111
3112 /* Helper function of vectorizable_simd_clone_call.  If OP, an SSA_NAME,
3113    is linear within simd lane (but not within whole loop), note it in
3114    *ARGINFO.  */
3115
3116 static void
3117 vect_simd_lane_linear (tree op, struct loop *loop,
3118                        struct simd_call_arg_info *arginfo)
3119 {
3120   gimple *def_stmt = SSA_NAME_DEF_STMT (op);
3121
3122   if (!is_gimple_assign (def_stmt)
3123       || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR
3124       || !is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
3125     return;
3126
3127   tree base = gimple_assign_rhs1 (def_stmt);
3128   HOST_WIDE_INT linear_step = 0;
3129   tree v = gimple_assign_rhs2 (def_stmt);
3130   while (TREE_CODE (v) == SSA_NAME)
3131     {
3132       tree t;
3133       def_stmt = SSA_NAME_DEF_STMT (v);
3134       if (is_gimple_assign (def_stmt))
3135         switch (gimple_assign_rhs_code (def_stmt))
3136           {
3137           case PLUS_EXPR:
3138             t = gimple_assign_rhs2 (def_stmt);
3139             if (linear_step || TREE_CODE (t) != INTEGER_CST)
3140               return;
3141             base = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), base, t);
3142             v = gimple_assign_rhs1 (def_stmt);
3143             continue;
3144           case MULT_EXPR:
3145             t = gimple_assign_rhs2 (def_stmt);
3146             if (linear_step || !tree_fits_shwi_p (t) || integer_zerop (t))
3147               return;
3148             linear_step = tree_to_shwi (t);
3149             v = gimple_assign_rhs1 (def_stmt);
3150             continue;
3151           CASE_CONVERT:
3152             t = gimple_assign_rhs1 (def_stmt);
3153             if (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
3154                 || (TYPE_PRECISION (TREE_TYPE (v))
3155                     < TYPE_PRECISION (TREE_TYPE (t))))
3156               return;
3157             if (!linear_step)
3158               linear_step = 1;
3159             v = t;
3160             continue;
3161           default:
3162             return;
3163           }
3164       else if (gimple_call_internal_p (def_stmt, IFN_GOMP_SIMD_LANE)
3165                && loop->simduid
3166                && TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME
3167                && (SSA_NAME_VAR (gimple_call_arg (def_stmt, 0))
3168                    == loop->simduid))
3169         {
3170           if (!linear_step)
3171             linear_step = 1;
3172           arginfo->linear_step = linear_step;
3173           arginfo->op = base;
3174           arginfo->simd_lane_linear = true;
3175           return;
3176         }
3177     }
3178 }
3179
3180 /* Function vectorizable_simd_clone_call.
3181
3182    Check if STMT performs a function call that can be vectorized
3183    by calling a simd clone of the function.
3184    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3185    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
3186    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
3187
3188 static bool
3189 vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
3190                               gimple **vec_stmt, slp_tree slp_node)
3191 {
3192   tree vec_dest;
3193   tree scalar_dest;
3194   tree op, type;
3195   tree vec_oprnd0 = NULL_TREE;
3196   stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
3197   tree vectype;
3198   unsigned int nunits;
3199   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3200   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
3201   vec_info *vinfo = stmt_info->vinfo;
3202   struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
3203   tree fndecl, new_temp;
3204   gimple *def_stmt;
3205   gimple *new_stmt = NULL;
3206   int ncopies, j;
3207   auto_vec<simd_call_arg_info> arginfo;
3208   vec<tree> vargs = vNULL;
3209   size_t i, nargs;
3210   tree lhs, rtype, ratype;
3211   vec<constructor_elt, va_gc> *ret_ctor_elts;
3212
3213   /* Is STMT a vectorizable call?   */
3214   if (!is_gimple_call (stmt))
3215     return false;
3216
3217   fndecl = gimple_call_fndecl (stmt);
3218   if (fndecl == NULL_TREE)
3219     return false;
3220
3221   struct cgraph_node *node = cgraph_node::get (fndecl);
3222   if (node == NULL || node->simd_clones == NULL)
3223     return false;
3224
3225   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
3226     return false;
3227
3228   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
3229       && ! vec_stmt)
3230     return false;
3231
3232   if (gimple_call_lhs (stmt)
3233       && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
3234     return false;
3235
3236   gcc_checking_assert (!stmt_can_throw_internal (stmt));
3237
3238   vectype = STMT_VINFO_VECTYPE (stmt_info);
3239
3240   if (loop_vinfo && nested_in_vect_loop_p (loop, stmt))
3241     return false;
3242
3243   /* FORNOW */
3244   if (slp_node)
3245     return false;
3246
3247   /* Process function arguments.  */
3248   nargs = gimple_call_num_args (stmt);
3249
3250   /* Bail out if the function has zero arguments.  */
3251   if (nargs == 0)
3252     return false;
3253
3254   arginfo.reserve (nargs, true);
3255
3256   for (i = 0; i < nargs; i++)
3257     {
3258       simd_call_arg_info thisarginfo;
3259       affine_iv iv;
3260
3261       thisarginfo.linear_step = 0;
3262       thisarginfo.align = 0;
3263       thisarginfo.op = NULL_TREE;
3264       thisarginfo.simd_lane_linear = false;
3265
3266       op = gimple_call_arg (stmt, i);
3267       if (!vect_is_simple_use (op, vinfo, &def_stmt, &thisarginfo.dt,
3268                                &thisarginfo.vectype)
3269           || thisarginfo.dt == vect_uninitialized_def)
3270         {
3271           if (dump_enabled_p ())
3272             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3273                              "use not simple.\n");
3274           return false;
3275         }
3276
3277       if (thisarginfo.dt == vect_constant_def
3278           || thisarginfo.dt == vect_external_def)
3279         gcc_assert (thisarginfo.vectype == NULL_TREE);
3280       else
3281         gcc_assert (thisarginfo.vectype != NULL_TREE);
3282
3283       /* For linear arguments, the analyze phase should have saved
3284          the base and step in STMT_VINFO_SIMD_CLONE_INFO.  */
3285       if (i * 3 + 4 <= STMT_VINFO_SIMD_CLONE_INFO (stmt_info).length ()
3286           && STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 3 + 2])
3287         {
3288           gcc_assert (vec_stmt);
3289           thisarginfo.linear_step
3290             = tree_to_shwi (STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 3 + 2]);
3291           thisarginfo.op
3292             = STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 3 + 1];
3293           thisarginfo.simd_lane_linear
3294             = (STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 3 + 3]
3295                == boolean_true_node);
3296           /* If loop has been peeled for alignment, we need to adjust it.  */
3297           tree n1 = LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo);
3298           tree n2 = LOOP_VINFO_NITERS (loop_vinfo);
3299           if (n1 != n2 && !thisarginfo.simd_lane_linear)
3300             {
3301               tree bias = fold_build2 (MINUS_EXPR, TREE_TYPE (n1), n1, n2);
3302               tree step = STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 3 + 2];
3303               tree opt = TREE_TYPE (thisarginfo.op);
3304               bias = fold_convert (TREE_TYPE (step), bias);
3305               bias = fold_build2 (MULT_EXPR, TREE_TYPE (step), bias, step);
3306               thisarginfo.op
3307                 = fold_build2 (POINTER_TYPE_P (opt)
3308                                ? POINTER_PLUS_EXPR : PLUS_EXPR, opt,
3309                                thisarginfo.op, bias);
3310             }
3311         }
3312       else if (!vec_stmt
3313                && thisarginfo.dt != vect_constant_def
3314                && thisarginfo.dt != vect_external_def
3315                && loop_vinfo
3316                && TREE_CODE (op) == SSA_NAME
3317                && simple_iv (loop, loop_containing_stmt (stmt), op,
3318                              &iv, false)
3319                && tree_fits_shwi_p (iv.step))
3320         {
3321           thisarginfo.linear_step = tree_to_shwi (iv.step);
3322           thisarginfo.op = iv.base;
3323         }
3324       else if ((thisarginfo.dt == vect_constant_def
3325                 || thisarginfo.dt == vect_external_def)
3326                && POINTER_TYPE_P (TREE_TYPE (op)))
3327         thisarginfo.align = get_pointer_alignment (op) / BITS_PER_UNIT;
3328       /* Addresses of array elements indexed by GOMP_SIMD_LANE are
3329          linear too.  */
3330       if (POINTER_TYPE_P (TREE_TYPE (op))
3331           && !thisarginfo.linear_step
3332           && !vec_stmt
3333           && thisarginfo.dt != vect_constant_def
3334           && thisarginfo.dt != vect_external_def
3335           && loop_vinfo
3336           && !slp_node
3337           && TREE_CODE (op) == SSA_NAME)
3338         vect_simd_lane_linear (op, loop, &thisarginfo);
3339
3340       arginfo.quick_push (thisarginfo);
3341     }
3342
3343   unsigned int badness = 0;
3344   struct cgraph_node *bestn = NULL;
3345   if (STMT_VINFO_SIMD_CLONE_INFO (stmt_info).exists ())
3346     bestn = cgraph_node::get (STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[0]);
3347   else
3348     for (struct cgraph_node *n = node->simd_clones; n != NULL;
3349          n = n->simdclone->next_clone)
3350       {
3351         unsigned int this_badness = 0;
3352         if (n->simdclone->simdlen
3353             > (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo)
3354             || n->simdclone->nargs != nargs)
3355           continue;
3356         if (n->simdclone->simdlen
3357             < (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo))
3358           this_badness += (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo))
3359                            - exact_log2 (n->simdclone->simdlen)) * 1024;
3360         if (n->simdclone->inbranch)
3361           this_badness += 2048;
3362         int target_badness = targetm.simd_clone.usable (n);
3363         if (target_badness < 0)
3364           continue;
3365         this_badness += target_badness * 512;
3366         /* FORNOW: Have to add code to add the mask argument.  */
3367         if (n->simdclone->inbranch)
3368           continue;
3369         for (i = 0; i < nargs; i++)
3370           {
3371             switch (n->simdclone->args[i].arg_type)
3372               {
3373               case SIMD_CLONE_ARG_TYPE_VECTOR:
3374                 if (!useless_type_conversion_p
3375                         (n->simdclone->args[i].orig_type,
3376                          TREE_TYPE (gimple_call_arg (stmt, i))))
3377                   i = -1;
3378                 else if (arginfo[i].dt == vect_constant_def
3379                          || arginfo[i].dt == vect_external_def
3380                          || arginfo[i].linear_step)
3381                   this_badness += 64;
3382                 break;
3383               case SIMD_CLONE_ARG_TYPE_UNIFORM:
3384                 if (arginfo[i].dt != vect_constant_def
3385                     && arginfo[i].dt != vect_external_def)
3386                   i = -1;
3387                 break;
3388               case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
3389               case SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP:
3390                 if (arginfo[i].dt == vect_constant_def
3391                     || arginfo[i].dt == vect_external_def
3392                     || (arginfo[i].linear_step
3393                         != n->simdclone->args[i].linear_step))
3394                   i = -1;
3395                 break;
3396               case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
3397               case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
3398               case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
3399               case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP:
3400               case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
3401               case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
3402                 /* FORNOW */
3403                 i = -1;
3404                 break;
3405               case SIMD_CLONE_ARG_TYPE_MASK:
3406                 gcc_unreachable ();
3407               }
3408             if (i == (size_t) -1)
3409               break;
3410             if (n->simdclone->args[i].alignment > arginfo[i].align)
3411               {
3412                 i = -1;
3413                 break;
3414               }
3415             if (arginfo[i].align)
3416               this_badness += (exact_log2 (arginfo[i].align)
3417                                - exact_log2 (n->simdclone->args[i].alignment));
3418           }
3419         if (i == (size_t) -1)
3420           continue;
3421         if (bestn == NULL || this_badness < badness)
3422           {
3423             bestn = n;
3424             badness = this_badness;
3425           }
3426       }
3427
3428   if (bestn == NULL)
3429     return false;
3430
3431   for (i = 0; i < nargs; i++)
3432     if ((arginfo[i].dt == vect_constant_def
3433          || arginfo[i].dt == vect_external_def)
3434         && bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
3435       {
3436         arginfo[i].vectype
3437           = get_vectype_for_scalar_type (TREE_TYPE (gimple_call_arg (stmt,
3438                                                                      i)));
3439         if (arginfo[i].vectype == NULL
3440             || (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
3441                 > bestn->simdclone->simdlen))
3442           return false;
3443       }
3444
3445   fndecl = bestn->decl;
3446   nunits = bestn->simdclone->simdlen;
3447   ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
3448
3449   /* If the function isn't const, only allow it in simd loops where user
3450      has asserted that at least nunits consecutive iterations can be
3451      performed using SIMD instructions.  */
3452   if ((loop == NULL || (unsigned) loop->safelen < nunits)
3453       && gimple_vuse (stmt))
3454     return false;
3455
3456   /* Sanity check: make sure that at least one copy of the vectorized stmt
3457      needs to be generated.  */
3458   gcc_assert (ncopies >= 1);
3459
3460   if (!vec_stmt) /* transformation not required.  */
3461     {
3462       STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (bestn->decl);
3463       for (i = 0; i < nargs; i++)
3464         if ((bestn->simdclone->args[i].arg_type
3465              == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
3466             || (bestn->simdclone->args[i].arg_type
3467                 == SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP))
3468           {
3469             STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_grow_cleared (i * 3
3470                                                                         + 1);
3471             STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (arginfo[i].op);
3472             tree lst = POINTER_TYPE_P (TREE_TYPE (arginfo[i].op))
3473                        ? size_type_node : TREE_TYPE (arginfo[i].op);
3474             tree ls = build_int_cst (lst, arginfo[i].linear_step);
3475             STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (ls);
3476             tree sll = arginfo[i].simd_lane_linear
3477                        ? boolean_true_node : boolean_false_node;
3478             STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (sll);
3479           }
3480       STMT_VINFO_TYPE (stmt_info) = call_simd_clone_vec_info_type;
3481       if (dump_enabled_p ())
3482         dump_printf_loc (MSG_NOTE, vect_location,
3483                          "=== vectorizable_simd_clone_call ===\n");
3484 /*      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); */
3485       return true;
3486     }
3487
3488   /* Transform.  */
3489
3490   if (dump_enabled_p ())
3491     dump_printf_loc (MSG_NOTE, vect_location, "transform call.\n");
3492
3493   /* Handle def.  */
3494   scalar_dest = gimple_call_lhs (stmt);
3495   vec_dest = NULL_TREE;
3496   rtype = NULL_TREE;
3497   ratype = NULL_TREE;
3498   if (scalar_dest)
3499     {
3500       vec_dest = vect_create_destination_var (scalar_dest, vectype);
3501       rtype = TREE_TYPE (TREE_TYPE (fndecl));
3502       if (TREE_CODE (rtype) == ARRAY_TYPE)
3503         {
3504           ratype = rtype;
3505           rtype = TREE_TYPE (ratype);
3506         }
3507     }
3508
3509   prev_stmt_info = NULL;
3510   for (j = 0; j < ncopies; ++j)
3511     {
3512       /* Build argument list for the vectorized call.  */
3513       if (j == 0)
3514         vargs.create (nargs);
3515       else
3516         vargs.truncate (0);
3517
3518       for (i = 0; i < nargs; i++)
3519         {
3520           unsigned int k, l, m, o;
3521           tree atype;
3522           op = gimple_call_arg (stmt, i);
3523           switch (bestn->simdclone->args[i].arg_type)
3524             {
3525             case SIMD_CLONE_ARG_TYPE_VECTOR:
3526               atype = bestn->simdclone->args[i].vector_type;
3527               o = nunits / TYPE_VECTOR_SUBPARTS (atype);
3528               for (m = j * o; m < (j + 1) * o; m++)
3529                 {
3530                   if (TYPE_VECTOR_SUBPARTS (atype)
3531                       < TYPE_VECTOR_SUBPARTS (arginfo[i].vectype))
3532                     {
3533                       unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (atype));
3534                       k = (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
3535                            / TYPE_VECTOR_SUBPARTS (atype));
3536                       gcc_assert ((k & (k - 1)) == 0);
3537                       if (m == 0)
3538                         vec_oprnd0
3539                           = vect_get_vec_def_for_operand (op, stmt);
3540                       else
3541                         {
3542                           vec_oprnd0 = arginfo[i].op;
3543                           if ((m & (k - 1)) == 0)
3544                             vec_oprnd0
3545                               = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
3546                                                                 vec_oprnd0);
3547                         }
3548                       arginfo[i].op = vec_oprnd0;
3549                       vec_oprnd0
3550                         = build3 (BIT_FIELD_REF, atype, vec_oprnd0,
3551                                   bitsize_int (prec),
3552                                   bitsize_int ((m & (k - 1)) * prec));
3553                       new_stmt
3554                         = gimple_build_assign (make_ssa_name (atype),
3555                                                vec_oprnd0);
3556                       vect_finish_stmt_generation (stmt, new_stmt, gsi);
3557                       vargs.safe_push (gimple_assign_lhs (new_stmt));
3558                     }
3559                   else
3560                     {
3561                       k = (TYPE_VECTOR_SUBPARTS (atype)
3562                            / TYPE_VECTOR_SUBPARTS (arginfo[i].vectype));
3563                       gcc_assert ((k & (k - 1)) == 0);
3564                       vec<constructor_elt, va_gc> *ctor_elts;
3565                       if (k != 1)
3566                         vec_alloc (ctor_elts, k);
3567                       else
3568                         ctor_elts = NULL;
3569                       for (l = 0; l < k; l++)
3570                         {
3571                           if (m == 0 && l == 0)
3572                             vec_oprnd0
3573                               = vect_get_vec_def_for_operand (op, stmt);
3574                           else
3575                             vec_oprnd0
3576                               = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
3577                                                                 arginfo[i].op);
3578                           arginfo[i].op = vec_oprnd0;
3579                           if (k == 1)
3580                             break;
3581                           CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE,
3582                                                   vec_oprnd0);
3583                         }
3584                       if (k == 1)
3585                         vargs.safe_push (vec_oprnd0);
3586                       else
3587                         {
3588                           vec_oprnd0 = build_constructor (atype, ctor_elts);
3589                           new_stmt
3590                             = gimple_build_assign (make_ssa_name (atype),
3591                                                    vec_oprnd0);
3592                           vect_finish_stmt_generation (stmt, new_stmt, gsi);
3593                           vargs.safe_push (gimple_assign_lhs (new_stmt));
3594                         }
3595                     }
3596                 }
3597               break;
3598             case SIMD_CLONE_ARG_TYPE_UNIFORM:
3599               vargs.safe_push (op);
3600               break;
3601             case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
3602             case SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP:
3603               if (j == 0)
3604                 {
3605                   gimple_seq stmts;
3606                   arginfo[i].op
3607                     = force_gimple_operand (arginfo[i].op, &stmts, true,
3608                                             NULL_TREE);
3609                   if (stmts != NULL)
3610                     {
3611                       basic_block new_bb;
3612                       edge pe = loop_preheader_edge (loop);
3613                       new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
3614                       gcc_assert (!new_bb);
3615                     }
3616                   if (arginfo[i].simd_lane_linear)
3617                     {
3618                       vargs.safe_push (arginfo[i].op);
3619                       break;
3620                     }
3621                   tree phi_res = copy_ssa_name (op);
3622                   gphi *new_phi = create_phi_node (phi_res, loop->header);
3623                   set_vinfo_for_stmt (new_phi,
3624                                       new_stmt_vec_info (new_phi, loop_vinfo));
3625                   add_phi_arg (new_phi, arginfo[i].op,
3626                                loop_preheader_edge (loop), UNKNOWN_LOCATION);
3627                   enum tree_code code
3628                     = POINTER_TYPE_P (TREE_TYPE (op))
3629                       ? POINTER_PLUS_EXPR : PLUS_EXPR;
3630                   tree type = POINTER_TYPE_P (TREE_TYPE (op))
3631                               ? sizetype : TREE_TYPE (op);
3632                   widest_int cst
3633                     = wi::mul (bestn->simdclone->args[i].linear_step,
3634                                ncopies * nunits);
3635                   tree tcst = wide_int_to_tree (type, cst);
3636                   tree phi_arg = copy_ssa_name (op);
3637                   new_stmt
3638                     = gimple_build_assign (phi_arg, code, phi_res, tcst);
3639                   gimple_stmt_iterator si = gsi_after_labels (loop->header);
3640                   gsi_insert_after (&si, new_stmt, GSI_NEW_STMT);
3641                   set_vinfo_for_stmt (new_stmt,
3642                                       new_stmt_vec_info (new_stmt, loop_vinfo));
3643                   add_phi_arg (new_phi, phi_arg, loop_latch_edge (loop),
3644                                UNKNOWN_LOCATION);
3645                   arginfo[i].op = phi_res;
3646                   vargs.safe_push (phi_res);
3647                 }
3648               else
3649                 {
3650                   enum tree_code code
3651                     = POINTER_TYPE_P (TREE_TYPE (op))
3652                       ? POINTER_PLUS_EXPR : PLUS_EXPR;
3653                   tree type = POINTER_TYPE_P (TREE_TYPE (op))
3654                               ? sizetype : TREE_TYPE (op);
3655                   widest_int cst
3656                     = wi::mul (bestn->simdclone->args[i].linear_step,
3657                                j * nunits);
3658                   tree tcst = wide_int_to_tree (type, cst);
3659                   new_temp = make_ssa_name (TREE_TYPE (op));
3660                   new_stmt = gimple_build_assign (new_temp, code,
3661                                                   arginfo[i].op, tcst);
3662                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3663                   vargs.safe_push (new_temp);
3664                 }
3665               break;
3666             case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
3667             case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
3668             case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
3669             case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP:
3670             case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
3671             case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
3672             default:
3673               gcc_unreachable ();
3674             }
3675         }
3676
3677       new_stmt = gimple_build_call_vec (fndecl, vargs);
3678       if (vec_dest)
3679         {
3680           gcc_assert (ratype || TYPE_VECTOR_SUBPARTS (rtype) == nunits);
3681           if (ratype)
3682             new_temp = create_tmp_var (ratype);
3683           else if (TYPE_VECTOR_SUBPARTS (vectype)
3684                    == TYPE_VECTOR_SUBPARTS (rtype))
3685             new_temp = make_ssa_name (vec_dest, new_stmt);
3686           else
3687             new_temp = make_ssa_name (rtype, new_stmt);
3688           gimple_call_set_lhs (new_stmt, new_temp);
3689         }
3690       vect_finish_stmt_generation (stmt, new_stmt, gsi);
3691
3692       if (vec_dest)
3693         {
3694           if (TYPE_VECTOR_SUBPARTS (vectype) < nunits)
3695             {
3696               unsigned int k, l;
3697               unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (vectype));
3698               k = nunits / TYPE_VECTOR_SUBPARTS (vectype);
3699               gcc_assert ((k & (k - 1)) == 0);
3700               for (l = 0; l < k; l++)
3701                 {
3702                   tree t;
3703                   if (ratype)
3704                     {
3705                       t = build_fold_addr_expr (new_temp);
3706                       t = build2 (MEM_REF, vectype, t,
3707                                   build_int_cst (TREE_TYPE (t),
3708                                                  l * prec / BITS_PER_UNIT));
3709                     }
3710                   else
3711                     t = build3 (BIT_FIELD_REF, vectype, new_temp,
3712                                 bitsize_int (prec), bitsize_int (l * prec));
3713                   new_stmt
3714                     = gimple_build_assign (make_ssa_name (vectype), t);
3715                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3716                   if (j == 0 && l == 0)
3717                     STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
3718                   else
3719                     STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3720
3721                   prev_stmt_info = vinfo_for_stmt (new_stmt);
3722                 }
3723
3724               if (ratype)
3725                 {
3726                   tree clobber = build_constructor (ratype, NULL);
3727                   TREE_THIS_VOLATILE (clobber) = 1;
3728                   new_stmt = gimple_build_assign (new_temp, clobber);
3729                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3730                 }
3731               continue;
3732             }
3733           else if (TYPE_VECTOR_SUBPARTS (vectype) > nunits)
3734             {
3735               unsigned int k = (TYPE_VECTOR_SUBPARTS (vectype)
3736                                 / TYPE_VECTOR_SUBPARTS (rtype));
3737               gcc_assert ((k & (k - 1)) == 0);
3738               if ((j & (k - 1)) == 0)
3739                 vec_alloc (ret_ctor_elts, k);
3740               if (ratype)
3741                 {
3742                   unsigned int m, o = nunits / TYPE_VECTOR_SUBPARTS (rtype);
3743                   for (m = 0; m < o; m++)
3744                     {
3745                       tree tem = build4 (ARRAY_REF, rtype, new_temp,
3746                                          size_int (m), NULL_TREE, NULL_TREE);
3747                       new_stmt
3748                         = gimple_build_assign (make_ssa_name (rtype), tem);
3749                       vect_finish_stmt_generation (stmt, new_stmt, gsi);
3750                       CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE,
3751                                               gimple_assign_lhs (new_stmt));
3752                     }
3753                   tree clobber = build_constructor (ratype, NULL);
3754                   TREE_THIS_VOLATILE (clobber) = 1;
3755                   new_stmt = gimple_build_assign (new_temp, clobber);
3756                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3757                 }
3758               else
3759                 CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, new_temp);
3760               if ((j & (k - 1)) != k - 1)
3761                 continue;
3762               vec_oprnd0 = build_constructor (vectype, ret_ctor_elts);
3763               new_stmt
3764                 = gimple_build_assign (make_ssa_name (vec_dest), vec_oprnd0);
3765               vect_finish_stmt_generation (stmt, new_stmt, gsi);
3766
3767               if ((unsigned) j == k - 1)
3768                 STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
3769               else
3770                 STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3771
3772               prev_stmt_info = vinfo_for_stmt (new_stmt);
3773               continue;
3774             }
3775           else if (ratype)
3776             {
3777               tree t = build_fold_addr_expr (new_temp);
3778               t = build2 (MEM_REF, vectype, t,
3779                           build_int_cst (TREE_TYPE (t), 0));
3780               new_stmt
3781                 = gimple_build_assign (make_ssa_name (vec_dest), t);
3782               vect_finish_stmt_generation (stmt, new_stmt, gsi);
3783               tree clobber = build_constructor (ratype, NULL);
3784               TREE_THIS_VOLATILE (clobber) = 1;
3785               vect_finish_stmt_generation (stmt,
3786                                            gimple_build_assign (new_temp,
3787                                                                 clobber), gsi);
3788             }
3789         }
3790
3791       if (j == 0)
3792         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
3793       else
3794         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3795
3796       prev_stmt_info = vinfo_for_stmt (new_stmt);
3797     }
3798
3799   vargs.release ();
3800
3801   /* The call in STMT might prevent it from being removed in dce.
3802      We however cannot remove it here, due to the way the ssa name
3803      it defines is mapped to the new definition.  So just replace
3804      rhs of the statement with something harmless.  */
3805
3806   if (slp_node)
3807     return true;
3808
3809   if (scalar_dest)
3810     {
3811       type = TREE_TYPE (scalar_dest);
3812       if (is_pattern_stmt_p (stmt_info))
3813         lhs = gimple_call_lhs (STMT_VINFO_RELATED_STMT (stmt_info));
3814       else
3815         lhs = gimple_call_lhs (stmt);
3816       new_stmt = gimple_build_assign (lhs, build_zero_cst (type));
3817     }
3818   else
3819     new_stmt = gimple_build_nop ();
3820   set_vinfo_for_stmt (new_stmt, stmt_info);
3821   set_vinfo_for_stmt (stmt, NULL);
3822   STMT_VINFO_STMT (stmt_info) = new_stmt;
3823   gsi_replace (gsi, new_stmt, true);
3824   unlink_stmt_vdef (stmt);
3825
3826   return true;
3827 }
3828
3829
3830 /* Function vect_gen_widened_results_half
3831
3832    Create a vector stmt whose code, type, number of arguments, and result
3833    variable are CODE, OP_TYPE, and VEC_DEST, and its arguments are
3834    VEC_OPRND0 and VEC_OPRND1.  The new vector stmt is to be inserted at BSI.
3835    In the case that CODE is a CALL_EXPR, this means that a call to DECL
3836    needs to be created (DECL is a function-decl of a target-builtin).
3837    STMT is the original scalar stmt that we are vectorizing.  */
3838
3839 static gimple *
3840 vect_gen_widened_results_half (enum tree_code code,
3841                                tree decl,
3842                                tree vec_oprnd0, tree vec_oprnd1, int op_type,
3843                                tree vec_dest, gimple_stmt_iterator *gsi,
3844                                gimple *stmt)
3845 {
3846   gimple *new_stmt;
3847   tree new_temp;
3848
3849   /* Generate half of the widened result:  */
3850   if (code == CALL_EXPR)
3851     {
3852       /* Target specific support  */
3853       if (op_type == binary_op)
3854         new_stmt = gimple_build_call (decl, 2, vec_oprnd0, vec_oprnd1);
3855       else
3856         new_stmt = gimple_build_call (decl, 1, vec_oprnd0);
3857       new_temp = make_ssa_name (vec_dest, new_stmt);
3858       gimple_call_set_lhs (new_stmt, new_temp);
3859     }
3860   else
3861     {
3862       /* Generic support */
3863       gcc_assert (op_type == TREE_CODE_LENGTH (code));
3864       if (op_type != binary_op)
3865         vec_oprnd1 = NULL;
3866       new_stmt = gimple_build_assign (vec_dest, code, vec_oprnd0, vec_oprnd1);
3867       new_temp = make_ssa_name (vec_dest, new_stmt);
3868       gimple_assign_set_lhs (new_stmt, new_temp);
3869     }
3870   vect_finish_stmt_generation (stmt, new_stmt, gsi);
3871
3872   return new_stmt;
3873 }
3874
3875
3876 /* Get vectorized definitions for loop-based vectorization.  For the first
3877    operand we call vect_get_vec_def_for_operand() (with OPRND containing
3878    scalar operand), and for the rest we get a copy with
3879    vect_get_vec_def_for_stmt_copy() using the previous vector definition
3880    (stored in OPRND). See vect_get_vec_def_for_stmt_copy() for details.
3881    The vectors are collected into VEC_OPRNDS.  */
3882
3883 static void
3884 vect_get_loop_based_defs (tree *oprnd, gimple *stmt, enum vect_def_type dt,
3885                           vec<tree> *vec_oprnds, int multi_step_cvt)
3886 {
3887   tree vec_oprnd;
3888
3889   /* Get first vector operand.  */
3890   /* All the vector operands except the very first one (that is scalar oprnd)
3891      are stmt copies.  */
3892   if (TREE_CODE (TREE_TYPE (*oprnd)) != VECTOR_TYPE)
3893     vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt);
3894   else
3895     vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, *oprnd);
3896
3897   vec_oprnds->quick_push (vec_oprnd);
3898
3899   /* Get second vector operand.  */
3900   vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
3901   vec_oprnds->quick_push (vec_oprnd);
3902
3903   *oprnd = vec_oprnd;
3904
3905   /* For conversion in multiple steps, continue to get operands
3906      recursively.  */
3907   if (multi_step_cvt)
3908     vect_get_loop_based_defs (oprnd, stmt, dt, vec_oprnds,  multi_step_cvt - 1);
3909 }
3910
3911
3912 /* Create vectorized demotion statements for vector operands from VEC_OPRNDS.
3913    For multi-step conversions store the resulting vectors and call the function
3914    recursively.  */
3915
3916 static void
3917 vect_create_vectorized_demotion_stmts (vec<tree> *vec_oprnds,
3918                                        int multi_step_cvt, gimple *stmt,
3919                                        vec<tree> vec_dsts,
3920                                        gimple_stmt_iterator *gsi,
3921                                        slp_tree slp_node, enum tree_code code,
3922                                        stmt_vec_info *prev_stmt_info)
3923 {
3924   unsigned int i;
3925   tree vop0, vop1, new_tmp, vec_dest;
3926   gimple *new_stmt;
3927   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3928
3929   vec_dest = vec_dsts.pop ();
3930
3931   for (i = 0; i < vec_oprnds->length (); i += 2)
3932     {
3933       /* Create demotion operation.  */
3934       vop0 = (*vec_oprnds)[i];
3935       vop1 = (*vec_oprnds)[i + 1];
3936       new_stmt = gimple_build_assign (vec_dest, code, vop0, vop1);
3937       new_tmp = make_ssa_name (vec_dest, new_stmt);
3938       gimple_assign_set_lhs (new_stmt, new_tmp);
3939       vect_finish_stmt_generation (stmt, new_stmt, gsi);
3940
3941       if (multi_step_cvt)
3942         /* Store the resulting vector for next recursive call.  */
3943         (*vec_oprnds)[i/2] = new_tmp;
3944       else
3945         {
3946           /* This is the last step of the conversion sequence. Store the
3947              vectors in SLP_NODE or in vector info of the scalar statement
3948              (or in STMT_VINFO_RELATED_STMT chain).  */
3949           if (slp_node)
3950             SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
3951           else
3952             {
3953               if (!*prev_stmt_info)
3954                 STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
3955               else
3956                 STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
3957
3958               *prev_stmt_info = vinfo_for_stmt (new_stmt);
3959             }
3960         }
3961     }
3962
3963   /* For multi-step demotion operations we first generate demotion operations
3964      from the source type to the intermediate types, and then combine the
3965      results (stored in VEC_OPRNDS) in demotion operation to the destination
3966      type.  */
3967   if (multi_step_cvt)
3968     {
3969       /* At each level of recursion we have half of the operands we had at the
3970          previous level.  */
3971       vec_oprnds->truncate ((i+1)/2);
3972       vect_create_vectorized_demotion_stmts (vec_oprnds, multi_step_cvt - 1,
3973                                              stmt, vec_dsts, gsi, slp_node,
3974                                              VEC_PACK_TRUNC_EXPR,
3975                                              prev_stmt_info);
3976     }
3977
3978   vec_dsts.quick_push (vec_dest);
3979 }
3980
3981
3982 /* Create vectorized promotion statements for vector operands from VEC_OPRNDS0
3983    and VEC_OPRNDS1 (for binary operations).  For multi-step conversions store
3984    the resulting vectors and call the function recursively.  */
3985
3986 static void
3987 vect_create_vectorized_promotion_stmts (vec<tree> *vec_oprnds0,
3988                                         vec<tree> *vec_oprnds1,
3989                                         gimple *stmt, tree vec_dest,
3990                                         gimple_stmt_iterator *gsi,
3991                                         enum tree_code code1,
3992                                         enum tree_code code2, tree decl1,
3993                                         tree decl2, int op_type)
3994 {
3995   int i;
3996   tree vop0, vop1, new_tmp1, new_tmp2;
3997   gimple *new_stmt1, *new_stmt2;
3998   vec<tree> vec_tmp = vNULL;
3999
4000   vec_tmp.create (vec_oprnds0->length () * 2);
4001   FOR_EACH_VEC_ELT (*vec_oprnds0, i, vop0)
4002     {
4003       if (op_type == binary_op)
4004         vop1 = (*vec_oprnds1)[i];
4005       else
4006         vop1 = NULL_TREE;
4007
4008       /* Generate the two halves of promotion operation.  */
4009       new_stmt1 = vect_gen_widened_results_half (code1, decl1, vop0, vop1,
4010                                                  op_type, vec_dest, gsi, stmt);
4011       new_stmt2 = vect_gen_widened_results_half (code2, decl2, vop0, vop1,
4012                                                  op_type, vec_dest, gsi, stmt);
4013       if (is_gimple_call (new_stmt1))
4014         {
4015           new_tmp1 = gimple_call_lhs (new_stmt1);
4016           new_tmp2 = gimple_call_lhs (new_stmt2);
4017         }
4018       else
4019         {
4020           new_tmp1 = gimple_assign_lhs (new_stmt1);
4021           new_tmp2 = gimple_assign_lhs (new_stmt2);
4022         }
4023
4024       /* Store the results for the next step.  */
4025       vec_tmp.quick_push (new_tmp1);
4026       vec_tmp.quick_push (new_tmp2);
4027     }
4028
4029   vec_oprnds0->release ();
4030   *vec_oprnds0 = vec_tmp;
4031 }
4032
4033
4034 /* Check if STMT performs a conversion operation, that can be vectorized.
4035    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
4036    stmt to replace it, put it in VEC_STMT, and insert it at GSI.
4037    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
4038
4039 static bool
4040 vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
4041                          gimple **vec_stmt, slp_tree slp_node)
4042 {
4043   tree vec_dest;
4044   tree scalar_dest;
4045   tree op0, op1 = NULL_TREE;
4046   tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
4047   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4048   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4049   enum tree_code code, code1 = ERROR_MARK, code2 = ERROR_MARK;
4050   enum tree_code codecvt1 = ERROR_MARK, codecvt2 = ERROR_MARK;
4051   tree decl1 = NULL_TREE, decl2 = NULL_TREE;
4052   tree new_temp;
4053   gimple *def_stmt;
4054   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
4055   int ndts = 2;
4056   gimple *new_stmt = NULL;
4057   stmt_vec_info prev_stmt_info;
4058   int nunits_in;
4059   int nunits_out;
4060   tree vectype_out, vectype_in;
4061   int ncopies, i, j;
4062   tree lhs_type, rhs_type;
4063   enum { NARROW, NONE, WIDEN } modifier;
4064   vec<tree> vec_oprnds0 = vNULL;
4065   vec<tree> vec_oprnds1 = vNULL;
4066   tree vop0;
4067   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
4068   vec_info *vinfo = stmt_info->vinfo;
4069   int multi_step_cvt = 0;
4070   vec<tree> interm_types = vNULL;
4071   tree last_oprnd, intermediate_type, cvt_type = NULL_TREE;
4072   int op_type;
4073   machine_mode rhs_mode;
4074   unsigned short fltsz;
4075
4076   /* Is STMT a vectorizable conversion?   */
4077
4078   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
4079     return false;
4080
4081   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
4082       && ! vec_stmt)
4083     return false;
4084
4085   if (!is_gimple_assign (stmt))
4086     return false;
4087
4088   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
4089     return false;
4090
4091   code = gimple_assign_rhs_code (stmt);
4092   if (!CONVERT_EXPR_CODE_P (code)
4093       && code != FIX_TRUNC_EXPR
4094       && code != FLOAT_EXPR
4095       && code != WIDEN_MULT_EXPR
4096       && code != WIDEN_LSHIFT_EXPR)
4097     return false;
4098
4099   op_type = TREE_CODE_LENGTH (code);
4100
4101   /* Check types of lhs and rhs.  */
4102   scalar_dest = gimple_assign_lhs (stmt);
4103   lhs_type = TREE_TYPE (scalar_dest);
4104   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
4105
4106   op0 = gimple_assign_rhs1 (stmt);
4107   rhs_type = TREE_TYPE (op0);
4108
4109   if ((code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
4110       && !((INTEGRAL_TYPE_P (lhs_type)
4111             && INTEGRAL_TYPE_P (rhs_type))
4112            || (SCALAR_FLOAT_TYPE_P (lhs_type)
4113                && SCALAR_FLOAT_TYPE_P (rhs_type))))
4114     return false;
4115
4116   if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
4117       && ((INTEGRAL_TYPE_P (lhs_type)
4118            && !type_has_mode_precision_p (lhs_type))
4119           || (INTEGRAL_TYPE_P (rhs_type)
4120               && !type_has_mode_precision_p (rhs_type))))
4121     {
4122       if (dump_enabled_p ())
4123         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4124                          "type conversion to/from bit-precision unsupported."
4125                          "\n");
4126       return false;
4127     }
4128
4129   /* Check the operands of the operation.  */
4130   if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype_in))
4131     {
4132       if (dump_enabled_p ())
4133         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4134                          "use not simple.\n");
4135       return false;
4136     }
4137   if (op_type == binary_op)
4138     {
4139       bool ok;
4140
4141       op1 = gimple_assign_rhs2 (stmt);
4142       gcc_assert (code == WIDEN_MULT_EXPR || code == WIDEN_LSHIFT_EXPR);
4143       /* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
4144          OP1.  */
4145       if (CONSTANT_CLASS_P (op0))
4146         ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &vectype_in);
4147       else
4148         ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]);
4149
4150       if (!ok)
4151         {
4152           if (dump_enabled_p ())
4153             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4154                              "use not simple.\n");
4155           return false;
4156         }
4157     }
4158
4159   /* If op0 is an external or constant defs use a vector type of
4160      the same size as the output vector type.  */
4161   if (!vectype_in)
4162     vectype_in = get_same_sized_vectype (rhs_type, vectype_out);
4163   if (vec_stmt)
4164     gcc_assert (vectype_in);
4165   if (!vectype_in)
4166     {
4167       if (dump_enabled_p ())
4168         {
4169           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4170                            "no vectype for scalar type ");
4171           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type);
4172           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
4173         }
4174
4175       return false;
4176     }
4177
4178   if (VECTOR_BOOLEAN_TYPE_P (vectype_out)
4179       && !VECTOR_BOOLEAN_TYPE_P (vectype_in))
4180     {
4181       if (dump_enabled_p ())
4182         {
4183           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4184                            "can't convert between boolean and non "
4185                            "boolean vectors");
4186           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type);
4187           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
4188         }
4189
4190       return false;
4191     }
4192
4193   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
4194   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
4195   if (nunits_in < nunits_out)
4196     modifier = NARROW;
4197   else if (nunits_out == nunits_in)
4198     modifier = NONE;
4199   else
4200     modifier = WIDEN;
4201
4202   /* Multiple types in SLP are handled by creating the appropriate number of
4203      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
4204      case of SLP.  */
4205   if (slp_node)
4206     ncopies = 1;
4207   else if (modifier == NARROW)
4208     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
4209   else
4210     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
4211
4212   /* Sanity check: make sure that at least one copy of the vectorized stmt
4213      needs to be generated.  */
4214   gcc_assert (ncopies >= 1);
4215
4216   /* Supportable by target?  */
4217   switch (modifier)
4218     {
4219     case NONE:
4220       if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
4221         return false;
4222       if (supportable_convert_operation (code, vectype_out, vectype_in,
4223                                          &decl1, &code1))
4224         break;
4225       /* FALLTHRU */
4226     unsupported:
4227       if (dump_enabled_p ())
4228         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4229                          "conversion not supported by target.\n");
4230       return false;
4231
4232     case WIDEN:
4233       if (supportable_widening_operation (code, stmt, vectype_out, vectype_in,
4234                                           &code1, &code2, &multi_step_cvt,
4235                                           &interm_types))
4236         {
4237           /* Binary widening operation can only be supported directly by the
4238              architecture.  */
4239           gcc_assert (!(multi_step_cvt && op_type == binary_op));
4240           break;
4241         }
4242
4243       if (code != FLOAT_EXPR
4244           || (GET_MODE_SIZE (TYPE_MODE (lhs_type))
4245               <= GET_MODE_SIZE (TYPE_MODE (rhs_type))))
4246         goto unsupported;
4247
4248       rhs_mode = TYPE_MODE (rhs_type);
4249       fltsz = GET_MODE_SIZE (TYPE_MODE (lhs_type));
4250       for (rhs_mode = GET_MODE_2XWIDER_MODE (TYPE_MODE (rhs_type));
4251            rhs_mode != VOIDmode && GET_MODE_SIZE (rhs_mode) <= fltsz;
4252            rhs_mode = GET_MODE_2XWIDER_MODE (rhs_mode))
4253         {
4254           cvt_type
4255             = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
4256           cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
4257           if (cvt_type == NULL_TREE)
4258             goto unsupported;
4259
4260           if (GET_MODE_SIZE (rhs_mode) == fltsz)
4261             {
4262               if (!supportable_convert_operation (code, vectype_out,
4263                                                   cvt_type, &decl1, &codecvt1))
4264                 goto unsupported;
4265             }
4266           else if (!supportable_widening_operation (code, stmt, vectype_out,
4267                                                     cvt_type, &codecvt1,
4268                                                     &codecvt2, &multi_step_cvt,
4269                                                     &interm_types))
4270             continue;
4271           else
4272             gcc_assert (multi_step_cvt == 0);
4273
4274           if (supportable_widening_operation (NOP_EXPR, stmt, cvt_type,
4275                                               vectype_in, &code1, &code2,
4276                                               &multi_step_cvt, &interm_types))
4277             break;
4278         }
4279
4280       if (rhs_mode == VOIDmode || GET_MODE_SIZE (rhs_mode) > fltsz)
4281         goto unsupported;
4282
4283       if (GET_MODE_SIZE (rhs_mode) == fltsz)
4284         codecvt2 = ERROR_MARK;
4285       else
4286         {
4287           multi_step_cvt++;
4288           interm_types.safe_push (cvt_type);
4289           cvt_type = NULL_TREE;
4290         }
4291       break;
4292
4293     case NARROW:
4294       gcc_assert (op_type == unary_op);
4295       if (supportable_narrowing_operation (code, vectype_out, vectype_in,
4296                                            &code1, &multi_step_cvt,
4297                                            &interm_types))
4298         break;
4299
4300       if (code != FIX_TRUNC_EXPR
4301           || (GET_MODE_SIZE (TYPE_MODE (lhs_type))
4302               >= GET_MODE_SIZE (TYPE_MODE (rhs_type))))
4303         goto unsupported;
4304
4305       rhs_mode = TYPE_MODE (rhs_type);
4306       cvt_type
4307         = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
4308       cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
4309       if (cvt_type == NULL_TREE)
4310         goto unsupported;
4311       if (!supportable_convert_operation (code, cvt_type, vectype_in,
4312                                           &decl1, &codecvt1))
4313         goto unsupported;
4314       if (supportable_narrowing_operation (NOP_EXPR, vectype_out, cvt_type,
4315                                            &code1, &multi_step_cvt,
4316                                            &interm_types))
4317         break;
4318       goto unsupported;
4319
4320     default:
4321       gcc_unreachable ();
4322     }
4323
4324   if (!vec_stmt)                /* transformation not required.  */
4325     {
4326       if (dump_enabled_p ())
4327         dump_printf_loc (MSG_NOTE, vect_location,
4328                          "=== vectorizable_conversion ===\n");
4329       if (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR)
4330         {
4331           STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type;
4332           vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
4333         }
4334       else if (modifier == NARROW)
4335         {
4336           STMT_VINFO_TYPE (stmt_info) = type_demotion_vec_info_type;
4337           vect_model_promotion_demotion_cost (stmt_info, dt, multi_step_cvt);
4338         }
4339       else
4340         {
4341           STMT_VINFO_TYPE (stmt_info) = type_promotion_vec_info_type;
4342           vect_model_promotion_demotion_cost (stmt_info, dt, multi_step_cvt);
4343         }
4344       interm_types.release ();
4345       return true;
4346     }
4347
4348   /* Transform.  */
4349   if (dump_enabled_p ())
4350     dump_printf_loc (MSG_NOTE, vect_location,
4351                      "transform conversion. ncopies = %d.\n", ncopies);
4352
4353   if (op_type == binary_op)
4354     {
4355       if (CONSTANT_CLASS_P (op0))
4356         op0 = fold_convert (TREE_TYPE (op1), op0);
4357       else if (CONSTANT_CLASS_P (op1))
4358         op1 = fold_convert (TREE_TYPE (op0), op1);
4359     }
4360
4361   /* In case of multi-step conversion, we first generate conversion operations
4362      to the intermediate types, and then from that types to the final one.
4363      We create vector destinations for the intermediate type (TYPES) received
4364      from supportable_*_operation, and store them in the correct order
4365      for future use in vect_create_vectorized_*_stmts ().  */
4366   auto_vec<tree> vec_dsts (multi_step_cvt + 1);
4367   vec_dest = vect_create_destination_var (scalar_dest,
4368                                           (cvt_type && modifier == WIDEN)
4369                                           ? cvt_type : vectype_out);
4370   vec_dsts.quick_push (vec_dest);
4371
4372   if (multi_step_cvt)
4373     {
4374       for (i = interm_types.length () - 1;
4375            interm_types.iterate (i, &intermediate_type); i--)
4376         {
4377           vec_dest = vect_create_destination_var (scalar_dest,
4378                                                   intermediate_type);
4379           vec_dsts.quick_push (vec_dest);
4380         }
4381     }
4382
4383   if (cvt_type)
4384     vec_dest = vect_create_destination_var (scalar_dest,
4385                                             modifier == WIDEN
4386                                             ? vectype_out : cvt_type);
4387
4388   if (!slp_node)
4389     {
4390       if (modifier == WIDEN)
4391         {
4392           vec_oprnds0.create (multi_step_cvt ? vect_pow2 (multi_step_cvt) : 1);
4393           if (op_type == binary_op)
4394             vec_oprnds1.create (1);
4395         }
4396       else if (modifier == NARROW)
4397         vec_oprnds0.create (
4398                    2 * (multi_step_cvt ? vect_pow2 (multi_step_cvt) : 1));
4399     }
4400   else if (code == WIDEN_LSHIFT_EXPR)
4401     vec_oprnds1.create (slp_node->vec_stmts_size);
4402
4403   last_oprnd = op0;
4404   prev_stmt_info = NULL;
4405   switch (modifier)
4406     {
4407     case NONE:
4408       for (j = 0; j < ncopies; j++)
4409         {
4410           if (j == 0)
4411             vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node);
4412           else
4413             vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
4414
4415           FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
4416             {
4417               /* Arguments are ready, create the new vector stmt.  */
4418               if (code1 == CALL_EXPR)
4419                 {
4420                   new_stmt = gimple_build_call (decl1, 1, vop0);
4421                   new_temp = make_ssa_name (vec_dest, new_stmt);
4422                   gimple_call_set_lhs (new_stmt, new_temp);
4423                 }
4424               else
4425                 {
4426                   gcc_assert (TREE_CODE_LENGTH (code1) == unary_op);
4427                   new_stmt = gimple_build_assign (vec_dest, code1, vop0);
4428                   new_temp = make_ssa_name (vec_dest, new_stmt);
4429                   gimple_assign_set_lhs (new_stmt, new_temp);
4430                 }
4431
4432               vect_finish_stmt_generation (stmt, new_stmt, gsi);
4433               if (slp_node)
4434                 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
4435               else
4436                 {
4437                   if (!prev_stmt_info)
4438                     STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
4439                   else
4440                     STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4441                   prev_stmt_info = vinfo_for_stmt (new_stmt);
4442                 }
4443             }
4444         }
4445       break;
4446
4447     case WIDEN:
4448       /* In case the vectorization factor (VF) is bigger than the number
4449          of elements that we can fit in a vectype (nunits), we have to
4450          generate more than one vector stmt - i.e - we need to "unroll"
4451          the vector stmt by a factor VF/nunits.  */
4452       for (j = 0; j < ncopies; j++)
4453         {
4454           /* Handle uses.  */
4455           if (j == 0)
4456             {
4457               if (slp_node)
4458                 {
4459                   if (code == WIDEN_LSHIFT_EXPR)
4460                     {
4461                       unsigned int k;
4462
4463                       vec_oprnd1 = op1;
4464                       /* Store vec_oprnd1 for every vector stmt to be created
4465                          for SLP_NODE.  We check during the analysis that all
4466                          the shift arguments are the same.  */
4467                       for (k = 0; k < slp_node->vec_stmts_size - 1; k++)
4468                         vec_oprnds1.quick_push (vec_oprnd1);
4469
4470                       vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
4471                                          slp_node);
4472                     }
4473                   else
4474                     vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0,
4475                                        &vec_oprnds1, slp_node);
4476                 }
4477               else
4478                 {
4479                   vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
4480                   vec_oprnds0.quick_push (vec_oprnd0);
4481                   if (op_type == binary_op)
4482                     {
4483                       if (code == WIDEN_LSHIFT_EXPR)
4484                         vec_oprnd1 = op1;
4485                       else
4486                         vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt);
4487                       vec_oprnds1.quick_push (vec_oprnd1);
4488                     }
4489                 }
4490             }
4491           else
4492             {
4493               vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0);
4494               vec_oprnds0.truncate (0);
4495               vec_oprnds0.quick_push (vec_oprnd0);
4496               if (op_type == binary_op)
4497                 {
4498                   if (code == WIDEN_LSHIFT_EXPR)
4499                     vec_oprnd1 = op1;
4500                   else
4501                     vec_oprnd1 = vect_get_vec_def_for_stmt_copy (dt[1],
4502                                                                  vec_oprnd1);
4503                   vec_oprnds1.truncate (0);
4504                   vec_oprnds1.quick_push (vec_oprnd1);
4505                 }
4506             }
4507
4508           /* Arguments are ready.  Create the new vector stmts.  */
4509           for (i = multi_step_cvt; i >= 0; i--)
4510             {
4511               tree this_dest = vec_dsts[i];
4512               enum tree_code c1 = code1, c2 = code2;
4513               if (i == 0 && codecvt2 != ERROR_MARK)
4514                 {
4515                   c1 = codecvt1;
4516                   c2 = codecvt2;
4517                 }
4518               vect_create_vectorized_promotion_stmts (&vec_oprnds0,
4519                                                       &vec_oprnds1,
4520                                                       stmt, this_dest, gsi,
4521                                                       c1, c2, decl1, decl2,
4522                                                       op_type);
4523             }
4524
4525           FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
4526             {
4527               if (cvt_type)
4528                 {
4529                   if (codecvt1 == CALL_EXPR)
4530                     {
4531                       new_stmt = gimple_build_call (decl1, 1, vop0);
4532                       new_temp = make_ssa_name (vec_dest, new_stmt);
4533                       gimple_call_set_lhs (new_stmt, new_temp);
4534                     }
4535                   else
4536                     {
4537                       gcc_assert (TREE_CODE_LENGTH (codecvt1) == unary_op);
4538                       new_temp = make_ssa_name (vec_dest);
4539                       new_stmt = gimple_build_assign (new_temp, codecvt1,
4540                                                       vop0);
4541                     }
4542
4543                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
4544                 }
4545               else
4546                 new_stmt = SSA_NAME_DEF_STMT (vop0);
4547
4548               if (slp_node)
4549                 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
4550               else
4551                 {
4552                   if (!prev_stmt_info)
4553                     STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
4554                   else
4555                     STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4556                   prev_stmt_info = vinfo_for_stmt (new_stmt);
4557                 }
4558             }
4559         }
4560
4561       *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
4562       break;
4563
4564     case NARROW:
4565       /* In case the vectorization factor (VF) is bigger than the number
4566          of elements that we can fit in a vectype (nunits), we have to
4567          generate more than one vector stmt - i.e - we need to "unroll"
4568          the vector stmt by a factor VF/nunits.  */
4569       for (j = 0; j < ncopies; j++)
4570         {
4571           /* Handle uses.  */
4572           if (slp_node)
4573             vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
4574                                slp_node);
4575           else
4576             {
4577               vec_oprnds0.truncate (0);
4578               vect_get_loop_based_defs (&last_oprnd, stmt, dt[0], &vec_oprnds0,
4579                                         vect_pow2 (multi_step_cvt) - 1);
4580             }
4581
4582           /* Arguments are ready.  Create the new vector stmts.  */
4583           if (cvt_type)
4584             FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
4585               {
4586                 if (codecvt1 == CALL_EXPR)
4587                   {
4588                     new_stmt = gimple_build_call (decl1, 1, vop0);
4589                     new_temp = make_ssa_name (vec_dest, new_stmt);
4590                     gimple_call_set_lhs (new_stmt, new_temp);
4591                   }
4592                 else
4593                   {
4594                     gcc_assert (TREE_CODE_LENGTH (codecvt1) == unary_op);
4595                     new_temp = make_ssa_name (vec_dest);
4596                     new_stmt = gimple_build_assign (new_temp, codecvt1,
4597                                                     vop0);
4598                   }
4599
4600                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
4601                 vec_oprnds0[i] = new_temp;
4602               }
4603
4604           vect_create_vectorized_demotion_stmts (&vec_oprnds0, multi_step_cvt,
4605                                                  stmt, vec_dsts, gsi,
4606                                                  slp_node, code1,
4607                                                  &prev_stmt_info);
4608         }
4609
4610       *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
4611       break;
4612     }
4613
4614   vec_oprnds0.release ();
4615   vec_oprnds1.release ();
4616   interm_types.release ();
4617
4618   return true;
4619 }
4620
4621
4622 /* Function vectorizable_assignment.
4623
4624    Check if STMT performs an assignment (copy) that can be vectorized.
4625    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
4626    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
4627    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
4628
4629 static bool
4630 vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi,
4631                          gimple **vec_stmt, slp_tree slp_node)
4632 {
4633   tree vec_dest;
4634   tree scalar_dest;
4635   tree op;
4636   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4637   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4638   tree new_temp;
4639   gimple *def_stmt;
4640   enum vect_def_type dt[1] = {vect_unknown_def_type};
4641   int ndts = 1;
4642   int ncopies;
4643   int i, j;
4644   vec<tree> vec_oprnds = vNULL;
4645   tree vop;
4646   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
4647   vec_info *vinfo = stmt_info->vinfo;
4648   gimple *new_stmt = NULL;
4649   stmt_vec_info prev_stmt_info = NULL;
4650   enum tree_code code;
4651   tree vectype_in;
4652
4653   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
4654     return false;
4655
4656   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
4657       && ! vec_stmt)
4658     return false;
4659
4660   /* Is vectorizable assignment?  */
4661   if (!is_gimple_assign (stmt))
4662     return false;
4663
4664   scalar_dest = gimple_assign_lhs (stmt);
4665   if (TREE_CODE (scalar_dest) != SSA_NAME)
4666     return false;
4667
4668   code = gimple_assign_rhs_code (stmt);
4669   if (gimple_assign_single_p (stmt)
4670       || code == PAREN_EXPR
4671       || CONVERT_EXPR_CODE_P (code))
4672     op = gimple_assign_rhs1 (stmt);
4673   else
4674     return false;
4675
4676   if (code == VIEW_CONVERT_EXPR)
4677     op = TREE_OPERAND (op, 0);
4678
4679   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4680   unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype);
4681
4682   /* Multiple types in SLP are handled by creating the appropriate number of
4683      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
4684      case of SLP.  */
4685   if (slp_node)
4686     ncopies = 1;
4687   else
4688     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
4689
4690   gcc_assert (ncopies >= 1);
4691
4692   if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[0], &vectype_in))
4693     {
4694       if (dump_enabled_p ())
4695         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4696                          "use not simple.\n");
4697       return false;
4698     }
4699
4700   /* We can handle NOP_EXPR conversions that do not change the number
4701      of elements or the vector size.  */
4702   if ((CONVERT_EXPR_CODE_P (code)
4703        || code == VIEW_CONVERT_EXPR)
4704       && (!vectype_in
4705           || TYPE_VECTOR_SUBPARTS (vectype_in) != nunits
4706           || (GET_MODE_SIZE (TYPE_MODE (vectype))
4707               != GET_MODE_SIZE (TYPE_MODE (vectype_in)))))
4708     return false;
4709
4710   /* We do not handle bit-precision changes.  */
4711   if ((CONVERT_EXPR_CODE_P (code)
4712        || code == VIEW_CONVERT_EXPR)
4713       && INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
4714       && (!type_has_mode_precision_p (TREE_TYPE (scalar_dest))
4715           || !type_has_mode_precision_p (TREE_TYPE (op)))
4716       /* But a conversion that does not change the bit-pattern is ok.  */
4717       && !((TYPE_PRECISION (TREE_TYPE (scalar_dest))
4718             > TYPE_PRECISION (TREE_TYPE (op)))
4719            && TYPE_UNSIGNED (TREE_TYPE (op)))
4720       /* Conversion between boolean types of different sizes is
4721          a simple assignment in case their vectypes are same
4722          boolean vectors.  */
4723       && (!VECTOR_BOOLEAN_TYPE_P (vectype)
4724           || !VECTOR_BOOLEAN_TYPE_P (vectype_in)))
4725     {
4726       if (dump_enabled_p ())
4727         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4728                          "type conversion to/from bit-precision "
4729                          "unsupported.\n");
4730       return false;
4731     }
4732
4733   if (!vec_stmt) /* transformation not required.  */
4734     {
4735       STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
4736       if (dump_enabled_p ())
4737         dump_printf_loc (MSG_NOTE, vect_location,
4738                          "=== vectorizable_assignment ===\n");
4739       vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
4740       return true;
4741     }
4742
4743   /* Transform.  */
4744   if (dump_enabled_p ())
4745     dump_printf_loc (MSG_NOTE, vect_location, "transform assignment.\n");
4746
4747   /* Handle def.  */
4748   vec_dest = vect_create_destination_var (scalar_dest, vectype);
4749
4750   /* Handle use.  */
4751   for (j = 0; j < ncopies; j++)
4752     {
4753       /* Handle uses.  */
4754       if (j == 0)
4755         vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
4756       else
4757         vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
4758
4759       /* Arguments are ready. create the new vector stmt.  */
4760       FOR_EACH_VEC_ELT (vec_oprnds, i, vop)
4761        {
4762          if (CONVERT_EXPR_CODE_P (code)
4763              || code == VIEW_CONVERT_EXPR)
4764            vop = build1 (VIEW_CONVERT_EXPR, vectype, vop);
4765          new_stmt = gimple_build_assign (vec_dest, vop);
4766          new_temp = make_ssa_name (vec_dest, new_stmt);
4767          gimple_assign_set_lhs (new_stmt, new_temp);
4768          vect_finish_stmt_generation (stmt, new_stmt, gsi);
4769          if (slp_node)
4770            SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
4771        }
4772
4773       if (slp_node)
4774         continue;
4775
4776       if (j == 0)
4777         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
4778       else
4779         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4780
4781       prev_stmt_info = vinfo_for_stmt (new_stmt);
4782     }
4783
4784   vec_oprnds.release ();
4785   return true;
4786 }
4787
4788
4789 /* Return TRUE if CODE (a shift operation) is supported for SCALAR_TYPE
4790    either as shift by a scalar or by a vector.  */
4791
4792 bool
4793 vect_supportable_shift (enum tree_code code, tree scalar_type)
4794 {
4795
4796   machine_mode vec_mode;
4797   optab optab;
4798   int icode;
4799   tree vectype;
4800
4801   vectype = get_vectype_for_scalar_type (scalar_type);
4802   if (!vectype)
4803     return false;
4804
4805   optab = optab_for_tree_code (code, vectype, optab_scalar);
4806   if (!optab
4807       || optab_handler (optab, TYPE_MODE (vectype)) == CODE_FOR_nothing)
4808     {
4809       optab = optab_for_tree_code (code, vectype, optab_vector);
4810       if (!optab
4811           || (optab_handler (optab, TYPE_MODE (vectype))
4812                       == CODE_FOR_nothing))
4813         return false;
4814     }
4815
4816   vec_mode = TYPE_MODE (vectype);
4817   icode = (int) optab_handler (optab, vec_mode);
4818   if (icode == CODE_FOR_nothing)
4819     return false;
4820
4821   return true;
4822 }
4823
4824
4825 /* Function vectorizable_shift.
4826
4827    Check if STMT performs a shift operation that can be vectorized.
4828    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
4829    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
4830    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
4831
4832 static bool
4833 vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
4834                     gimple **vec_stmt, slp_tree slp_node)
4835 {
4836   tree vec_dest;
4837   tree scalar_dest;
4838   tree op0, op1 = NULL;
4839   tree vec_oprnd1 = NULL_TREE;
4840   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4841   tree vectype;
4842   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4843   enum tree_code code;
4844   machine_mode vec_mode;
4845   tree new_temp;
4846   optab optab;
4847   int icode;
4848   machine_mode optab_op2_mode;
4849   gimple *def_stmt;
4850   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
4851   int ndts = 2;
4852   gimple *new_stmt = NULL;
4853   stmt_vec_info prev_stmt_info;
4854   int nunits_in;
4855   int nunits_out;
4856   tree vectype_out;
4857   tree op1_vectype;
4858   int ncopies;
4859   int j, i;
4860   vec<tree> vec_oprnds0 = vNULL;
4861   vec<tree> vec_oprnds1 = vNULL;
4862   tree vop0, vop1;
4863   unsigned int k;
4864   bool scalar_shift_arg = true;
4865   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
4866   vec_info *vinfo = stmt_info->vinfo;
4867   int vf;
4868
4869   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
4870     return false;
4871
4872   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
4873       && ! vec_stmt)
4874     return false;
4875
4876   /* Is STMT a vectorizable binary/unary operation?   */
4877   if (!is_gimple_assign (stmt))
4878     return false;
4879
4880   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
4881     return false;
4882
4883   code = gimple_assign_rhs_code (stmt);
4884
4885   if (!(code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR
4886       || code == RROTATE_EXPR))
4887     return false;
4888
4889   scalar_dest = gimple_assign_lhs (stmt);
4890   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
4891   if (!type_has_mode_precision_p (TREE_TYPE (scalar_dest)))
4892     {
4893       if (dump_enabled_p ())
4894         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4895                          "bit-precision shifts not supported.\n");
4896       return false;
4897     }
4898
4899   op0 = gimple_assign_rhs1 (stmt);
4900   if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
4901     {
4902       if (dump_enabled_p ())
4903         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4904                          "use not simple.\n");
4905       return false;
4906     }
4907   /* If op0 is an external or constant def use a vector type with
4908      the same size as the output vector type.  */
4909   if (!vectype)
4910     vectype = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
4911   if (vec_stmt)
4912     gcc_assert (vectype);
4913   if (!vectype)
4914     {
4915       if (dump_enabled_p ())
4916         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4917                          "no vectype for scalar type\n");
4918       return false;
4919     }
4920
4921   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
4922   nunits_in = TYPE_VECTOR_SUBPARTS (vectype);
4923   if (nunits_out != nunits_in)
4924     return false;
4925
4926   op1 = gimple_assign_rhs2 (stmt);
4927   if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &op1_vectype))
4928     {
4929       if (dump_enabled_p ())
4930         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4931                          "use not simple.\n");
4932       return false;
4933     }
4934
4935   if (loop_vinfo)
4936     vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
4937   else
4938     vf = 1;
4939
4940   /* Multiple types in SLP are handled by creating the appropriate number of
4941      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
4942      case of SLP.  */
4943   if (slp_node)
4944     ncopies = 1;
4945   else
4946     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
4947
4948   gcc_assert (ncopies >= 1);
4949
4950   /* Determine whether the shift amount is a vector, or scalar.  If the
4951      shift/rotate amount is a vector, use the vector/vector shift optabs.  */
4952
4953   if ((dt[1] == vect_internal_def
4954        || dt[1] == vect_induction_def)
4955       && !slp_node)
4956     scalar_shift_arg = false;
4957   else if (dt[1] == vect_constant_def
4958            || dt[1] == vect_external_def
4959            || dt[1] == vect_internal_def)
4960     {
4961       /* In SLP, need to check whether the shift count is the same,
4962          in loops if it is a constant or invariant, it is always
4963          a scalar shift.  */
4964       if (slp_node)
4965         {
4966           vec<gimple *> stmts = SLP_TREE_SCALAR_STMTS (slp_node);
4967           gimple *slpstmt;
4968
4969           FOR_EACH_VEC_ELT (stmts, k, slpstmt)
4970             if (!operand_equal_p (gimple_assign_rhs2 (slpstmt), op1, 0))
4971               scalar_shift_arg = false;
4972         }
4973
4974       /* If the shift amount is computed by a pattern stmt we cannot
4975          use the scalar amount directly thus give up and use a vector
4976          shift.  */
4977       if (dt[1] == vect_internal_def)
4978         {
4979           gimple *def = SSA_NAME_DEF_STMT (op1);
4980           if (is_pattern_stmt_p (vinfo_for_stmt (def)))
4981             scalar_shift_arg = false;
4982         }
4983     }
4984   else
4985     {
4986       if (dump_enabled_p ())
4987         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4988                          "operand mode requires invariant argument.\n");
4989       return false;
4990     }
4991
4992   /* Vector shifted by vector.  */
4993   if (!scalar_shift_arg)
4994     {
4995       optab = optab_for_tree_code (code, vectype, optab_vector);
4996       if (dump_enabled_p ())
4997         dump_printf_loc (MSG_NOTE, vect_location,
4998                          "vector/vector shift/rotate found.\n");
4999
5000       if (!op1_vectype)
5001         op1_vectype = get_same_sized_vectype (TREE_TYPE (op1), vectype_out);
5002       if (op1_vectype == NULL_TREE
5003           || TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
5004         {
5005           if (dump_enabled_p ())
5006             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5007                              "unusable type for last operand in"
5008                              " vector/vector shift/rotate.\n");
5009           return false;
5010         }
5011     }
5012   /* See if the machine has a vector shifted by scalar insn and if not
5013      then see if it has a vector shifted by vector insn.  */
5014   else
5015     {
5016       optab = optab_for_tree_code (code, vectype, optab_scalar);
5017       if (optab
5018           && optab_handler (optab, TYPE_MODE (vectype)) != CODE_FOR_nothing)
5019         {
5020           if (dump_enabled_p ())
5021             dump_printf_loc (MSG_NOTE, vect_location,
5022                              "vector/scalar shift/rotate found.\n");
5023         }
5024       else
5025         {
5026           optab = optab_for_tree_code (code, vectype, optab_vector);
5027           if (optab
5028                && (optab_handler (optab, TYPE_MODE (vectype))
5029                       != CODE_FOR_nothing))
5030             {
5031               scalar_shift_arg = false;
5032
5033               if (dump_enabled_p ())
5034                 dump_printf_loc (MSG_NOTE, vect_location,
5035                                  "vector/vector shift/rotate found.\n");
5036
5037               /* Unlike the other binary operators, shifts/rotates have
5038                  the rhs being int, instead of the same type as the lhs,
5039                  so make sure the scalar is the right type if we are
5040                  dealing with vectors of long long/long/short/char.  */
5041               if (dt[1] == vect_constant_def)
5042                 op1 = fold_convert (TREE_TYPE (vectype), op1);
5043               else if (!useless_type_conversion_p (TREE_TYPE (vectype),
5044                                                    TREE_TYPE (op1)))
5045                 {
5046                   if (slp_node
5047                       && TYPE_MODE (TREE_TYPE (vectype))
5048                          != TYPE_MODE (TREE_TYPE (op1)))
5049                     {
5050                       if (dump_enabled_p ())
5051                         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5052                                          "unusable type for last operand in"
5053                                          " vector/vector shift/rotate.\n");
5054                       return false;
5055                     }
5056                   if (vec_stmt && !slp_node)
5057                     {
5058                       op1 = fold_convert (TREE_TYPE (vectype), op1);
5059                       op1 = vect_init_vector (stmt, op1,
5060                                               TREE_TYPE (vectype), NULL);
5061                     }
5062                 }
5063             }
5064         }
5065     }
5066
5067   /* Supportable by target?  */
5068   if (!optab)
5069     {
5070       if (dump_enabled_p ())
5071         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5072                          "no optab.\n");
5073       return false;
5074     }
5075   vec_mode = TYPE_MODE (vectype);
5076   icode = (int) optab_handler (optab, vec_mode);
5077   if (icode == CODE_FOR_nothing)
5078     {
5079       if (dump_enabled_p ())
5080         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5081                          "op not supported by target.\n");
5082       /* Check only during analysis.  */
5083       if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
5084           || (vf < vect_min_worthwhile_factor (code)
5085               && !vec_stmt))
5086         return false;
5087       if (dump_enabled_p ())
5088         dump_printf_loc (MSG_NOTE, vect_location,
5089                          "proceeding using word mode.\n");
5090     }
5091
5092   /* Worthwhile without SIMD support?  Check only during analysis.  */
5093   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
5094       && vf < vect_min_worthwhile_factor (code)
5095       && !vec_stmt)
5096     {
5097       if (dump_enabled_p ())
5098         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5099                          "not worthwhile without SIMD support.\n");
5100       return false;
5101     }
5102
5103   if (!vec_stmt) /* transformation not required.  */
5104     {
5105       STMT_VINFO_TYPE (stmt_info) = shift_vec_info_type;
5106       if (dump_enabled_p ())
5107         dump_printf_loc (MSG_NOTE, vect_location,
5108                          "=== vectorizable_shift ===\n");
5109       vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
5110       return true;
5111     }
5112
5113   /* Transform.  */
5114
5115   if (dump_enabled_p ())
5116     dump_printf_loc (MSG_NOTE, vect_location,
5117                      "transform binary/unary operation.\n");
5118
5119   /* Handle def.  */
5120   vec_dest = vect_create_destination_var (scalar_dest, vectype);
5121
5122   prev_stmt_info = NULL;
5123   for (j = 0; j < ncopies; j++)
5124     {
5125       /* Handle uses.  */
5126       if (j == 0)
5127         {
5128           if (scalar_shift_arg)
5129             {
5130               /* Vector shl and shr insn patterns can be defined with scalar
5131                  operand 2 (shift operand).  In this case, use constant or loop
5132                  invariant op1 directly, without extending it to vector mode
5133                  first.  */
5134               optab_op2_mode = insn_data[icode].operand[2].mode;
5135               if (!VECTOR_MODE_P (optab_op2_mode))
5136                 {
5137                   if (dump_enabled_p ())
5138                     dump_printf_loc (MSG_NOTE, vect_location,
5139                                      "operand 1 using scalar mode.\n");
5140                   vec_oprnd1 = op1;
5141                   vec_oprnds1.create (slp_node ? slp_node->vec_stmts_size : 1);
5142                   vec_oprnds1.quick_push (vec_oprnd1);
5143                   if (slp_node)
5144                     {
5145                       /* Store vec_oprnd1 for every vector stmt to be created
5146                          for SLP_NODE.  We check during the analysis that all
5147                          the shift arguments are the same.
5148                          TODO: Allow different constants for different vector
5149                          stmts generated for an SLP instance.  */
5150                       for (k = 0; k < slp_node->vec_stmts_size - 1; k++)
5151                         vec_oprnds1.quick_push (vec_oprnd1);
5152                     }
5153                 }
5154             }
5155
5156           /* vec_oprnd1 is available if operand 1 should be of a scalar-type
5157              (a special case for certain kind of vector shifts); otherwise,
5158              operand 1 should be of a vector type (the usual case).  */
5159           if (vec_oprnd1)
5160             vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
5161                                slp_node);
5162           else
5163             vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
5164                                slp_node);
5165         }
5166       else
5167         vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
5168
5169       /* Arguments are ready.  Create the new vector stmt.  */
5170       FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
5171         {
5172           vop1 = vec_oprnds1[i];
5173           new_stmt = gimple_build_assign (vec_dest, code, vop0, vop1);
5174           new_temp = make_ssa_name (vec_dest, new_stmt);
5175           gimple_assign_set_lhs (new_stmt, new_temp);
5176           vect_finish_stmt_generation (stmt, new_stmt, gsi);
5177           if (slp_node)
5178             SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
5179         }
5180
5181       if (slp_node)
5182         continue;
5183
5184       if (j == 0)
5185         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
5186       else
5187         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
5188       prev_stmt_info = vinfo_for_stmt (new_stmt);
5189     }
5190
5191   vec_oprnds0.release ();
5192   vec_oprnds1.release ();
5193
5194   return true;
5195 }
5196
5197
5198 /* Function vectorizable_operation.
5199
5200    Check if STMT performs a binary, unary or ternary operation that can
5201    be vectorized.
5202    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
5203    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
5204    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
5205
5206 static bool
5207 vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
5208                         gimple **vec_stmt, slp_tree slp_node)
5209 {
5210   tree vec_dest;
5211   tree scalar_dest;
5212   tree op0, op1 = NULL_TREE, op2 = NULL_TREE;
5213   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5214   tree vectype;
5215   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
5216   enum tree_code code;
5217   machine_mode vec_mode;
5218   tree new_temp;
5219   int op_type;
5220   optab optab;
5221   bool target_support_p;
5222   gimple *def_stmt;
5223   enum vect_def_type dt[3]
5224     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
5225   int ndts = 3;
5226   gimple *new_stmt = NULL;
5227   stmt_vec_info prev_stmt_info;
5228   int nunits_in;
5229   int nunits_out;
5230   tree vectype_out;
5231   int ncopies;
5232   int j, i;
5233   vec<tree> vec_oprnds0 = vNULL;
5234   vec<tree> vec_oprnds1 = vNULL;
5235   vec<tree> vec_oprnds2 = vNULL;
5236   tree vop0, vop1, vop2;
5237   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
5238   vec_info *vinfo = stmt_info->vinfo;
5239   int vf;
5240
5241   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
5242     return false;
5243
5244   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
5245       && ! vec_stmt)
5246     return false;
5247
5248   /* Is STMT a vectorizable binary/unary operation?   */
5249   if (!is_gimple_assign (stmt))
5250     return false;
5251
5252   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
5253     return false;
5254
5255   code = gimple_assign_rhs_code (stmt);
5256
5257   /* For pointer addition, we should use the normal plus for
5258      the vector addition.  */
5259   if (code == POINTER_PLUS_EXPR)
5260     code = PLUS_EXPR;
5261
5262   /* Support only unary or binary operations.  */
5263   op_type = TREE_CODE_LENGTH (code);
5264   if (op_type != unary_op && op_type != binary_op && op_type != ternary_op)
5265     {
5266       if (dump_enabled_p ())
5267         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5268                          "num. args = %d (not unary/binary/ternary op).\n",
5269                          op_type);
5270       return false;
5271     }
5272
5273   scalar_dest = gimple_assign_lhs (stmt);
5274   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
5275
5276   /* Most operations cannot handle bit-precision types without extra
5277      truncations.  */
5278   if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
5279       && !type_has_mode_precision_p (TREE_TYPE (scalar_dest))
5280       /* Exception are bitwise binary operations.  */
5281       && code != BIT_IOR_EXPR
5282       && code != BIT_XOR_EXPR
5283       && code != BIT_AND_EXPR)
5284     {
5285       if (dump_enabled_p ())
5286         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5287                          "bit-precision arithmetic not supported.\n");
5288       return false;
5289     }
5290
5291   op0 = gimple_assign_rhs1 (stmt);
5292   if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
5293     {
5294       if (dump_enabled_p ())
5295         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5296                          "use not simple.\n");
5297       return false;
5298     }
5299   /* If op0 is an external or constant def use a vector type with
5300      the same size as the output vector type.  */
5301   if (!vectype)
5302     {
5303       /* For boolean type we cannot determine vectype by
5304          invariant value (don't know whether it is a vector
5305          of booleans or vector of integers).  We use output
5306          vectype because operations on boolean don't change
5307          type.  */
5308       if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op0)))
5309         {
5310           if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (scalar_dest)))
5311             {
5312               if (dump_enabled_p ())
5313                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5314                                  "not supported operation on bool value.\n");
5315               return false;
5316             }
5317           vectype = vectype_out;
5318         }
5319       else
5320         vectype = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
5321     }
5322   if (vec_stmt)
5323     gcc_assert (vectype);
5324   if (!vectype)
5325     {
5326       if (dump_enabled_p ())
5327         {
5328           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5329                            "no vectype for scalar type ");
5330           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
5331                              TREE_TYPE (op0));
5332           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
5333         }
5334
5335       return false;
5336     }
5337
5338   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
5339   nunits_in = TYPE_VECTOR_SUBPARTS (vectype);
5340   if (nunits_out != nunits_in)
5341     return false;
5342
5343   if (op_type == binary_op || op_type == ternary_op)
5344     {
5345       op1 = gimple_assign_rhs2 (stmt);
5346       if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]))
5347         {
5348           if (dump_enabled_p ())
5349             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5350                              "use not simple.\n");
5351           return false;
5352         }
5353     }
5354   if (op_type == ternary_op)
5355     {
5356       op2 = gimple_assign_rhs3 (stmt);
5357       if (!vect_is_simple_use (op2, vinfo, &def_stmt, &dt[2]))
5358         {
5359           if (dump_enabled_p ())
5360             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5361                              "use not simple.\n");
5362           return false;
5363         }
5364     }
5365
5366   if (loop_vinfo)
5367     vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
5368   else
5369     vf = 1;
5370
5371   /* Multiple types in SLP are handled by creating the appropriate number of
5372      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
5373      case of SLP.  */
5374   if (slp_node)
5375     ncopies = 1;
5376   else
5377     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
5378
5379   gcc_assert (ncopies >= 1);
5380
5381   /* Shifts are handled in vectorizable_shift ().  */
5382   if (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR
5383       || code == RROTATE_EXPR)
5384    return false;
5385
5386   /* Supportable by target?  */
5387
5388   vec_mode = TYPE_MODE (vectype);
5389   if (code == MULT_HIGHPART_EXPR)
5390     target_support_p = can_mult_highpart_p (vec_mode, TYPE_UNSIGNED (vectype));
5391   else
5392     {
5393       optab = optab_for_tree_code (code, vectype, optab_default);
5394       if (!optab)
5395         {
5396           if (dump_enabled_p ())
5397             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5398                              "no optab.\n");
5399           return false;
5400         }
5401       target_support_p = (optab_handler (optab, vec_mode)
5402                           != CODE_FOR_nothing);
5403     }
5404
5405   if (!target_support_p)
5406     {
5407       if (dump_enabled_p ())
5408         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5409                          "op not supported by target.\n");
5410       /* Check only during analysis.  */
5411       if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
5412           || (!vec_stmt && vf < vect_min_worthwhile_factor (code)))
5413         return false;
5414       if (dump_enabled_p ())
5415         dump_printf_loc (MSG_NOTE, vect_location,
5416                          "proceeding using word mode.\n");
5417     }
5418
5419   /* Worthwhile without SIMD support?  Check only during analysis.  */
5420   if (!VECTOR_MODE_P (vec_mode)
5421       && !vec_stmt
5422       && vf < vect_min_worthwhile_factor (code))
5423     {
5424       if (dump_enabled_p ())
5425         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5426                          "not worthwhile without SIMD support.\n");
5427       return false;
5428     }
5429
5430   if (!vec_stmt) /* transformation not required.  */
5431     {
5432       STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
5433       if (dump_enabled_p ())
5434         dump_printf_loc (MSG_NOTE, vect_location,
5435                          "=== vectorizable_operation ===\n");
5436       vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
5437       return true;
5438     }
5439
5440   /* Transform.  */
5441
5442   if (dump_enabled_p ())
5443     dump_printf_loc (MSG_NOTE, vect_location,
5444                      "transform binary/unary operation.\n");
5445
5446   /* Handle def.  */
5447   vec_dest = vect_create_destination_var (scalar_dest, vectype);
5448
5449   /* In case the vectorization factor (VF) is bigger than the number
5450      of elements that we can fit in a vectype (nunits), we have to generate
5451      more than one vector stmt - i.e - we need to "unroll" the
5452      vector stmt by a factor VF/nunits.  In doing so, we record a pointer
5453      from one copy of the vector stmt to the next, in the field
5454      STMT_VINFO_RELATED_STMT.  This is necessary in order to allow following
5455      stages to find the correct vector defs to be used when vectorizing
5456      stmts that use the defs of the current stmt.  The example below
5457      illustrates the vectorization process when VF=16 and nunits=4 (i.e.,
5458      we need to create 4 vectorized stmts):
5459
5460      before vectorization:
5461                                 RELATED_STMT    VEC_STMT
5462         S1:     x = memref      -               -
5463         S2:     z = x + 1       -               -
5464
5465      step 1: vectorize stmt S1 (done in vectorizable_load. See more details
5466              there):
5467                                 RELATED_STMT    VEC_STMT
5468         VS1_0:  vx0 = memref0   VS1_1           -
5469         VS1_1:  vx1 = memref1   VS1_2           -
5470         VS1_2:  vx2 = memref2   VS1_3           -
5471         VS1_3:  vx3 = memref3   -               -
5472         S1:     x = load        -               VS1_0
5473         S2:     z = x + 1       -               -
5474
5475      step2: vectorize stmt S2 (done here):
5476         To vectorize stmt S2 we first need to find the relevant vector
5477         def for the first operand 'x'.  This is, as usual, obtained from
5478         the vector stmt recorded in the STMT_VINFO_VEC_STMT of the stmt
5479         that defines 'x' (S1).  This way we find the stmt VS1_0, and the
5480         relevant vector def 'vx0'.  Having found 'vx0' we can generate
5481         the vector stmt VS2_0, and as usual, record it in the
5482         STMT_VINFO_VEC_STMT of stmt S2.
5483         When creating the second copy (VS2_1), we obtain the relevant vector
5484         def from the vector stmt recorded in the STMT_VINFO_RELATED_STMT of
5485         stmt VS1_0.  This way we find the stmt VS1_1 and the relevant
5486         vector def 'vx1'.  Using 'vx1' we create stmt VS2_1 and record a
5487         pointer to it in the STMT_VINFO_RELATED_STMT of the vector stmt VS2_0.
5488         Similarly when creating stmts VS2_2 and VS2_3.  This is the resulting
5489         chain of stmts and pointers:
5490                                 RELATED_STMT    VEC_STMT
5491         VS1_0:  vx0 = memref0   VS1_1           -
5492         VS1_1:  vx1 = memref1   VS1_2           -
5493         VS1_2:  vx2 = memref2   VS1_3           -
5494         VS1_3:  vx3 = memref3   -               -
5495         S1:     x = load        -               VS1_0
5496         VS2_0:  vz0 = vx0 + v1  VS2_1           -
5497         VS2_1:  vz1 = vx1 + v1  VS2_2           -
5498         VS2_2:  vz2 = vx2 + v1  VS2_3           -
5499         VS2_3:  vz3 = vx3 + v1  -               -
5500         S2:     z = x + 1       -               VS2_0  */
5501
5502   prev_stmt_info = NULL;
5503   for (j = 0; j < ncopies; j++)
5504     {
5505       /* Handle uses.  */
5506       if (j == 0)
5507         {
5508           if (op_type == binary_op || op_type == ternary_op)
5509             vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
5510                                slp_node);
5511           else
5512             vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
5513                                slp_node);
5514           if (op_type == ternary_op)
5515             vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL,
5516                                slp_node);
5517         }
5518       else
5519         {
5520           vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
5521           if (op_type == ternary_op)
5522             {
5523               tree vec_oprnd = vec_oprnds2.pop ();
5524               vec_oprnds2.quick_push (vect_get_vec_def_for_stmt_copy (dt[2],
5525                                                                    vec_oprnd));
5526             }
5527         }
5528
5529       /* Arguments are ready.  Create the new vector stmt.  */
5530       FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
5531         {
5532           vop1 = ((op_type == binary_op || op_type == ternary_op)
5533                   ? vec_oprnds1[i] : NULL_TREE);
5534           vop2 = ((op_type == ternary_op)
5535                   ? vec_oprnds2[i] : NULL_TREE);
5536           new_stmt = gimple_build_assign (vec_dest, code, vop0, vop1, vop2);
5537           new_temp = make_ssa_name (vec_dest, new_stmt);
5538           gimple_assign_set_lhs (new_stmt, new_temp);
5539           vect_finish_stmt_generation (stmt, new_stmt, gsi);
5540           if (slp_node)
5541             SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
5542         }
5543
5544       if (slp_node)
5545         continue;
5546
5547       if (j == 0)
5548         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
5549       else
5550         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
5551       prev_stmt_info = vinfo_for_stmt (new_stmt);
5552     }
5553
5554   vec_oprnds0.release ();
5555   vec_oprnds1.release ();
5556   vec_oprnds2.release ();
5557
5558   return true;
5559 }
5560
5561 /* A helper function to ensure data reference DR's base alignment
5562    for STMT_INFO.  */
5563
5564 static void
5565 ensure_base_align (stmt_vec_info stmt_info, struct data_reference *dr)
5566 {
5567   if (!dr->aux)
5568     return;
5569
5570   if (DR_VECT_AUX (dr)->base_misaligned)
5571     {
5572       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
5573       tree base_decl = DR_VECT_AUX (dr)->base_decl;
5574
5575       if (decl_in_symtab_p (base_decl))
5576         symtab_node::get (base_decl)->increase_alignment (TYPE_ALIGN (vectype));
5577       else
5578         {
5579           SET_DECL_ALIGN (base_decl, TYPE_ALIGN (vectype));
5580           DECL_USER_ALIGN (base_decl) = 1;
5581         }
5582       DR_VECT_AUX (dr)->base_misaligned = false;
5583     }
5584 }
5585
5586
5587 /* Function get_group_alias_ptr_type.
5588
5589    Return the alias type for the group starting at FIRST_STMT.  */
5590
5591 static tree
5592 get_group_alias_ptr_type (gimple *first_stmt)
5593 {
5594   struct data_reference *first_dr, *next_dr;
5595   gimple *next_stmt;
5596
5597   first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
5598   next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (first_stmt));
5599   while (next_stmt)
5600     {
5601       next_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (next_stmt));
5602       if (get_alias_set (DR_REF (first_dr))
5603           != get_alias_set (DR_REF (next_dr)))
5604         {
5605           if (dump_enabled_p ())
5606             dump_printf_loc (MSG_NOTE, vect_location,
5607                              "conflicting alias set types.\n");
5608           return ptr_type_node;
5609         }
5610       next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
5611     }
5612   return reference_alias_ptr_type (DR_REF (first_dr));
5613 }
5614
5615
5616 /* Function vectorizable_store.
5617
5618    Check if STMT defines a non scalar data-ref (array/pointer/structure) that
5619    can be vectorized.
5620    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
5621    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
5622    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
5623
5624 static bool
5625 vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
5626                     slp_tree slp_node)
5627 {
5628   tree scalar_dest;
5629   tree data_ref;
5630   tree op;
5631   tree vec_oprnd = NULL_TREE;
5632   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5633   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr = NULL;
5634   tree elem_type;
5635   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
5636   struct loop *loop = NULL;
5637   machine_mode vec_mode;
5638   tree dummy;
5639   enum dr_alignment_support alignment_support_scheme;
5640   gimple *def_stmt;
5641   enum vect_def_type dt;
5642   stmt_vec_info prev_stmt_info = NULL;
5643   tree dataref_ptr = NULL_TREE;
5644   tree dataref_offset = NULL_TREE;
5645   gimple *ptr_incr = NULL;
5646   int ncopies;
5647   int j;
5648   gimple *next_stmt, *first_stmt;
5649   bool grouped_store;
5650   unsigned int group_size, i;
5651   vec<tree> oprnds = vNULL;
5652   vec<tree> result_chain = vNULL;
5653   bool inv_p;
5654   tree offset = NULL_TREE;
5655   vec<tree> vec_oprnds = vNULL;
5656   bool slp = (slp_node != NULL);
5657   unsigned int vec_num;
5658   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
5659   vec_info *vinfo = stmt_info->vinfo;
5660   tree aggr_type;
5661   gather_scatter_info gs_info;
5662   enum vect_def_type scatter_src_dt = vect_unknown_def_type;
5663   gimple *new_stmt;
5664   int vf;
5665   vec_load_store_type vls_type;
5666   tree ref_type;
5667
5668   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
5669     return false;
5670
5671   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
5672       && ! vec_stmt)
5673     return false;
5674
5675   /* Is vectorizable store? */
5676
5677   if (!is_gimple_assign (stmt))
5678     return false;
5679
5680   scalar_dest = gimple_assign_lhs (stmt);
5681   if (TREE_CODE (scalar_dest) == VIEW_CONVERT_EXPR
5682       && is_pattern_stmt_p (stmt_info))
5683     scalar_dest = TREE_OPERAND (scalar_dest, 0);
5684   if (TREE_CODE (scalar_dest) != ARRAY_REF
5685       && TREE_CODE (scalar_dest) != BIT_FIELD_REF
5686       && TREE_CODE (scalar_dest) != INDIRECT_REF
5687       && TREE_CODE (scalar_dest) != COMPONENT_REF
5688       && TREE_CODE (scalar_dest) != IMAGPART_EXPR
5689       && TREE_CODE (scalar_dest) != REALPART_EXPR
5690       && TREE_CODE (scalar_dest) != MEM_REF)
5691     return false;
5692
5693   /* Cannot have hybrid store SLP -- that would mean storing to the
5694      same location twice.  */
5695   gcc_assert (slp == PURE_SLP_STMT (stmt_info));
5696
5697   gcc_assert (gimple_assign_single_p (stmt));
5698
5699   tree vectype = STMT_VINFO_VECTYPE (stmt_info), rhs_vectype = NULL_TREE;
5700   unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype);
5701
5702   if (loop_vinfo)
5703     {
5704       loop = LOOP_VINFO_LOOP (loop_vinfo);
5705       vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
5706     }
5707   else
5708     vf = 1;
5709
5710   /* Multiple types in SLP are handled by creating the appropriate number of
5711      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
5712      case of SLP.  */
5713   if (slp)
5714     ncopies = 1;
5715   else
5716     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
5717
5718   gcc_assert (ncopies >= 1);
5719
5720   /* FORNOW.  This restriction should be relaxed.  */
5721   if (loop && nested_in_vect_loop_p (loop, stmt) && ncopies > 1)
5722     {
5723       if (dump_enabled_p ())
5724         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5725                          "multiple types in nested loop.\n");
5726       return false;
5727     }
5728
5729   op = gimple_assign_rhs1 (stmt);
5730
5731   if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt, &rhs_vectype))
5732     {
5733       if (dump_enabled_p ())
5734         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5735                          "use not simple.\n");
5736       return false;
5737     }
5738
5739   if (dt == vect_constant_def || dt == vect_external_def)
5740     vls_type = VLS_STORE_INVARIANT;
5741   else
5742     vls_type = VLS_STORE;
5743
5744   if (rhs_vectype && !useless_type_conversion_p (vectype, rhs_vectype))
5745     return false;
5746
5747   elem_type = TREE_TYPE (vectype);
5748   vec_mode = TYPE_MODE (vectype);
5749
5750   /* FORNOW. In some cases can vectorize even if data-type not supported
5751      (e.g. - array initialization with 0).  */
5752   if (optab_handler (mov_optab, vec_mode) == CODE_FOR_nothing)
5753     return false;
5754
5755   if (!STMT_VINFO_DATA_REF (stmt_info))
5756     return false;
5757
5758   vect_memory_access_type memory_access_type;
5759   if (!get_load_store_type (stmt, vectype, slp, vls_type, ncopies,
5760                             &memory_access_type, &gs_info))
5761     return false;
5762
5763   if (!vec_stmt) /* transformation not required.  */
5764     {
5765       STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) = memory_access_type;
5766       STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
5767       /* The SLP costs are calculated during SLP analysis.  */
5768       if (!PURE_SLP_STMT (stmt_info))
5769         vect_model_store_cost (stmt_info, ncopies, memory_access_type, dt,
5770                                NULL, NULL, NULL);
5771       return true;
5772     }
5773   gcc_assert (memory_access_type == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info));
5774
5775   /* Transform.  */
5776
5777   ensure_base_align (stmt_info, dr);
5778
5779   if (memory_access_type == VMAT_GATHER_SCATTER)
5780     {
5781       tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE, op, src;
5782       tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gs_info.decl));
5783       tree rettype, srctype, ptrtype, idxtype, masktype, scaletype;
5784       tree ptr, mask, var, scale, perm_mask = NULL_TREE;
5785       edge pe = loop_preheader_edge (loop);
5786       gimple_seq seq;
5787       basic_block new_bb;
5788       enum { NARROW, NONE, WIDEN } modifier;
5789       int scatter_off_nunits = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype);
5790
5791       if (nunits == (unsigned int) scatter_off_nunits)
5792         modifier = NONE;
5793       else if (nunits == (unsigned int) scatter_off_nunits / 2)
5794         {
5795           unsigned char *sel = XALLOCAVEC (unsigned char, scatter_off_nunits);
5796           modifier = WIDEN;
5797
5798           for (i = 0; i < (unsigned int) scatter_off_nunits; ++i)
5799             sel[i] = i | nunits;
5800
5801           perm_mask = vect_gen_perm_mask_checked (gs_info.offset_vectype, sel);
5802           gcc_assert (perm_mask != NULL_TREE);
5803         }
5804       else if (nunits == (unsigned int) scatter_off_nunits * 2)
5805         {
5806           unsigned char *sel = XALLOCAVEC (unsigned char, nunits);
5807           modifier = NARROW;
5808
5809           for (i = 0; i < (unsigned int) nunits; ++i)
5810             sel[i] = i | scatter_off_nunits;
5811
5812           perm_mask = vect_gen_perm_mask_checked (vectype, sel);
5813           gcc_assert (perm_mask != NULL_TREE);
5814           ncopies *= 2;
5815         }
5816       else
5817         gcc_unreachable ();
5818
5819       rettype = TREE_TYPE (TREE_TYPE (gs_info.decl));
5820       ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
5821       masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
5822       idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
5823       srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
5824       scaletype = TREE_VALUE (arglist);
5825
5826       gcc_checking_assert (TREE_CODE (masktype) == INTEGER_TYPE
5827                            && TREE_CODE (rettype) == VOID_TYPE);
5828
5829       ptr = fold_convert (ptrtype, gs_info.base);
5830       if (!is_gimple_min_invariant (ptr))
5831         {
5832           ptr = force_gimple_operand (ptr, &seq, true, NULL_TREE);
5833           new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
5834           gcc_assert (!new_bb);
5835         }
5836
5837       /* Currently we support only unconditional scatter stores,
5838          so mask should be all ones.  */
5839       mask = build_int_cst (masktype, -1);
5840       mask = vect_init_vector (stmt, mask, masktype, NULL);
5841
5842       scale = build_int_cst (scaletype, gs_info.scale);
5843
5844       prev_stmt_info = NULL;
5845       for (j = 0; j < ncopies; ++j)
5846         {
5847           if (j == 0)
5848             {
5849               src = vec_oprnd1
5850                 = vect_get_vec_def_for_operand (gimple_assign_rhs1 (stmt), stmt);
5851               op = vec_oprnd0
5852                 = vect_get_vec_def_for_operand (gs_info.offset, stmt);
5853             }
5854           else if (modifier != NONE && (j & 1))
5855             {
5856               if (modifier == WIDEN)
5857                 {
5858                   src = vec_oprnd1
5859                     = vect_get_vec_def_for_stmt_copy (scatter_src_dt, vec_oprnd1);
5860                   op = permute_vec_elements (vec_oprnd0, vec_oprnd0, perm_mask,
5861                                              stmt, gsi);
5862                 }
5863               else if (modifier == NARROW)
5864                 {
5865                   src = permute_vec_elements (vec_oprnd1, vec_oprnd1, perm_mask,
5866                                               stmt, gsi);
5867                   op = vec_oprnd0
5868                     = vect_get_vec_def_for_stmt_copy (gs_info.offset_dt,
5869                                                       vec_oprnd0);
5870                 }
5871               else
5872                 gcc_unreachable ();
5873             }
5874           else
5875             {
5876               src = vec_oprnd1
5877                 = vect_get_vec_def_for_stmt_copy (scatter_src_dt, vec_oprnd1);
5878               op = vec_oprnd0
5879                 = vect_get_vec_def_for_stmt_copy (gs_info.offset_dt,
5880                                                   vec_oprnd0);
5881             }
5882
5883           if (!useless_type_conversion_p (srctype, TREE_TYPE (src)))
5884             {
5885               gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (src))
5886                           == TYPE_VECTOR_SUBPARTS (srctype));
5887               var = vect_get_new_ssa_name (srctype, vect_simple_var);
5888               src = build1 (VIEW_CONVERT_EXPR, srctype, src);
5889               new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, src);
5890               vect_finish_stmt_generation (stmt, new_stmt, gsi);
5891               src = var;
5892             }
5893
5894           if (!useless_type_conversion_p (idxtype, TREE_TYPE (op)))
5895             {
5896               gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
5897                           == TYPE_VECTOR_SUBPARTS (idxtype));
5898               var = vect_get_new_ssa_name (idxtype, vect_simple_var);
5899               op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
5900               new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
5901               vect_finish_stmt_generation (stmt, new_stmt, gsi);
5902               op = var;
5903             }
5904
5905           new_stmt
5906             = gimple_build_call (gs_info.decl, 5, ptr, mask, op, src, scale);
5907
5908           vect_finish_stmt_generation (stmt, new_stmt, gsi);
5909
5910           if (prev_stmt_info == NULL)
5911             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
5912           else
5913             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
5914           prev_stmt_info = vinfo_for_stmt (new_stmt);
5915         }
5916       return true;
5917     }
5918
5919   grouped_store = STMT_VINFO_GROUPED_ACCESS (stmt_info);
5920   if (grouped_store)
5921     {
5922       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
5923       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
5924       group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
5925
5926       GROUP_STORE_COUNT (vinfo_for_stmt (first_stmt))++;
5927
5928       /* FORNOW */
5929       gcc_assert (!loop || !nested_in_vect_loop_p (loop, stmt));
5930
5931       /* We vectorize all the stmts of the interleaving group when we
5932          reach the last stmt in the group.  */
5933       if (GROUP_STORE_COUNT (vinfo_for_stmt (first_stmt))
5934           < GROUP_SIZE (vinfo_for_stmt (first_stmt))
5935           && !slp)
5936         {
5937           *vec_stmt = NULL;
5938           return true;
5939         }
5940
5941       if (slp)
5942         {
5943           grouped_store = false;
5944           /* VEC_NUM is the number of vect stmts to be created for this 
5945              group.  */
5946           vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
5947           first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0]; 
5948           gcc_assert (GROUP_FIRST_ELEMENT (vinfo_for_stmt (first_stmt)) == first_stmt);
5949           first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
5950           op = gimple_assign_rhs1 (first_stmt);
5951         } 
5952       else
5953         /* VEC_NUM is the number of vect stmts to be created for this 
5954            group.  */
5955         vec_num = group_size;
5956
5957       ref_type = get_group_alias_ptr_type (first_stmt);
5958     }
5959   else
5960     {
5961       first_stmt = stmt;
5962       first_dr = dr;
5963       group_size = vec_num = 1;
5964       ref_type = reference_alias_ptr_type (DR_REF (first_dr));
5965     }
5966
5967   if (dump_enabled_p ())
5968     dump_printf_loc (MSG_NOTE, vect_location,
5969                      "transform store. ncopies = %d\n", ncopies);
5970
5971   if (memory_access_type == VMAT_ELEMENTWISE
5972       || memory_access_type == VMAT_STRIDED_SLP)
5973     {
5974       gimple_stmt_iterator incr_gsi;
5975       bool insert_after;
5976       gimple *incr;
5977       tree offvar;
5978       tree ivstep;
5979       tree running_off;
5980       gimple_seq stmts = NULL;
5981       tree stride_base, stride_step, alias_off;
5982       tree vec_oprnd;
5983       unsigned int g;
5984
5985       gcc_assert (!nested_in_vect_loop_p (loop, stmt));
5986
5987       stride_base
5988         = fold_build_pointer_plus
5989             (unshare_expr (DR_BASE_ADDRESS (first_dr)),
5990              size_binop (PLUS_EXPR,
5991                          convert_to_ptrofftype (unshare_expr (DR_OFFSET (first_dr))),
5992                          convert_to_ptrofftype (DR_INIT (first_dr))));
5993       stride_step = fold_convert (sizetype, unshare_expr (DR_STEP (first_dr)));
5994
5995       /* For a store with loop-invariant (but other than power-of-2)
5996          stride (i.e. not a grouped access) like so:
5997
5998            for (i = 0; i < n; i += stride)
5999              array[i] = ...;
6000
6001          we generate a new induction variable and new stores from
6002          the components of the (vectorized) rhs:
6003
6004            for (j = 0; ; j += VF*stride)
6005              vectemp = ...;
6006              tmp1 = vectemp[0];
6007              array[j] = tmp1;
6008              tmp2 = vectemp[1];
6009              array[j + stride] = tmp2;
6010              ...
6011          */
6012
6013       unsigned nstores = nunits;
6014       unsigned lnel = 1;
6015       tree ltype = elem_type;
6016       tree lvectype = vectype;
6017       if (slp)
6018         {
6019           if (group_size < nunits
6020               && nunits % group_size == 0)
6021             {
6022               nstores = nunits / group_size;
6023               lnel = group_size;
6024               ltype = build_vector_type (elem_type, group_size);
6025               lvectype = vectype;
6026
6027               /* First check if vec_extract optab doesn't support extraction
6028                  of vector elts directly.  */
6029               machine_mode elmode = TYPE_MODE (elem_type);
6030               machine_mode vmode = mode_for_vector (elmode, group_size);
6031               if (! VECTOR_MODE_P (vmode)
6032                   || (convert_optab_handler (vec_extract_optab,
6033                                              TYPE_MODE (vectype), vmode)
6034                       == CODE_FOR_nothing))
6035                 {
6036                   /* Try to avoid emitting an extract of vector elements
6037                      by performing the extracts using an integer type of the
6038                      same size, extracting from a vector of those and then
6039                      re-interpreting it as the original vector type if
6040                      supported.  */
6041                   unsigned lsize
6042                     = group_size * GET_MODE_BITSIZE (elmode);
6043                   elmode = mode_for_size (lsize, MODE_INT, 0);
6044                   vmode = mode_for_vector (elmode, nunits / group_size);
6045                   /* If we can't construct such a vector fall back to
6046                      element extracts from the original vector type and
6047                      element size stores.  */
6048                   if (VECTOR_MODE_P (vmode)
6049                       && (convert_optab_handler (vec_extract_optab,
6050                                                  vmode, elmode)
6051                           != CODE_FOR_nothing))
6052                     {
6053                       nstores = nunits / group_size;
6054                       lnel = group_size;
6055                       ltype = build_nonstandard_integer_type (lsize, 1);
6056                       lvectype = build_vector_type (ltype, nstores);
6057                     }
6058                   /* Else fall back to vector extraction anyway.
6059                      Fewer stores are more important than avoiding spilling
6060                      of the vector we extract from.  Compared to the
6061                      construction case in vectorizable_load no store-forwarding
6062                      issue exists here for reasonable archs.  */
6063                 }
6064             }
6065           else if (group_size >= nunits
6066                    && group_size % nunits == 0)
6067             {
6068               nstores = 1;
6069               lnel = nunits;
6070               ltype = vectype;
6071               lvectype = vectype;
6072             }
6073           ltype = build_aligned_type (ltype, TYPE_ALIGN (elem_type));
6074           ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
6075         }
6076
6077       ivstep = stride_step;
6078       ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (ivstep), ivstep,
6079                             build_int_cst (TREE_TYPE (ivstep), vf));
6080
6081       standard_iv_increment_position (loop, &incr_gsi, &insert_after);
6082
6083       create_iv (stride_base, ivstep, NULL,
6084                  loop, &incr_gsi, insert_after,
6085                  &offvar, NULL);
6086       incr = gsi_stmt (incr_gsi);
6087       set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
6088
6089       stride_step = force_gimple_operand (stride_step, &stmts, true, NULL_TREE);
6090       if (stmts)
6091         gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
6092
6093       prev_stmt_info = NULL;
6094       alias_off = build_int_cst (ref_type, 0);
6095       next_stmt = first_stmt;
6096       for (g = 0; g < group_size; g++)
6097         {
6098           running_off = offvar;
6099           if (g)
6100             {
6101               tree size = TYPE_SIZE_UNIT (ltype);
6102               tree pos = fold_build2 (MULT_EXPR, sizetype, size_int (g),
6103                                       size);
6104               tree newoff = copy_ssa_name (running_off, NULL);
6105               incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR,
6106                                           running_off, pos);
6107               vect_finish_stmt_generation (stmt, incr, gsi);
6108               running_off = newoff;
6109             }
6110           unsigned int group_el = 0;
6111           unsigned HOST_WIDE_INT
6112             elsz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
6113           for (j = 0; j < ncopies; j++)
6114             {
6115               /* We've set op and dt above, from gimple_assign_rhs1(stmt),
6116                  and first_stmt == stmt.  */
6117               if (j == 0)
6118                 {
6119                   if (slp)
6120                     {
6121                       vect_get_vec_defs (op, NULL_TREE, stmt, &vec_oprnds, NULL,
6122                                          slp_node);
6123                       vec_oprnd = vec_oprnds[0];
6124                     }
6125                   else
6126                     {
6127                       gcc_assert (gimple_assign_single_p (next_stmt));
6128                       op = gimple_assign_rhs1 (next_stmt);
6129                       vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
6130                     }
6131                 }
6132               else
6133                 {
6134                   if (slp)
6135                     vec_oprnd = vec_oprnds[j];
6136                   else
6137                     {
6138                       vect_is_simple_use (vec_oprnd, vinfo, &def_stmt, &dt);
6139                       vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
6140                     }
6141                 }
6142               /* Pun the vector to extract from if necessary.  */
6143               if (lvectype != vectype)
6144                 {
6145                   tree tem = make_ssa_name (lvectype);
6146                   gimple *pun
6147                     = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR,
6148                                                         lvectype, vec_oprnd));
6149                   vect_finish_stmt_generation (stmt, pun, gsi);
6150                   vec_oprnd = tem;
6151                 }
6152               for (i = 0; i < nstores; i++)
6153                 {
6154                   tree newref, newoff;
6155                   gimple *incr, *assign;
6156                   tree size = TYPE_SIZE (ltype);
6157                   /* Extract the i'th component.  */
6158                   tree pos = fold_build2 (MULT_EXPR, bitsizetype,
6159                                           bitsize_int (i), size);
6160                   tree elem = fold_build3 (BIT_FIELD_REF, ltype, vec_oprnd,
6161                                            size, pos);
6162
6163                   elem = force_gimple_operand_gsi (gsi, elem, true,
6164                                                    NULL_TREE, true,
6165                                                    GSI_SAME_STMT);
6166
6167                   tree this_off = build_int_cst (TREE_TYPE (alias_off),
6168                                                  group_el * elsz);
6169                   newref = build2 (MEM_REF, ltype,
6170                                    running_off, this_off);
6171
6172                   /* And store it to *running_off.  */
6173                   assign = gimple_build_assign (newref, elem);
6174                   vect_finish_stmt_generation (stmt, assign, gsi);
6175
6176                   group_el += lnel;
6177                   if (! slp
6178                       || group_el == group_size)
6179                     {
6180                       newoff = copy_ssa_name (running_off, NULL);
6181                       incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR,
6182                                                   running_off, stride_step);
6183                       vect_finish_stmt_generation (stmt, incr, gsi);
6184
6185                       running_off = newoff;
6186                       group_el = 0;
6187                     }
6188                   if (g == group_size - 1
6189                       && !slp)
6190                     {
6191                       if (j == 0 && i == 0)
6192                         STMT_VINFO_VEC_STMT (stmt_info)
6193                             = *vec_stmt = assign;
6194                       else
6195                         STMT_VINFO_RELATED_STMT (prev_stmt_info) = assign;
6196                       prev_stmt_info = vinfo_for_stmt (assign);
6197                     }
6198                 }
6199             }
6200           next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
6201           if (slp)
6202             break;
6203         }
6204
6205       vec_oprnds.release ();
6206       return true;
6207     }
6208
6209   auto_vec<tree> dr_chain (group_size);
6210   oprnds.create (group_size);
6211
6212   alignment_support_scheme = vect_supportable_dr_alignment (first_dr, false);
6213   gcc_assert (alignment_support_scheme);
6214   /* Targets with store-lane instructions must not require explicit
6215      realignment.  */
6216   gcc_assert (memory_access_type != VMAT_LOAD_STORE_LANES
6217               || alignment_support_scheme == dr_aligned
6218               || alignment_support_scheme == dr_unaligned_supported);
6219
6220   if (memory_access_type == VMAT_CONTIGUOUS_DOWN
6221       || memory_access_type == VMAT_CONTIGUOUS_REVERSE)
6222     offset = size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1);
6223
6224   if (memory_access_type == VMAT_LOAD_STORE_LANES)
6225     aggr_type = build_array_type_nelts (elem_type, vec_num * nunits);
6226   else
6227     aggr_type = vectype;
6228
6229   /* In case the vectorization factor (VF) is bigger than the number
6230      of elements that we can fit in a vectype (nunits), we have to generate
6231      more than one vector stmt - i.e - we need to "unroll" the
6232      vector stmt by a factor VF/nunits.  For more details see documentation in
6233      vect_get_vec_def_for_copy_stmt.  */
6234
6235   /* In case of interleaving (non-unit grouped access):
6236
6237         S1:  &base + 2 = x2
6238         S2:  &base = x0
6239         S3:  &base + 1 = x1
6240         S4:  &base + 3 = x3
6241
6242      We create vectorized stores starting from base address (the access of the
6243      first stmt in the chain (S2 in the above example), when the last store stmt
6244      of the chain (S4) is reached:
6245
6246         VS1: &base = vx2
6247         VS2: &base + vec_size*1 = vx0
6248         VS3: &base + vec_size*2 = vx1
6249         VS4: &base + vec_size*3 = vx3
6250
6251      Then permutation statements are generated:
6252
6253         VS5: vx5 = VEC_PERM_EXPR < vx0, vx3, {0, 8, 1, 9, 2, 10, 3, 11} >
6254         VS6: vx6 = VEC_PERM_EXPR < vx0, vx3, {4, 12, 5, 13, 6, 14, 7, 15} >
6255         ...
6256
6257      And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
6258      (the order of the data-refs in the output of vect_permute_store_chain
6259      corresponds to the order of scalar stmts in the interleaving chain - see
6260      the documentation of vect_permute_store_chain()).
6261
6262      In case of both multiple types and interleaving, above vector stores and
6263      permutation stmts are created for every copy.  The result vector stmts are
6264      put in STMT_VINFO_VEC_STMT for the first copy and in the corresponding
6265      STMT_VINFO_RELATED_STMT for the next copies.
6266   */
6267
6268   prev_stmt_info = NULL;
6269   for (j = 0; j < ncopies; j++)
6270     {
6271
6272       if (j == 0)
6273         {
6274           if (slp)
6275             {
6276               /* Get vectorized arguments for SLP_NODE.  */
6277               vect_get_vec_defs (op, NULL_TREE, stmt, &vec_oprnds,
6278                                  NULL, slp_node);
6279
6280               vec_oprnd = vec_oprnds[0];
6281             }
6282           else
6283             {
6284               /* For interleaved stores we collect vectorized defs for all the
6285                  stores in the group in DR_CHAIN and OPRNDS. DR_CHAIN is then
6286                  used as an input to vect_permute_store_chain(), and OPRNDS as
6287                  an input to vect_get_vec_def_for_stmt_copy() for the next copy.
6288
6289                  If the store is not grouped, GROUP_SIZE is 1, and DR_CHAIN and
6290                  OPRNDS are of size 1.  */
6291               next_stmt = first_stmt;
6292               for (i = 0; i < group_size; i++)
6293                 {
6294                   /* Since gaps are not supported for interleaved stores,
6295                      GROUP_SIZE is the exact number of stmts in the chain.
6296                      Therefore, NEXT_STMT can't be NULL_TREE.  In case that
6297                      there is no interleaving, GROUP_SIZE is 1, and only one
6298                      iteration of the loop will be executed.  */
6299                   gcc_assert (next_stmt
6300                               && gimple_assign_single_p (next_stmt));
6301                   op = gimple_assign_rhs1 (next_stmt);
6302
6303                   vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
6304                   dr_chain.quick_push (vec_oprnd);
6305                   oprnds.quick_push (vec_oprnd);
6306                   next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
6307                 }
6308             }
6309
6310           /* We should have catched mismatched types earlier.  */
6311           gcc_assert (useless_type_conversion_p (vectype,
6312                                                  TREE_TYPE (vec_oprnd)));
6313           bool simd_lane_access_p
6314             = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
6315           if (simd_lane_access_p
6316               && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
6317               && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
6318               && integer_zerop (DR_OFFSET (first_dr))
6319               && integer_zerop (DR_INIT (first_dr))
6320               && alias_sets_conflict_p (get_alias_set (aggr_type),
6321                                         get_alias_set (TREE_TYPE (ref_type))))
6322             {
6323               dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
6324               dataref_offset = build_int_cst (ref_type, 0);
6325               inv_p = false;
6326             }
6327           else
6328             dataref_ptr
6329               = vect_create_data_ref_ptr (first_stmt, aggr_type,
6330                                           simd_lane_access_p ? loop : NULL,
6331                                           offset, &dummy, gsi, &ptr_incr,
6332                                           simd_lane_access_p, &inv_p);
6333           gcc_assert (bb_vinfo || !inv_p);
6334         }
6335       else
6336         {
6337           /* For interleaved stores we created vectorized defs for all the
6338              defs stored in OPRNDS in the previous iteration (previous copy).
6339              DR_CHAIN is then used as an input to vect_permute_store_chain(),
6340              and OPRNDS as an input to vect_get_vec_def_for_stmt_copy() for the
6341              next copy.
6342              If the store is not grouped, GROUP_SIZE is 1, and DR_CHAIN and
6343              OPRNDS are of size 1.  */
6344           for (i = 0; i < group_size; i++)
6345             {
6346               op = oprnds[i];
6347               vect_is_simple_use (op, vinfo, &def_stmt, &dt);
6348               vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
6349               dr_chain[i] = vec_oprnd;
6350               oprnds[i] = vec_oprnd;
6351             }
6352           if (dataref_offset)
6353             dataref_offset
6354               = int_const_binop (PLUS_EXPR, dataref_offset,
6355                                  TYPE_SIZE_UNIT (aggr_type));
6356           else
6357             dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
6358                                            TYPE_SIZE_UNIT (aggr_type));
6359         }
6360
6361       if (memory_access_type == VMAT_LOAD_STORE_LANES)
6362         {
6363           tree vec_array;
6364
6365           /* Combine all the vectors into an array.  */
6366           vec_array = create_vector_array (vectype, vec_num);
6367           for (i = 0; i < vec_num; i++)
6368             {
6369               vec_oprnd = dr_chain[i];
6370               write_vector_array (stmt, gsi, vec_oprnd, vec_array, i);
6371             }
6372
6373           /* Emit:
6374                MEM_REF[...all elements...] = STORE_LANES (VEC_ARRAY).  */
6375           data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
6376           gcall *call = gimple_build_call_internal (IFN_STORE_LANES, 1,
6377                                                     vec_array);
6378           gimple_call_set_lhs (call, data_ref);
6379           gimple_call_set_nothrow (call, true);
6380           new_stmt = call;
6381           vect_finish_stmt_generation (stmt, new_stmt, gsi);
6382         }
6383       else
6384         {
6385           new_stmt = NULL;
6386           if (grouped_store)
6387             {
6388               if (j == 0)
6389                 result_chain.create (group_size);
6390               /* Permute.  */
6391               vect_permute_store_chain (dr_chain, group_size, stmt, gsi,
6392                                         &result_chain);
6393             }
6394
6395           next_stmt = first_stmt;
6396           for (i = 0; i < vec_num; i++)
6397             {
6398               unsigned align, misalign;
6399
6400               if (i > 0)
6401                 /* Bump the vector pointer.  */
6402                 dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
6403                                                stmt, NULL_TREE);
6404
6405               if (slp)
6406                 vec_oprnd = vec_oprnds[i];
6407               else if (grouped_store)
6408                 /* For grouped stores vectorized defs are interleaved in
6409                    vect_permute_store_chain().  */
6410                 vec_oprnd = result_chain[i];
6411
6412               data_ref = fold_build2 (MEM_REF, vectype,
6413                                       dataref_ptr,
6414                                       dataref_offset
6415                                       ? dataref_offset
6416                                       : build_int_cst (ref_type, 0));
6417               align = TYPE_ALIGN_UNIT (vectype);
6418               if (aligned_access_p (first_dr))
6419                 misalign = 0;
6420               else if (DR_MISALIGNMENT (first_dr) == -1)
6421                 {
6422                   align = dr_alignment (vect_dr_behavior (first_dr));
6423                   misalign = 0;
6424                   TREE_TYPE (data_ref)
6425                     = build_aligned_type (TREE_TYPE (data_ref),
6426                                           align * BITS_PER_UNIT);
6427                 }
6428               else
6429                 {
6430                   TREE_TYPE (data_ref)
6431                     = build_aligned_type (TREE_TYPE (data_ref),
6432                                           TYPE_ALIGN (elem_type));
6433                   misalign = DR_MISALIGNMENT (first_dr);
6434                 }
6435               if (dataref_offset == NULL_TREE
6436                   && TREE_CODE (dataref_ptr) == SSA_NAME)
6437                 set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
6438                                         misalign);
6439
6440               if (memory_access_type == VMAT_CONTIGUOUS_REVERSE)
6441                 {
6442                   tree perm_mask = perm_mask_for_reverse (vectype);
6443                   tree perm_dest 
6444                     = vect_create_destination_var (gimple_assign_rhs1 (stmt),
6445                                                    vectype);
6446                   tree new_temp = make_ssa_name (perm_dest);
6447
6448                   /* Generate the permute statement.  */
6449                   gimple *perm_stmt 
6450                     = gimple_build_assign (new_temp, VEC_PERM_EXPR, vec_oprnd,
6451                                            vec_oprnd, perm_mask);
6452                   vect_finish_stmt_generation (stmt, perm_stmt, gsi);
6453
6454                   perm_stmt = SSA_NAME_DEF_STMT (new_temp);
6455                   vec_oprnd = new_temp;
6456                 }
6457
6458               /* Arguments are ready.  Create the new vector stmt.  */
6459               new_stmt = gimple_build_assign (data_ref, vec_oprnd);
6460               vect_finish_stmt_generation (stmt, new_stmt, gsi);
6461
6462               if (slp)
6463                 continue;
6464
6465               next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
6466               if (!next_stmt)
6467                 break;
6468             }
6469         }
6470       if (!slp)
6471         {
6472           if (j == 0)
6473             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
6474           else
6475             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
6476           prev_stmt_info = vinfo_for_stmt (new_stmt);
6477         }
6478     }
6479
6480   oprnds.release ();
6481   result_chain.release ();
6482   vec_oprnds.release ();
6483
6484   return true;
6485 }
6486
6487 /* Given a vector type VECTYPE, turns permutation SEL into the equivalent
6488    VECTOR_CST mask.  No checks are made that the target platform supports the
6489    mask, so callers may wish to test can_vec_perm_p separately, or use
6490    vect_gen_perm_mask_checked.  */
6491
6492 tree
6493 vect_gen_perm_mask_any (tree vectype, const unsigned char *sel)
6494 {
6495   tree mask_elt_type, mask_type, mask_vec, *mask_elts;
6496   int i, nunits;
6497
6498   nunits = TYPE_VECTOR_SUBPARTS (vectype);
6499
6500   mask_elt_type = lang_hooks.types.type_for_mode
6501                     (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1);
6502   mask_type = get_vectype_for_scalar_type (mask_elt_type);
6503
6504   mask_elts = XALLOCAVEC (tree, nunits);
6505   for (i = nunits - 1; i >= 0; i--)
6506     mask_elts[i] = build_int_cst (mask_elt_type, sel[i]);
6507   mask_vec = build_vector (mask_type, mask_elts);
6508
6509   return mask_vec;
6510 }
6511
6512 /* Checked version of vect_gen_perm_mask_any.  Asserts can_vec_perm_p,
6513    i.e. that the target supports the pattern _for arbitrary input vectors_.  */
6514
6515 tree
6516 vect_gen_perm_mask_checked (tree vectype, const unsigned char *sel)
6517 {
6518   gcc_assert (can_vec_perm_p (TYPE_MODE (vectype), false, sel));
6519   return vect_gen_perm_mask_any (vectype, sel);
6520 }
6521
6522 /* Given a vector variable X and Y, that was generated for the scalar
6523    STMT, generate instructions to permute the vector elements of X and Y
6524    using permutation mask MASK_VEC, insert them at *GSI and return the
6525    permuted vector variable.  */
6526
6527 static tree
6528 permute_vec_elements (tree x, tree y, tree mask_vec, gimple *stmt,
6529                       gimple_stmt_iterator *gsi)
6530 {
6531   tree vectype = TREE_TYPE (x);
6532   tree perm_dest, data_ref;
6533   gimple *perm_stmt;
6534
6535   perm_dest = vect_create_destination_var (gimple_get_lhs (stmt), vectype);
6536   data_ref = make_ssa_name (perm_dest);
6537
6538   /* Generate the permute statement.  */
6539   perm_stmt = gimple_build_assign (data_ref, VEC_PERM_EXPR, x, y, mask_vec);
6540   vect_finish_stmt_generation (stmt, perm_stmt, gsi);
6541
6542   return data_ref;
6543 }
6544
6545 /* Hoist the definitions of all SSA uses on STMT out of the loop LOOP,
6546    inserting them on the loops preheader edge.  Returns true if we
6547    were successful in doing so (and thus STMT can be moved then),
6548    otherwise returns false.  */
6549
6550 static bool
6551 hoist_defs_of_uses (gimple *stmt, struct loop *loop)
6552 {
6553   ssa_op_iter i;
6554   tree op;
6555   bool any = false;
6556
6557   FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
6558     {
6559       gimple *def_stmt = SSA_NAME_DEF_STMT (op);
6560       if (!gimple_nop_p (def_stmt)
6561           && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
6562         {
6563           /* Make sure we don't need to recurse.  While we could do
6564              so in simple cases when there are more complex use webs
6565              we don't have an easy way to preserve stmt order to fulfil
6566              dependencies within them.  */
6567           tree op2;
6568           ssa_op_iter i2;
6569           if (gimple_code (def_stmt) == GIMPLE_PHI)
6570             return false;
6571           FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE)
6572             {
6573               gimple *def_stmt2 = SSA_NAME_DEF_STMT (op2);
6574               if (!gimple_nop_p (def_stmt2)
6575                   && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2)))
6576                 return false;
6577             }
6578           any = true;
6579         }
6580     }
6581
6582   if (!any)
6583     return true;
6584
6585   FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
6586     {
6587       gimple *def_stmt = SSA_NAME_DEF_STMT (op);
6588       if (!gimple_nop_p (def_stmt)
6589           && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
6590         {
6591           gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
6592           gsi_remove (&gsi, false);
6593           gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt);
6594         }
6595     }
6596
6597   return true;
6598 }
6599
6600 /* vectorizable_load.
6601
6602    Check if STMT reads a non scalar data-ref (array/pointer/structure) that
6603    can be vectorized.
6604    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
6605    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
6606    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
6607
6608 static bool
6609 vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
6610                    slp_tree slp_node, slp_instance slp_node_instance)
6611 {
6612   tree scalar_dest;
6613   tree vec_dest = NULL;
6614   tree data_ref = NULL;
6615   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
6616   stmt_vec_info prev_stmt_info;
6617   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
6618   struct loop *loop = NULL;
6619   struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
6620   bool nested_in_vect_loop = false;
6621   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr = NULL;
6622   tree elem_type;
6623   tree new_temp;
6624   machine_mode mode;
6625   gimple *new_stmt = NULL;
6626   tree dummy;
6627   enum dr_alignment_support alignment_support_scheme;
6628   tree dataref_ptr = NULL_TREE;
6629   tree dataref_offset = NULL_TREE;
6630   gimple *ptr_incr = NULL;
6631   int ncopies;
6632   int i, j, group_size, group_gap_adj;
6633   tree msq = NULL_TREE, lsq;
6634   tree offset = NULL_TREE;
6635   tree byte_offset = NULL_TREE;
6636   tree realignment_token = NULL_TREE;
6637   gphi *phi = NULL;
6638   vec<tree> dr_chain = vNULL;
6639   bool grouped_load = false;
6640   gimple *first_stmt;
6641   gimple *first_stmt_for_drptr = NULL;
6642   bool inv_p;
6643   bool compute_in_loop = false;
6644   struct loop *at_loop;
6645   int vec_num;
6646   bool slp = (slp_node != NULL);
6647   bool slp_perm = false;
6648   enum tree_code code;
6649   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
6650   int vf;
6651   tree aggr_type;
6652   gather_scatter_info gs_info;
6653   vec_info *vinfo = stmt_info->vinfo;
6654   tree ref_type;
6655
6656   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
6657     return false;
6658
6659   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
6660       && ! vec_stmt)
6661     return false;
6662
6663   /* Is vectorizable load? */
6664   if (!is_gimple_assign (stmt))
6665     return false;
6666
6667   scalar_dest = gimple_assign_lhs (stmt);
6668   if (TREE_CODE (scalar_dest) != SSA_NAME)
6669     return false;
6670
6671   code = gimple_assign_rhs_code (stmt);
6672   if (code != ARRAY_REF
6673       && code != BIT_FIELD_REF
6674       && code != INDIRECT_REF
6675       && code != COMPONENT_REF
6676       && code != IMAGPART_EXPR
6677       && code != REALPART_EXPR
6678       && code != MEM_REF
6679       && TREE_CODE_CLASS (code) != tcc_declaration)
6680     return false;
6681
6682   if (!STMT_VINFO_DATA_REF (stmt_info))
6683     return false;
6684
6685   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
6686   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
6687
6688   if (loop_vinfo)
6689     {
6690       loop = LOOP_VINFO_LOOP (loop_vinfo);
6691       nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
6692       vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
6693     }
6694   else
6695     vf = 1;
6696
6697   /* Multiple types in SLP are handled by creating the appropriate number of
6698      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
6699      case of SLP.  */
6700   if (slp)
6701     ncopies = 1;
6702   else
6703     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
6704
6705   gcc_assert (ncopies >= 1);
6706
6707   /* FORNOW. This restriction should be relaxed.  */
6708   if (nested_in_vect_loop && ncopies > 1)
6709     {
6710       if (dump_enabled_p ())
6711         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
6712                          "multiple types in nested loop.\n");
6713       return false;
6714     }
6715
6716   /* Invalidate assumptions made by dependence analysis when vectorization
6717      on the unrolled body effectively re-orders stmts.  */
6718   if (ncopies > 1
6719       && STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0
6720       && ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo)
6721           > STMT_VINFO_MIN_NEG_DIST (stmt_info)))
6722     {
6723       if (dump_enabled_p ())
6724         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
6725                          "cannot perform implicit CSE when unrolling "
6726                          "with negative dependence distance\n");
6727       return false;
6728     }
6729
6730   elem_type = TREE_TYPE (vectype);
6731   mode = TYPE_MODE (vectype);
6732
6733   /* FORNOW. In some cases can vectorize even if data-type not supported
6734     (e.g. - data copies).  */
6735   if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
6736     {
6737       if (dump_enabled_p ())
6738         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
6739                          "Aligned load, but unsupported type.\n");
6740       return false;
6741     }
6742
6743   /* Check if the load is a part of an interleaving chain.  */
6744   if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
6745     {
6746       grouped_load = true;
6747       /* FORNOW */
6748       gcc_assert (!nested_in_vect_loop);
6749       gcc_assert (!STMT_VINFO_GATHER_SCATTER_P (stmt_info));
6750
6751       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
6752       group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
6753
6754       if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
6755         slp_perm = true;
6756
6757       /* Invalidate assumptions made by dependence analysis when vectorization
6758          on the unrolled body effectively re-orders stmts.  */
6759       if (!PURE_SLP_STMT (stmt_info)
6760           && STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0
6761           && ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo)
6762               > STMT_VINFO_MIN_NEG_DIST (stmt_info)))
6763         {
6764           if (dump_enabled_p ())
6765             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
6766                              "cannot perform implicit CSE when performing "
6767                              "group loads with negative dependence distance\n");
6768           return false;
6769         }
6770
6771       /* Similarly when the stmt is a load that is both part of a SLP
6772          instance and a loop vectorized stmt via the same-dr mechanism
6773          we have to give up.  */
6774       if (STMT_VINFO_GROUP_SAME_DR_STMT (stmt_info)
6775           && (STMT_SLP_TYPE (stmt_info)
6776               != STMT_SLP_TYPE (vinfo_for_stmt
6777                                  (STMT_VINFO_GROUP_SAME_DR_STMT (stmt_info)))))
6778         {
6779           if (dump_enabled_p ())
6780             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
6781                              "conflicting SLP types for CSEd load\n");
6782           return false;
6783         }
6784     }
6785
6786   vect_memory_access_type memory_access_type;
6787   if (!get_load_store_type (stmt, vectype, slp, VLS_LOAD, ncopies,
6788                             &memory_access_type, &gs_info))
6789     return false;
6790
6791   if (!vec_stmt) /* transformation not required.  */
6792     {
6793       if (!slp)
6794         STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) = memory_access_type;
6795       STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
6796       /* The SLP costs are calculated during SLP analysis.  */
6797       if (!PURE_SLP_STMT (stmt_info))
6798         vect_model_load_cost (stmt_info, ncopies, memory_access_type,
6799                               NULL, NULL, NULL);
6800       return true;
6801     }
6802
6803   if (!slp)
6804     gcc_assert (memory_access_type
6805                 == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info));
6806
6807   if (dump_enabled_p ())
6808     dump_printf_loc (MSG_NOTE, vect_location,
6809                      "transform load. ncopies = %d\n", ncopies);
6810
6811   /* Transform.  */
6812
6813   ensure_base_align (stmt_info, dr);
6814
6815   if (memory_access_type == VMAT_GATHER_SCATTER)
6816     {
6817       tree vec_oprnd0 = NULL_TREE, op;
6818       tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gs_info.decl));
6819       tree rettype, srctype, ptrtype, idxtype, masktype, scaletype;
6820       tree ptr, mask, var, scale, merge, perm_mask = NULL_TREE, prev_res = NULL_TREE;
6821       edge pe = loop_preheader_edge (loop);
6822       gimple_seq seq;
6823       basic_block new_bb;
6824       enum { NARROW, NONE, WIDEN } modifier;
6825       int gather_off_nunits = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype);
6826
6827       if (nunits == gather_off_nunits)
6828         modifier = NONE;
6829       else if (nunits == gather_off_nunits / 2)
6830         {
6831           unsigned char *sel = XALLOCAVEC (unsigned char, gather_off_nunits);
6832           modifier = WIDEN;
6833
6834           for (i = 0; i < gather_off_nunits; ++i)
6835             sel[i] = i | nunits;
6836
6837           perm_mask = vect_gen_perm_mask_checked (gs_info.offset_vectype, sel);
6838         }
6839       else if (nunits == gather_off_nunits * 2)
6840         {
6841           unsigned char *sel = XALLOCAVEC (unsigned char, nunits);
6842           modifier = NARROW;
6843
6844           for (i = 0; i < nunits; ++i)
6845             sel[i] = i < gather_off_nunits
6846                      ? i : i + nunits - gather_off_nunits;
6847
6848           perm_mask = vect_gen_perm_mask_checked (vectype, sel);
6849           ncopies *= 2;
6850         }
6851       else
6852         gcc_unreachable ();
6853
6854       rettype = TREE_TYPE (TREE_TYPE (gs_info.decl));
6855       srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
6856       ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
6857       idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
6858       masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
6859       scaletype = TREE_VALUE (arglist);
6860       gcc_checking_assert (types_compatible_p (srctype, rettype));
6861
6862       vec_dest = vect_create_destination_var (scalar_dest, vectype);
6863
6864       ptr = fold_convert (ptrtype, gs_info.base);
6865       if (!is_gimple_min_invariant (ptr))
6866         {
6867           ptr = force_gimple_operand (ptr, &seq, true, NULL_TREE);
6868           new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
6869           gcc_assert (!new_bb);
6870         }
6871
6872       /* Currently we support only unconditional gather loads,
6873          so mask should be all ones.  */
6874       if (TREE_CODE (masktype) == INTEGER_TYPE)
6875         mask = build_int_cst (masktype, -1);
6876       else if (TREE_CODE (TREE_TYPE (masktype)) == INTEGER_TYPE)
6877         {
6878           mask = build_int_cst (TREE_TYPE (masktype), -1);
6879           mask = build_vector_from_val (masktype, mask);
6880           mask = vect_init_vector (stmt, mask, masktype, NULL);
6881         }
6882       else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (masktype)))
6883         {
6884           REAL_VALUE_TYPE r;
6885           long tmp[6];
6886           for (j = 0; j < 6; ++j)
6887             tmp[j] = -1;
6888           real_from_target (&r, tmp, TYPE_MODE (TREE_TYPE (masktype)));
6889           mask = build_real (TREE_TYPE (masktype), r);
6890           mask = build_vector_from_val (masktype, mask);
6891           mask = vect_init_vector (stmt, mask, masktype, NULL);
6892         }
6893       else
6894         gcc_unreachable ();
6895
6896       scale = build_int_cst (scaletype, gs_info.scale);
6897
6898       if (TREE_CODE (TREE_TYPE (rettype)) == INTEGER_TYPE)
6899         merge = build_int_cst (TREE_TYPE (rettype), 0);
6900       else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (rettype)))
6901         {
6902           REAL_VALUE_TYPE r;
6903           long tmp[6];
6904           for (j = 0; j < 6; ++j)
6905             tmp[j] = 0;
6906           real_from_target (&r, tmp, TYPE_MODE (TREE_TYPE (rettype)));
6907           merge = build_real (TREE_TYPE (rettype), r);
6908         }
6909       else
6910         gcc_unreachable ();
6911       merge = build_vector_from_val (rettype, merge);
6912       merge = vect_init_vector (stmt, merge, rettype, NULL);
6913
6914       prev_stmt_info = NULL;
6915       for (j = 0; j < ncopies; ++j)
6916         {
6917           if (modifier == WIDEN && (j & 1))
6918             op = permute_vec_elements (vec_oprnd0, vec_oprnd0,
6919                                        perm_mask, stmt, gsi);
6920           else if (j == 0)
6921             op = vec_oprnd0
6922               = vect_get_vec_def_for_operand (gs_info.offset, stmt);
6923           else
6924             op = vec_oprnd0
6925               = vect_get_vec_def_for_stmt_copy (gs_info.offset_dt, vec_oprnd0);
6926
6927           if (!useless_type_conversion_p (idxtype, TREE_TYPE (op)))
6928             {
6929               gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
6930                           == TYPE_VECTOR_SUBPARTS (idxtype));
6931               var = vect_get_new_ssa_name (idxtype, vect_simple_var);
6932               op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
6933               new_stmt
6934                 = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
6935               vect_finish_stmt_generation (stmt, new_stmt, gsi);
6936               op = var;
6937             }
6938
6939           new_stmt
6940             = gimple_build_call (gs_info.decl, 5, merge, ptr, op, mask, scale);
6941
6942           if (!useless_type_conversion_p (vectype, rettype))
6943             {
6944               gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
6945                           == TYPE_VECTOR_SUBPARTS (rettype));
6946               op = vect_get_new_ssa_name (rettype, vect_simple_var);
6947               gimple_call_set_lhs (new_stmt, op);
6948               vect_finish_stmt_generation (stmt, new_stmt, gsi);
6949               var = make_ssa_name (vec_dest);
6950               op = build1 (VIEW_CONVERT_EXPR, vectype, op);
6951               new_stmt
6952                 = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
6953             }
6954           else
6955             {
6956               var = make_ssa_name (vec_dest, new_stmt);
6957               gimple_call_set_lhs (new_stmt, var);
6958             }
6959
6960           vect_finish_stmt_generation (stmt, new_stmt, gsi);
6961
6962           if (modifier == NARROW)
6963             {
6964               if ((j & 1) == 0)
6965                 {
6966                   prev_res = var;
6967                   continue;
6968                 }
6969               var = permute_vec_elements (prev_res, var,
6970                                           perm_mask, stmt, gsi);
6971               new_stmt = SSA_NAME_DEF_STMT (var);
6972             }
6973
6974           if (prev_stmt_info == NULL)
6975             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
6976           else
6977             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
6978           prev_stmt_info = vinfo_for_stmt (new_stmt);
6979         }
6980       return true;
6981     }
6982
6983   if (memory_access_type == VMAT_ELEMENTWISE
6984       || memory_access_type == VMAT_STRIDED_SLP)
6985     {
6986       gimple_stmt_iterator incr_gsi;
6987       bool insert_after;
6988       gimple *incr;
6989       tree offvar;
6990       tree ivstep;
6991       tree running_off;
6992       vec<constructor_elt, va_gc> *v = NULL;
6993       gimple_seq stmts = NULL;
6994       tree stride_base, stride_step, alias_off;
6995
6996       gcc_assert (!nested_in_vect_loop);
6997
6998       if (slp && grouped_load)
6999         {
7000           first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
7001           first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
7002           group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
7003           ref_type = get_group_alias_ptr_type (first_stmt);
7004         }
7005       else
7006         {
7007           first_stmt = stmt;
7008           first_dr = dr;
7009           group_size = 1;
7010           ref_type = reference_alias_ptr_type (DR_REF (first_dr));
7011         }
7012
7013       stride_base
7014         = fold_build_pointer_plus
7015             (DR_BASE_ADDRESS (first_dr),
7016              size_binop (PLUS_EXPR,
7017                          convert_to_ptrofftype (DR_OFFSET (first_dr)),
7018                          convert_to_ptrofftype (DR_INIT (first_dr))));
7019       stride_step = fold_convert (sizetype, DR_STEP (first_dr));
7020
7021       /* For a load with loop-invariant (but other than power-of-2)
7022          stride (i.e. not a grouped access) like so:
7023
7024            for (i = 0; i < n; i += stride)
7025              ... = array[i];
7026
7027          we generate a new induction variable and new accesses to
7028          form a new vector (or vectors, depending on ncopies):
7029
7030            for (j = 0; ; j += VF*stride)
7031              tmp1 = array[j];
7032              tmp2 = array[j + stride];
7033              ...
7034              vectemp = {tmp1, tmp2, ...}
7035          */
7036
7037       ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (stride_step), stride_step,
7038                             build_int_cst (TREE_TYPE (stride_step), vf));
7039
7040       standard_iv_increment_position (loop, &incr_gsi, &insert_after);
7041
7042       create_iv (unshare_expr (stride_base), unshare_expr (ivstep), NULL,
7043                  loop, &incr_gsi, insert_after,
7044                  &offvar, NULL);
7045       incr = gsi_stmt (incr_gsi);
7046       set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
7047
7048       stride_step = force_gimple_operand (unshare_expr (stride_step),
7049                                           &stmts, true, NULL_TREE);
7050       if (stmts)
7051         gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
7052
7053       prev_stmt_info = NULL;
7054       running_off = offvar;
7055       alias_off = build_int_cst (ref_type, 0);
7056       int nloads = nunits;
7057       int lnel = 1;
7058       tree ltype = TREE_TYPE (vectype);
7059       tree lvectype = vectype;
7060       auto_vec<tree> dr_chain;
7061       if (memory_access_type == VMAT_STRIDED_SLP)
7062         {
7063           if (group_size < nunits)
7064             {
7065               /* First check if vec_init optab supports construction from
7066                  vector elts directly.  */
7067               machine_mode elmode = TYPE_MODE (TREE_TYPE (vectype));
7068               machine_mode vmode = mode_for_vector (elmode, group_size);
7069               if (VECTOR_MODE_P (vmode)
7070                   && (convert_optab_handler (vec_init_optab,
7071                                              TYPE_MODE (vectype), vmode)
7072                       != CODE_FOR_nothing))
7073                 {
7074                   nloads = nunits / group_size;
7075                   lnel = group_size;
7076                   ltype = build_vector_type (TREE_TYPE (vectype), group_size);
7077                 }
7078               else
7079                 {
7080                   /* Otherwise avoid emitting a constructor of vector elements
7081                      by performing the loads using an integer type of the same
7082                      size, constructing a vector of those and then
7083                      re-interpreting it as the original vector type.
7084                      This avoids a huge runtime penalty due to the general
7085                      inability to perform store forwarding from smaller stores
7086                      to a larger load.  */
7087                   unsigned lsize
7088                     = group_size * TYPE_PRECISION (TREE_TYPE (vectype));
7089                   elmode = mode_for_size (lsize, MODE_INT, 0);
7090                   vmode = mode_for_vector (elmode, nunits / group_size);
7091                   /* If we can't construct such a vector fall back to
7092                      element loads of the original vector type.  */
7093                   if (VECTOR_MODE_P (vmode)
7094                       && (convert_optab_handler (vec_init_optab, vmode, elmode)
7095                           != CODE_FOR_nothing))
7096                     {
7097                       nloads = nunits / group_size;
7098                       lnel = group_size;
7099                       ltype = build_nonstandard_integer_type (lsize, 1);
7100                       lvectype = build_vector_type (ltype, nloads);
7101                     }
7102                 }
7103             }
7104           else
7105             {
7106               nloads = 1;
7107               lnel = nunits;
7108               ltype = vectype;
7109             }
7110           ltype = build_aligned_type (ltype, TYPE_ALIGN (TREE_TYPE (vectype)));
7111         }
7112       if (slp)
7113         {
7114           /* For SLP permutation support we need to load the whole group,
7115              not only the number of vector stmts the permutation result
7116              fits in.  */
7117           if (slp_perm)
7118             {
7119               ncopies = (group_size * vf + nunits - 1) / nunits;
7120               dr_chain.create (ncopies);
7121             }
7122           else
7123             ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
7124         }
7125       int group_el = 0;
7126       unsigned HOST_WIDE_INT
7127         elsz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
7128       for (j = 0; j < ncopies; j++)
7129         {
7130           if (nloads > 1)
7131             vec_alloc (v, nloads);
7132           for (i = 0; i < nloads; i++)
7133             {
7134               tree this_off = build_int_cst (TREE_TYPE (alias_off),
7135                                              group_el * elsz);
7136               new_stmt = gimple_build_assign (make_ssa_name (ltype),
7137                                               build2 (MEM_REF, ltype,
7138                                                       running_off, this_off));
7139               vect_finish_stmt_generation (stmt, new_stmt, gsi);
7140               if (nloads > 1)
7141                 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7142                                         gimple_assign_lhs (new_stmt));
7143
7144               group_el += lnel;
7145               if (! slp
7146                   || group_el == group_size)
7147                 {
7148                   tree newoff = copy_ssa_name (running_off);
7149                   gimple *incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR,
7150                                                       running_off, stride_step);
7151                   vect_finish_stmt_generation (stmt, incr, gsi);
7152
7153                   running_off = newoff;
7154                   group_el = 0;
7155                 }
7156             }
7157           if (nloads > 1)
7158             {
7159               tree vec_inv = build_constructor (lvectype, v);
7160               new_temp = vect_init_vector (stmt, vec_inv, lvectype, gsi);
7161               new_stmt = SSA_NAME_DEF_STMT (new_temp);
7162               if (lvectype != vectype)
7163                 {
7164                   new_stmt = gimple_build_assign (make_ssa_name (vectype),
7165                                                   VIEW_CONVERT_EXPR,
7166                                                   build1 (VIEW_CONVERT_EXPR,
7167                                                           vectype, new_temp));
7168                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
7169                 }
7170             }
7171
7172           if (slp)
7173             {
7174               if (slp_perm)
7175                 dr_chain.quick_push (gimple_assign_lhs (new_stmt));
7176               else
7177                 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
7178             }
7179           else
7180             {
7181               if (j == 0)
7182                 STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
7183               else
7184                 STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
7185               prev_stmt_info = vinfo_for_stmt (new_stmt);
7186             }
7187         }
7188       if (slp_perm)
7189         {
7190           unsigned n_perms;
7191           vect_transform_slp_perm_load (slp_node, dr_chain, gsi, vf,
7192                                         slp_node_instance, false, &n_perms);
7193         }
7194       return true;
7195     }
7196
7197   if (grouped_load)
7198     {
7199       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
7200       group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
7201       int group_gap = GROUP_GAP (vinfo_for_stmt (first_stmt));
7202       /* For SLP vectorization we directly vectorize a subchain
7203          without permutation.  */
7204       if (slp && ! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
7205         first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
7206       /* For BB vectorization always use the first stmt to base
7207          the data ref pointer on.  */
7208       if (bb_vinfo)
7209         first_stmt_for_drptr = SLP_TREE_SCALAR_STMTS (slp_node)[0];
7210
7211       /* Check if the chain of loads is already vectorized.  */
7212       if (STMT_VINFO_VEC_STMT (vinfo_for_stmt (first_stmt))
7213           /* For SLP we would need to copy over SLP_TREE_VEC_STMTS.
7214              ???  But we can only do so if there is exactly one
7215              as we have no way to get at the rest.  Leave the CSE
7216              opportunity alone.
7217              ???  With the group load eventually participating
7218              in multiple different permutations (having multiple
7219              slp nodes which refer to the same group) the CSE
7220              is even wrong code.  See PR56270.  */
7221           && !slp)
7222         {
7223           *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
7224           return true;
7225         }
7226       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
7227       group_gap_adj = 0;
7228
7229       /* VEC_NUM is the number of vect stmts to be created for this group.  */
7230       if (slp)
7231         {
7232           grouped_load = false;
7233           /* For SLP permutation support we need to load the whole group,
7234              not only the number of vector stmts the permutation result
7235              fits in.  */
7236           if (slp_perm)
7237             {
7238               vec_num = (group_size * vf + nunits - 1) / nunits;
7239               group_gap_adj = vf * group_size - nunits * vec_num;
7240             }
7241           else
7242             {
7243               vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
7244               group_gap_adj = group_gap;
7245             }
7246         }
7247       else
7248         vec_num = group_size;
7249
7250       ref_type = get_group_alias_ptr_type (first_stmt);
7251     }
7252   else
7253     {
7254       first_stmt = stmt;
7255       first_dr = dr;
7256       group_size = vec_num = 1;
7257       group_gap_adj = 0;
7258       ref_type = reference_alias_ptr_type (DR_REF (first_dr));
7259     }
7260
7261   alignment_support_scheme = vect_supportable_dr_alignment (first_dr, false);
7262   gcc_assert (alignment_support_scheme);
7263   /* Targets with load-lane instructions must not require explicit
7264      realignment.  */
7265   gcc_assert (memory_access_type != VMAT_LOAD_STORE_LANES
7266               || alignment_support_scheme == dr_aligned
7267               || alignment_support_scheme == dr_unaligned_supported);
7268
7269   /* In case the vectorization factor (VF) is bigger than the number
7270      of elements that we can fit in a vectype (nunits), we have to generate
7271      more than one vector stmt - i.e - we need to "unroll" the
7272      vector stmt by a factor VF/nunits.  In doing so, we record a pointer
7273      from one copy of the vector stmt to the next, in the field
7274      STMT_VINFO_RELATED_STMT.  This is necessary in order to allow following
7275      stages to find the correct vector defs to be used when vectorizing
7276      stmts that use the defs of the current stmt.  The example below
7277      illustrates the vectorization process when VF=16 and nunits=4 (i.e., we
7278      need to create 4 vectorized stmts):
7279
7280      before vectorization:
7281                                 RELATED_STMT    VEC_STMT
7282         S1:     x = memref      -               -
7283         S2:     z = x + 1       -               -
7284
7285      step 1: vectorize stmt S1:
7286         We first create the vector stmt VS1_0, and, as usual, record a
7287         pointer to it in the STMT_VINFO_VEC_STMT of the scalar stmt S1.
7288         Next, we create the vector stmt VS1_1, and record a pointer to
7289         it in the STMT_VINFO_RELATED_STMT of the vector stmt VS1_0.
7290         Similarly, for VS1_2 and VS1_3.  This is the resulting chain of
7291         stmts and pointers:
7292                                 RELATED_STMT    VEC_STMT
7293         VS1_0:  vx0 = memref0   VS1_1           -
7294         VS1_1:  vx1 = memref1   VS1_2           -
7295         VS1_2:  vx2 = memref2   VS1_3           -
7296         VS1_3:  vx3 = memref3   -               -
7297         S1:     x = load        -               VS1_0
7298         S2:     z = x + 1       -               -
7299
7300      See in documentation in vect_get_vec_def_for_stmt_copy for how the
7301      information we recorded in RELATED_STMT field is used to vectorize
7302      stmt S2.  */
7303
7304   /* In case of interleaving (non-unit grouped access):
7305
7306      S1:  x2 = &base + 2
7307      S2:  x0 = &base
7308      S3:  x1 = &base + 1
7309      S4:  x3 = &base + 3
7310
7311      Vectorized loads are created in the order of memory accesses
7312      starting from the access of the first stmt of the chain:
7313
7314      VS1: vx0 = &base
7315      VS2: vx1 = &base + vec_size*1
7316      VS3: vx3 = &base + vec_size*2
7317      VS4: vx4 = &base + vec_size*3
7318
7319      Then permutation statements are generated:
7320
7321      VS5: vx5 = VEC_PERM_EXPR < vx0, vx1, { 0, 2, ..., i*2 } >
7322      VS6: vx6 = VEC_PERM_EXPR < vx0, vx1, { 1, 3, ..., i*2+1 } >
7323        ...
7324
7325      And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
7326      (the order of the data-refs in the output of vect_permute_load_chain
7327      corresponds to the order of scalar stmts in the interleaving chain - see
7328      the documentation of vect_permute_load_chain()).
7329      The generation of permutation stmts and recording them in
7330      STMT_VINFO_VEC_STMT is done in vect_transform_grouped_load().
7331
7332      In case of both multiple types and interleaving, the vector loads and
7333      permutation stmts above are created for every copy.  The result vector
7334      stmts are put in STMT_VINFO_VEC_STMT for the first copy and in the
7335      corresponding STMT_VINFO_RELATED_STMT for the next copies.  */
7336
7337   /* If the data reference is aligned (dr_aligned) or potentially unaligned
7338      on a target that supports unaligned accesses (dr_unaligned_supported)
7339      we generate the following code:
7340          p = initial_addr;
7341          indx = 0;
7342          loop {
7343            p = p + indx * vectype_size;
7344            vec_dest = *(p);
7345            indx = indx + 1;
7346          }
7347
7348      Otherwise, the data reference is potentially unaligned on a target that
7349      does not support unaligned accesses (dr_explicit_realign_optimized) -
7350      then generate the following code, in which the data in each iteration is
7351      obtained by two vector loads, one from the previous iteration, and one
7352      from the current iteration:
7353          p1 = initial_addr;
7354          msq_init = *(floor(p1))
7355          p2 = initial_addr + VS - 1;
7356          realignment_token = call target_builtin;
7357          indx = 0;
7358          loop {
7359            p2 = p2 + indx * vectype_size
7360            lsq = *(floor(p2))
7361            vec_dest = realign_load (msq, lsq, realignment_token)
7362            indx = indx + 1;
7363            msq = lsq;
7364          }   */
7365
7366   /* If the misalignment remains the same throughout the execution of the
7367      loop, we can create the init_addr and permutation mask at the loop
7368      preheader.  Otherwise, it needs to be created inside the loop.
7369      This can only occur when vectorizing memory accesses in the inner-loop
7370      nested within an outer-loop that is being vectorized.  */
7371
7372   if (nested_in_vect_loop
7373       && (DR_STEP_ALIGNMENT (dr) % GET_MODE_SIZE (TYPE_MODE (vectype))) != 0)
7374     {
7375       gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized);
7376       compute_in_loop = true;
7377     }
7378
7379   if ((alignment_support_scheme == dr_explicit_realign_optimized
7380        || alignment_support_scheme == dr_explicit_realign)
7381       && !compute_in_loop)
7382     {
7383       msq = vect_setup_realignment (first_stmt, gsi, &realignment_token,
7384                                     alignment_support_scheme, NULL_TREE,
7385                                     &at_loop);
7386       if (alignment_support_scheme == dr_explicit_realign_optimized)
7387         {
7388           phi = as_a <gphi *> (SSA_NAME_DEF_STMT (msq));
7389           byte_offset = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (vectype),
7390                                     size_one_node);
7391         }
7392     }
7393   else
7394     at_loop = loop;
7395
7396   if (memory_access_type == VMAT_CONTIGUOUS_REVERSE)
7397     offset = size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1);
7398
7399   if (memory_access_type == VMAT_LOAD_STORE_LANES)
7400     aggr_type = build_array_type_nelts (elem_type, vec_num * nunits);
7401   else
7402     aggr_type = vectype;
7403
7404   prev_stmt_info = NULL;
7405   int group_elt = 0;
7406   for (j = 0; j < ncopies; j++)
7407     {
7408       /* 1. Create the vector or array pointer update chain.  */
7409       if (j == 0)
7410         {
7411           bool simd_lane_access_p
7412             = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
7413           if (simd_lane_access_p
7414               && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
7415               && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
7416               && integer_zerop (DR_OFFSET (first_dr))
7417               && integer_zerop (DR_INIT (first_dr))
7418               && alias_sets_conflict_p (get_alias_set (aggr_type),
7419                                         get_alias_set (TREE_TYPE (ref_type)))
7420               && (alignment_support_scheme == dr_aligned
7421                   || alignment_support_scheme == dr_unaligned_supported))
7422             {
7423               dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
7424               dataref_offset = build_int_cst (ref_type, 0);
7425               inv_p = false;
7426             }
7427           else if (first_stmt_for_drptr
7428                    && first_stmt != first_stmt_for_drptr)
7429             {
7430               dataref_ptr
7431                 = vect_create_data_ref_ptr (first_stmt_for_drptr, aggr_type,
7432                                             at_loop, offset, &dummy, gsi,
7433                                             &ptr_incr, simd_lane_access_p,
7434                                             &inv_p, byte_offset);
7435               /* Adjust the pointer by the difference to first_stmt.  */
7436               data_reference_p ptrdr
7437                 = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt_for_drptr));
7438               tree diff = fold_convert (sizetype,
7439                                         size_binop (MINUS_EXPR,
7440                                                     DR_INIT (first_dr),
7441                                                     DR_INIT (ptrdr)));
7442               dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
7443                                              stmt, diff);
7444             }
7445           else
7446             dataref_ptr
7447               = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,
7448                                           offset, &dummy, gsi, &ptr_incr,
7449                                           simd_lane_access_p, &inv_p,
7450                                           byte_offset);
7451         }
7452       else if (dataref_offset)
7453         dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset,
7454                                           TYPE_SIZE_UNIT (aggr_type));
7455       else
7456         dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
7457                                        TYPE_SIZE_UNIT (aggr_type));
7458
7459       if (grouped_load || slp_perm)
7460         dr_chain.create (vec_num);
7461
7462       if (memory_access_type == VMAT_LOAD_STORE_LANES)
7463         {
7464           tree vec_array;
7465
7466           vec_array = create_vector_array (vectype, vec_num);
7467
7468           /* Emit:
7469                VEC_ARRAY = LOAD_LANES (MEM_REF[...all elements...]).  */
7470           data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
7471           gcall *call = gimple_build_call_internal (IFN_LOAD_LANES, 1,
7472                                                     data_ref);
7473           gimple_call_set_lhs (call, vec_array);
7474           gimple_call_set_nothrow (call, true);
7475           new_stmt = call;
7476           vect_finish_stmt_generation (stmt, new_stmt, gsi);
7477
7478           /* Extract each vector into an SSA_NAME.  */
7479           for (i = 0; i < vec_num; i++)
7480             {
7481               new_temp = read_vector_array (stmt, gsi, scalar_dest,
7482                                             vec_array, i);
7483               dr_chain.quick_push (new_temp);
7484             }
7485
7486           /* Record the mapping between SSA_NAMEs and statements.  */
7487           vect_record_grouped_load_vectors (stmt, dr_chain);
7488         }
7489       else
7490         {
7491           for (i = 0; i < vec_num; i++)
7492             {
7493               if (i > 0)
7494                 dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
7495                                                stmt, NULL_TREE);
7496
7497               /* 2. Create the vector-load in the loop.  */
7498               switch (alignment_support_scheme)
7499                 {
7500                 case dr_aligned:
7501                 case dr_unaligned_supported:
7502                   {
7503                     unsigned int align, misalign;
7504
7505                     data_ref
7506                       = fold_build2 (MEM_REF, vectype, dataref_ptr,
7507                                      dataref_offset
7508                                      ? dataref_offset
7509                                      : build_int_cst (ref_type, 0));
7510                     align = TYPE_ALIGN_UNIT (vectype);
7511                     if (alignment_support_scheme == dr_aligned)
7512                       {
7513                         gcc_assert (aligned_access_p (first_dr));
7514                         misalign = 0;
7515                       }
7516                     else if (DR_MISALIGNMENT (first_dr) == -1)
7517                       {
7518                         align = dr_alignment (vect_dr_behavior (first_dr));
7519                         misalign = 0;
7520                         TREE_TYPE (data_ref)
7521                           = build_aligned_type (TREE_TYPE (data_ref),
7522                                                 align * BITS_PER_UNIT);
7523                       }
7524                     else
7525                       {
7526                         TREE_TYPE (data_ref)
7527                           = build_aligned_type (TREE_TYPE (data_ref),
7528                                                 TYPE_ALIGN (elem_type));
7529                         misalign = DR_MISALIGNMENT (first_dr);
7530                       }
7531                     if (dataref_offset == NULL_TREE
7532                         && TREE_CODE (dataref_ptr) == SSA_NAME)
7533                       set_ptr_info_alignment (get_ptr_info (dataref_ptr),
7534                                               align, misalign);
7535                     break;
7536                   }
7537                 case dr_explicit_realign:
7538                   {
7539                     tree ptr, bump;
7540
7541                     tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype));
7542
7543                     if (compute_in_loop)
7544                       msq = vect_setup_realignment (first_stmt, gsi,
7545                                                     &realignment_token,
7546                                                     dr_explicit_realign,
7547                                                     dataref_ptr, NULL);
7548
7549                     if (TREE_CODE (dataref_ptr) == SSA_NAME)
7550                       ptr = copy_ssa_name (dataref_ptr);
7551                     else
7552                       ptr = make_ssa_name (TREE_TYPE (dataref_ptr));
7553                     new_stmt = gimple_build_assign
7554                                  (ptr, BIT_AND_EXPR, dataref_ptr,
7555                                   build_int_cst
7556                                   (TREE_TYPE (dataref_ptr),
7557                                    -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
7558                     vect_finish_stmt_generation (stmt, new_stmt, gsi);
7559                     data_ref
7560                       = build2 (MEM_REF, vectype, ptr,
7561                                 build_int_cst (ref_type, 0));
7562                     vec_dest = vect_create_destination_var (scalar_dest,
7563                                                             vectype);
7564                     new_stmt = gimple_build_assign (vec_dest, data_ref);
7565                     new_temp = make_ssa_name (vec_dest, new_stmt);
7566                     gimple_assign_set_lhs (new_stmt, new_temp);
7567                     gimple_set_vdef (new_stmt, gimple_vdef (stmt));
7568                     gimple_set_vuse (new_stmt, gimple_vuse (stmt));
7569                     vect_finish_stmt_generation (stmt, new_stmt, gsi);
7570                     msq = new_temp;
7571
7572                     bump = size_binop (MULT_EXPR, vs,
7573                                        TYPE_SIZE_UNIT (elem_type));
7574                     bump = size_binop (MINUS_EXPR, bump, size_one_node);
7575                     ptr = bump_vector_ptr (dataref_ptr, NULL, gsi, stmt, bump);
7576                     new_stmt = gimple_build_assign
7577                                  (NULL_TREE, BIT_AND_EXPR, ptr,
7578                                   build_int_cst
7579                                   (TREE_TYPE (ptr),
7580                                    -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
7581                     ptr = copy_ssa_name (ptr, new_stmt);
7582                     gimple_assign_set_lhs (new_stmt, ptr);
7583                     vect_finish_stmt_generation (stmt, new_stmt, gsi);
7584                     data_ref
7585                       = build2 (MEM_REF, vectype, ptr,
7586                                 build_int_cst (ref_type, 0));
7587                     break;
7588                   }
7589                 case dr_explicit_realign_optimized:
7590                   if (TREE_CODE (dataref_ptr) == SSA_NAME)
7591                     new_temp = copy_ssa_name (dataref_ptr);
7592                   else
7593                     new_temp = make_ssa_name (TREE_TYPE (dataref_ptr));
7594                   new_stmt = gimple_build_assign
7595                                (new_temp, BIT_AND_EXPR, dataref_ptr,
7596                                 build_int_cst
7597                                   (TREE_TYPE (dataref_ptr),
7598                                    -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
7599                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
7600                   data_ref
7601                     = build2 (MEM_REF, vectype, new_temp,
7602                               build_int_cst (ref_type, 0));
7603                   break;
7604                 default:
7605                   gcc_unreachable ();
7606                 }
7607               vec_dest = vect_create_destination_var (scalar_dest, vectype);
7608               new_stmt = gimple_build_assign (vec_dest, data_ref);
7609               new_temp = make_ssa_name (vec_dest, new_stmt);
7610               gimple_assign_set_lhs (new_stmt, new_temp);
7611               vect_finish_stmt_generation (stmt, new_stmt, gsi);
7612
7613               /* 3. Handle explicit realignment if necessary/supported.
7614                  Create in loop:
7615                    vec_dest = realign_load (msq, lsq, realignment_token)  */
7616               if (alignment_support_scheme == dr_explicit_realign_optimized
7617                   || alignment_support_scheme == dr_explicit_realign)
7618                 {
7619                   lsq = gimple_assign_lhs (new_stmt);
7620                   if (!realignment_token)
7621                     realignment_token = dataref_ptr;
7622                   vec_dest = vect_create_destination_var (scalar_dest, vectype);
7623                   new_stmt = gimple_build_assign (vec_dest, REALIGN_LOAD_EXPR,
7624                                                   msq, lsq, realignment_token);
7625                   new_temp = make_ssa_name (vec_dest, new_stmt);
7626                   gimple_assign_set_lhs (new_stmt, new_temp);
7627                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
7628
7629                   if (alignment_support_scheme == dr_explicit_realign_optimized)
7630                     {
7631                       gcc_assert (phi);
7632                       if (i == vec_num - 1 && j == ncopies - 1)
7633                         add_phi_arg (phi, lsq,
7634                                      loop_latch_edge (containing_loop),
7635                                      UNKNOWN_LOCATION);
7636                       msq = lsq;
7637                     }
7638                 }
7639
7640               /* 4. Handle invariant-load.  */
7641               if (inv_p && !bb_vinfo)
7642                 {
7643                   gcc_assert (!grouped_load);
7644                   /* If we have versioned for aliasing or the loop doesn't
7645                      have any data dependencies that would preclude this,
7646                      then we are sure this is a loop invariant load and
7647                      thus we can insert it on the preheader edge.  */
7648                   if (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
7649                       && !nested_in_vect_loop
7650                       && hoist_defs_of_uses (stmt, loop))
7651                     {
7652                       if (dump_enabled_p ())
7653                         {
7654                           dump_printf_loc (MSG_NOTE, vect_location,
7655                                            "hoisting out of the vectorized "
7656                                            "loop: ");
7657                           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
7658                         }
7659                       tree tem = copy_ssa_name (scalar_dest);
7660                       gsi_insert_on_edge_immediate
7661                         (loop_preheader_edge (loop),
7662                          gimple_build_assign (tem,
7663                                               unshare_expr
7664                                                 (gimple_assign_rhs1 (stmt))));
7665                       new_temp = vect_init_vector (stmt, tem, vectype, NULL);
7666                       new_stmt = SSA_NAME_DEF_STMT (new_temp);
7667                       set_vinfo_for_stmt (new_stmt,
7668                                           new_stmt_vec_info (new_stmt, vinfo));
7669                     }
7670                   else
7671                     {
7672                       gimple_stmt_iterator gsi2 = *gsi;
7673                       gsi_next (&gsi2);
7674                       new_temp = vect_init_vector (stmt, scalar_dest,
7675                                                    vectype, &gsi2);
7676                       new_stmt = SSA_NAME_DEF_STMT (new_temp);
7677                     }
7678                 }
7679
7680               if (memory_access_type == VMAT_CONTIGUOUS_REVERSE)
7681                 {
7682                   tree perm_mask = perm_mask_for_reverse (vectype);
7683                   new_temp = permute_vec_elements (new_temp, new_temp,
7684                                                    perm_mask, stmt, gsi);
7685                   new_stmt = SSA_NAME_DEF_STMT (new_temp);
7686                 }
7687
7688               /* Collect vector loads and later create their permutation in
7689                  vect_transform_grouped_load ().  */
7690               if (grouped_load || slp_perm)
7691                 dr_chain.quick_push (new_temp);
7692
7693               /* Store vector loads in the corresponding SLP_NODE.  */
7694               if (slp && !slp_perm)
7695                 SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
7696
7697               /* With SLP permutation we load the gaps as well, without
7698                  we need to skip the gaps after we manage to fully load
7699                  all elements.  group_gap_adj is GROUP_SIZE here.  */
7700               group_elt += nunits;
7701               if (group_gap_adj != 0 && ! slp_perm
7702                   && group_elt == group_size - group_gap_adj)
7703                 {
7704                   bool ovf;
7705                   tree bump
7706                     = wide_int_to_tree (sizetype,
7707                                         wi::smul (TYPE_SIZE_UNIT (elem_type),
7708                                                   group_gap_adj, &ovf));
7709                   dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
7710                                                  stmt, bump);
7711                   group_elt = 0;
7712                 }
7713             }
7714           /* Bump the vector pointer to account for a gap or for excess
7715              elements loaded for a permuted SLP load.  */
7716           if (group_gap_adj != 0 && slp_perm)
7717             {
7718               bool ovf;
7719               tree bump
7720                 = wide_int_to_tree (sizetype,
7721                                     wi::smul (TYPE_SIZE_UNIT (elem_type),
7722                                               group_gap_adj, &ovf));
7723               dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
7724                                              stmt, bump);
7725             }
7726         }
7727
7728       if (slp && !slp_perm)
7729         continue;
7730
7731       if (slp_perm)
7732         {
7733           unsigned n_perms;
7734           if (!vect_transform_slp_perm_load (slp_node, dr_chain, gsi, vf,
7735                                              slp_node_instance, false,
7736                                              &n_perms))
7737             {
7738               dr_chain.release ();
7739               return false;
7740             }
7741         }
7742       else
7743         {
7744           if (grouped_load)
7745             {
7746               if (memory_access_type != VMAT_LOAD_STORE_LANES)
7747                 vect_transform_grouped_load (stmt, dr_chain, group_size, gsi);
7748               *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
7749             }
7750           else
7751             {
7752               if (j == 0)
7753                 STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
7754               else
7755                 STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
7756               prev_stmt_info = vinfo_for_stmt (new_stmt);
7757             }
7758         }
7759       dr_chain.release ();
7760     }
7761
7762   return true;
7763 }
7764
7765 /* Function vect_is_simple_cond.
7766
7767    Input:
7768    LOOP - the loop that is being vectorized.
7769    COND - Condition that is checked for simple use.
7770
7771    Output:
7772    *COMP_VECTYPE - the vector type for the comparison.
7773    *DTS - The def types for the arguments of the comparison
7774
7775    Returns whether a COND can be vectorized.  Checks whether
7776    condition operands are supportable using vec_is_simple_use.  */
7777
7778 static bool
7779 vect_is_simple_cond (tree cond, vec_info *vinfo,
7780                      tree *comp_vectype, enum vect_def_type *dts)
7781 {
7782   tree lhs, rhs;
7783   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
7784
7785   /* Mask case.  */
7786   if (TREE_CODE (cond) == SSA_NAME
7787       && VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (cond)))
7788     {
7789       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (cond);
7790       if (!vect_is_simple_use (cond, vinfo, &lhs_def_stmt,
7791                                &dts[0], comp_vectype)
7792           || !*comp_vectype
7793           || !VECTOR_BOOLEAN_TYPE_P (*comp_vectype))
7794         return false;
7795       return true;
7796     }
7797
7798   if (!COMPARISON_CLASS_P (cond))
7799     return false;
7800
7801   lhs = TREE_OPERAND (cond, 0);
7802   rhs = TREE_OPERAND (cond, 1);
7803
7804   if (TREE_CODE (lhs) == SSA_NAME)
7805     {
7806       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
7807       if (!vect_is_simple_use (lhs, vinfo, &lhs_def_stmt, &dts[0], &vectype1))
7808         return false;
7809     }
7810   else if (TREE_CODE (lhs) == INTEGER_CST || TREE_CODE (lhs) == REAL_CST
7811            || TREE_CODE (lhs) == FIXED_CST)
7812     dts[0] = vect_constant_def;
7813   else
7814     return false;
7815
7816   if (TREE_CODE (rhs) == SSA_NAME)
7817     {
7818       gimple *rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
7819       if (!vect_is_simple_use (rhs, vinfo, &rhs_def_stmt, &dts[1], &vectype2))
7820         return false;
7821     }
7822   else if (TREE_CODE (rhs) == INTEGER_CST || TREE_CODE (rhs) == REAL_CST
7823            || TREE_CODE (rhs) == FIXED_CST)
7824     dts[1] = vect_constant_def;
7825   else
7826     return false;
7827
7828   if (vectype1 && vectype2
7829       && TYPE_VECTOR_SUBPARTS (vectype1) != TYPE_VECTOR_SUBPARTS (vectype2))
7830     return false;
7831
7832   *comp_vectype = vectype1 ? vectype1 : vectype2;
7833   return true;
7834 }
7835
7836 /* vectorizable_condition.
7837
7838    Check if STMT is conditional modify expression that can be vectorized.
7839    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
7840    stmt using VEC_COND_EXPR  to replace it, put it in VEC_STMT, and insert it
7841    at GSI.
7842
7843    When STMT is vectorized as nested cycle, REDUC_DEF is the vector variable
7844    to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1, and in
7845    else clause if it is 2).
7846
7847    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
7848
7849 bool
7850 vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
7851                         gimple **vec_stmt, tree reduc_def, int reduc_index,
7852                         slp_tree slp_node)
7853 {
7854   tree scalar_dest = NULL_TREE;
7855   tree vec_dest = NULL_TREE;
7856   tree cond_expr, cond_expr0 = NULL_TREE, cond_expr1 = NULL_TREE;
7857   tree then_clause, else_clause;
7858   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
7859   tree comp_vectype = NULL_TREE;
7860   tree vec_cond_lhs = NULL_TREE, vec_cond_rhs = NULL_TREE;
7861   tree vec_then_clause = NULL_TREE, vec_else_clause = NULL_TREE;
7862   tree vec_compare;
7863   tree new_temp;
7864   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
7865   enum vect_def_type dts[4]
7866     = {vect_unknown_def_type, vect_unknown_def_type,
7867        vect_unknown_def_type, vect_unknown_def_type};
7868   int ndts = 4;
7869   int ncopies;
7870   enum tree_code code, cond_code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
7871   stmt_vec_info prev_stmt_info = NULL;
7872   int i, j;
7873   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
7874   vec<tree> vec_oprnds0 = vNULL;
7875   vec<tree> vec_oprnds1 = vNULL;
7876   vec<tree> vec_oprnds2 = vNULL;
7877   vec<tree> vec_oprnds3 = vNULL;
7878   tree vec_cmp_type;
7879   bool masked = false;
7880
7881   if (reduc_index && STMT_SLP_TYPE (stmt_info))
7882     return false;
7883
7884   if (STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info) == TREE_CODE_REDUCTION)
7885     {
7886       if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
7887         return false;
7888
7889       if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
7890           && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
7891                && reduc_def))
7892         return false;
7893
7894       /* FORNOW: not yet supported.  */
7895       if (STMT_VINFO_LIVE_P (stmt_info))
7896         {
7897           if (dump_enabled_p ())
7898             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
7899                              "value used after loop.\n");
7900           return false;
7901         }
7902     }
7903
7904   /* Is vectorizable conditional operation?  */
7905   if (!is_gimple_assign (stmt))
7906     return false;
7907
7908   code = gimple_assign_rhs_code (stmt);
7909
7910   if (code != COND_EXPR)
7911     return false;
7912
7913   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
7914   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
7915   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
7916
7917   if (slp_node)
7918     ncopies = 1;
7919   else
7920     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
7921
7922   gcc_assert (ncopies >= 1);
7923   if (reduc_index && ncopies > 1)
7924     return false; /* FORNOW */
7925
7926   cond_expr = gimple_assign_rhs1 (stmt);
7927   then_clause = gimple_assign_rhs2 (stmt);
7928   else_clause = gimple_assign_rhs3 (stmt);
7929
7930   if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
7931                             &comp_vectype, &dts[0])
7932       || !comp_vectype)
7933     return false;
7934
7935   gimple *def_stmt;
7936   if (!vect_is_simple_use (then_clause, stmt_info->vinfo, &def_stmt, &dts[2],
7937                            &vectype1))
7938     return false;
7939   if (!vect_is_simple_use (else_clause, stmt_info->vinfo, &def_stmt, &dts[3],
7940                            &vectype2))
7941     return false;
7942
7943   if (vectype1 && !useless_type_conversion_p (vectype, vectype1))
7944     return false;
7945
7946   if (vectype2 && !useless_type_conversion_p (vectype, vectype2))
7947     return false;
7948
7949   masked = !COMPARISON_CLASS_P (cond_expr);
7950   vec_cmp_type = build_same_sized_truth_vector_type (comp_vectype);
7951
7952   if (vec_cmp_type == NULL_TREE)
7953     return false;
7954
7955   cond_code = TREE_CODE (cond_expr);
7956   if (!masked)
7957     {
7958       cond_expr0 = TREE_OPERAND (cond_expr, 0);
7959       cond_expr1 = TREE_OPERAND (cond_expr, 1);
7960     }
7961
7962   if (!masked && VECTOR_BOOLEAN_TYPE_P (comp_vectype))
7963     {
7964       /* Boolean values may have another representation in vectors
7965          and therefore we prefer bit operations over comparison for
7966          them (which also works for scalar masks).  We store opcodes
7967          to use in bitop1 and bitop2.  Statement is vectorized as
7968          BITOP2 (rhs1 BITOP1 rhs2) or rhs1 BITOP2 (BITOP1 rhs2)
7969          depending on bitop1 and bitop2 arity.  */
7970       switch (cond_code)
7971         {
7972         case GT_EXPR:
7973           bitop1 = BIT_NOT_EXPR;
7974           bitop2 = BIT_AND_EXPR;
7975           break;
7976         case GE_EXPR:
7977           bitop1 = BIT_NOT_EXPR;
7978           bitop2 = BIT_IOR_EXPR;
7979           break;
7980         case LT_EXPR:
7981           bitop1 = BIT_NOT_EXPR;
7982           bitop2 = BIT_AND_EXPR;
7983           std::swap (cond_expr0, cond_expr1);
7984           break;
7985         case LE_EXPR:
7986           bitop1 = BIT_NOT_EXPR;
7987           bitop2 = BIT_IOR_EXPR;
7988           std::swap (cond_expr0, cond_expr1);
7989           break;
7990         case NE_EXPR:
7991           bitop1 = BIT_XOR_EXPR;
7992           break;
7993         case EQ_EXPR:
7994           bitop1 = BIT_XOR_EXPR;
7995           bitop2 = BIT_NOT_EXPR;
7996           break;
7997         default:
7998           return false;
7999         }
8000       cond_code = SSA_NAME;
8001     }
8002
8003   if (!vec_stmt)
8004     {
8005       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
8006       if (bitop1 != NOP_EXPR)
8007         {
8008           machine_mode mode = TYPE_MODE (comp_vectype);
8009           optab optab;
8010
8011           optab = optab_for_tree_code (bitop1, comp_vectype, optab_default);
8012           if (!optab || optab_handler (optab, mode) == CODE_FOR_nothing)
8013             return false;
8014
8015           if (bitop2 != NOP_EXPR)
8016             {
8017               optab = optab_for_tree_code (bitop2, comp_vectype,
8018                                            optab_default);
8019               if (!optab || optab_handler (optab, mode) == CODE_FOR_nothing)
8020                 return false;
8021             }
8022         }
8023       if (expand_vec_cond_expr_p (vectype, comp_vectype,
8024                                      cond_code))
8025         {
8026           vect_model_simple_cost (stmt_info, ncopies, dts, ndts, NULL, NULL);
8027           return true;
8028         }
8029       return false;
8030     }
8031
8032   /* Transform.  */
8033
8034   if (!slp_node)
8035     {
8036       vec_oprnds0.create (1);
8037       vec_oprnds1.create (1);
8038       vec_oprnds2.create (1);
8039       vec_oprnds3.create (1);
8040     }
8041
8042   /* Handle def.  */
8043   scalar_dest = gimple_assign_lhs (stmt);
8044   vec_dest = vect_create_destination_var (scalar_dest, vectype);
8045
8046   /* Handle cond expr.  */
8047   for (j = 0; j < ncopies; j++)
8048     {
8049       gassign *new_stmt = NULL;
8050       if (j == 0)
8051         {
8052           if (slp_node)
8053             {
8054               auto_vec<tree, 4> ops;
8055               auto_vec<vec<tree>, 4> vec_defs;
8056
8057               if (masked)
8058                 ops.safe_push (cond_expr);
8059               else
8060                 {
8061                   ops.safe_push (cond_expr0);
8062                   ops.safe_push (cond_expr1);
8063                 }
8064               ops.safe_push (then_clause);
8065               ops.safe_push (else_clause);
8066               vect_get_slp_defs (ops, slp_node, &vec_defs);
8067               vec_oprnds3 = vec_defs.pop ();
8068               vec_oprnds2 = vec_defs.pop ();
8069               if (!masked)
8070                 vec_oprnds1 = vec_defs.pop ();
8071               vec_oprnds0 = vec_defs.pop ();
8072             }
8073           else
8074             {
8075               gimple *gtemp;
8076               if (masked)
8077                 {
8078                   vec_cond_lhs
8079                     = vect_get_vec_def_for_operand (cond_expr, stmt,
8080                                                     comp_vectype);
8081                   vect_is_simple_use (cond_expr, stmt_info->vinfo,
8082                                       &gtemp, &dts[0]);
8083                 }
8084               else
8085                 {
8086                   vec_cond_lhs
8087                     = vect_get_vec_def_for_operand (cond_expr0,
8088                                                     stmt, comp_vectype);
8089                   vect_is_simple_use (cond_expr0, loop_vinfo, &gtemp, &dts[0]);
8090
8091                   vec_cond_rhs
8092                     = vect_get_vec_def_for_operand (cond_expr1,
8093                                                     stmt, comp_vectype);
8094                   vect_is_simple_use (cond_expr1, loop_vinfo, &gtemp, &dts[1]);
8095                 }
8096               if (reduc_index == 1)
8097                 vec_then_clause = reduc_def;
8098               else
8099                 {
8100                   vec_then_clause = vect_get_vec_def_for_operand (then_clause,
8101                                                                   stmt);
8102                   vect_is_simple_use (then_clause, loop_vinfo,
8103                                       &gtemp, &dts[2]);
8104                 }
8105               if (reduc_index == 2)
8106                 vec_else_clause = reduc_def;
8107               else
8108                 {
8109                   vec_else_clause = vect_get_vec_def_for_operand (else_clause,
8110                                                                   stmt);
8111                   vect_is_simple_use (else_clause, loop_vinfo, &gtemp, &dts[3]);
8112                 }
8113             }
8114         }
8115       else
8116         {
8117           vec_cond_lhs
8118             = vect_get_vec_def_for_stmt_copy (dts[0],
8119                                               vec_oprnds0.pop ());
8120           if (!masked)
8121             vec_cond_rhs
8122               = vect_get_vec_def_for_stmt_copy (dts[1],
8123                                                 vec_oprnds1.pop ());
8124
8125           vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2],
8126                                                             vec_oprnds2.pop ());
8127           vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3],
8128                                                             vec_oprnds3.pop ());
8129         }
8130
8131       if (!slp_node)
8132         {
8133           vec_oprnds0.quick_push (vec_cond_lhs);
8134           if (!masked)
8135             vec_oprnds1.quick_push (vec_cond_rhs);
8136           vec_oprnds2.quick_push (vec_then_clause);
8137           vec_oprnds3.quick_push (vec_else_clause);
8138         }
8139
8140       /* Arguments are ready.  Create the new vector stmt.  */
8141       FOR_EACH_VEC_ELT (vec_oprnds0, i, vec_cond_lhs)
8142         {
8143           vec_then_clause = vec_oprnds2[i];
8144           vec_else_clause = vec_oprnds3[i];
8145
8146           if (masked)
8147             vec_compare = vec_cond_lhs;
8148           else
8149             {
8150               vec_cond_rhs = vec_oprnds1[i];
8151               if (bitop1 == NOP_EXPR)
8152                 vec_compare = build2 (cond_code, vec_cmp_type,
8153                                       vec_cond_lhs, vec_cond_rhs);
8154               else
8155                 {
8156                   new_temp = make_ssa_name (vec_cmp_type);
8157                   if (bitop1 == BIT_NOT_EXPR)
8158                     new_stmt = gimple_build_assign (new_temp, bitop1,
8159                                                     vec_cond_rhs);
8160                   else
8161                     new_stmt
8162                       = gimple_build_assign (new_temp, bitop1, vec_cond_lhs,
8163                                              vec_cond_rhs);
8164                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
8165                   if (bitop2 == NOP_EXPR)
8166                     vec_compare = new_temp;
8167                   else if (bitop2 == BIT_NOT_EXPR)
8168                     {
8169                       /* Instead of doing ~x ? y : z do x ? z : y.  */
8170                       vec_compare = new_temp;
8171                       std::swap (vec_then_clause, vec_else_clause);
8172                     }
8173                   else
8174                     {
8175                       vec_compare = make_ssa_name (vec_cmp_type);
8176                       new_stmt
8177                         = gimple_build_assign (vec_compare, bitop2,
8178                                                vec_cond_lhs, new_temp);
8179                       vect_finish_stmt_generation (stmt, new_stmt, gsi);
8180                     }
8181                 }
8182             }
8183           new_temp = make_ssa_name (vec_dest);
8184           new_stmt = gimple_build_assign (new_temp, VEC_COND_EXPR,
8185                                           vec_compare, vec_then_clause,
8186                                           vec_else_clause);
8187           vect_finish_stmt_generation (stmt, new_stmt, gsi);
8188           if (slp_node)
8189             SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
8190         }
8191
8192         if (slp_node)
8193           continue;
8194
8195         if (j == 0)
8196           STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
8197         else
8198           STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
8199
8200         prev_stmt_info = vinfo_for_stmt (new_stmt);
8201     }
8202
8203   vec_oprnds0.release ();
8204   vec_oprnds1.release ();
8205   vec_oprnds2.release ();
8206   vec_oprnds3.release ();
8207
8208   return true;
8209 }
8210
8211 /* vectorizable_comparison.
8212
8213    Check if STMT is comparison expression that can be vectorized.
8214    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
8215    comparison, put it in VEC_STMT, and insert it at GSI.
8216
8217    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
8218
8219 static bool
8220 vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
8221                          gimple **vec_stmt, tree reduc_def,
8222                          slp_tree slp_node)
8223 {
8224   tree lhs, rhs1, rhs2;
8225   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
8226   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
8227   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
8228   tree vec_rhs1 = NULL_TREE, vec_rhs2 = NULL_TREE;
8229   tree new_temp;
8230   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
8231   enum vect_def_type dts[2] = {vect_unknown_def_type, vect_unknown_def_type};
8232   int ndts = 2;
8233   unsigned nunits;
8234   int ncopies;
8235   enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
8236   stmt_vec_info prev_stmt_info = NULL;
8237   int i, j;
8238   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
8239   vec<tree> vec_oprnds0 = vNULL;
8240   vec<tree> vec_oprnds1 = vNULL;
8241   gimple *def_stmt;
8242   tree mask_type;
8243   tree mask;
8244
8245   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
8246     return false;
8247
8248   if (!vectype || !VECTOR_BOOLEAN_TYPE_P (vectype))
8249     return false;
8250
8251   mask_type = vectype;
8252   nunits = TYPE_VECTOR_SUBPARTS (vectype);
8253
8254   if (slp_node)
8255     ncopies = 1;
8256   else
8257     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
8258
8259   gcc_assert (ncopies >= 1);
8260   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
8261       && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
8262            && reduc_def))
8263     return false;
8264
8265   if (STMT_VINFO_LIVE_P (stmt_info))
8266     {
8267       if (dump_enabled_p ())
8268         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
8269                          "value used after loop.\n");
8270       return false;
8271     }
8272
8273   if (!is_gimple_assign (stmt))
8274     return false;
8275
8276   code = gimple_assign_rhs_code (stmt);
8277
8278   if (TREE_CODE_CLASS (code) != tcc_comparison)
8279     return false;
8280
8281   rhs1 = gimple_assign_rhs1 (stmt);
8282   rhs2 = gimple_assign_rhs2 (stmt);
8283
8284   if (!vect_is_simple_use (rhs1, stmt_info->vinfo, &def_stmt,
8285                            &dts[0], &vectype1))
8286     return false;
8287
8288   if (!vect_is_simple_use (rhs2, stmt_info->vinfo, &def_stmt,
8289                            &dts[1], &vectype2))
8290     return false;
8291
8292   if (vectype1 && vectype2
8293       && TYPE_VECTOR_SUBPARTS (vectype1) != TYPE_VECTOR_SUBPARTS (vectype2))
8294     return false;
8295
8296   vectype = vectype1 ? vectype1 : vectype2;
8297
8298   /* Invariant comparison.  */
8299   if (!vectype)
8300     {
8301       vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1));
8302       if (TYPE_VECTOR_SUBPARTS (vectype) != nunits)
8303         return false;
8304     }
8305   else if (nunits != TYPE_VECTOR_SUBPARTS (vectype))
8306     return false;
8307
8308   /* Can't compare mask and non-mask types.  */
8309   if (vectype1 && vectype2
8310       && (VECTOR_BOOLEAN_TYPE_P (vectype1) ^ VECTOR_BOOLEAN_TYPE_P (vectype2)))
8311     return false;
8312
8313   /* Boolean values may have another representation in vectors
8314      and therefore we prefer bit operations over comparison for
8315      them (which also works for scalar masks).  We store opcodes
8316      to use in bitop1 and bitop2.  Statement is vectorized as
8317        BITOP2 (rhs1 BITOP1 rhs2) or
8318        rhs1 BITOP2 (BITOP1 rhs2)
8319      depending on bitop1 and bitop2 arity.  */
8320   if (VECTOR_BOOLEAN_TYPE_P (vectype))
8321     {
8322       if (code == GT_EXPR)
8323         {
8324           bitop1 = BIT_NOT_EXPR;
8325           bitop2 = BIT_AND_EXPR;
8326         }
8327       else if (code == GE_EXPR)
8328         {
8329           bitop1 = BIT_NOT_EXPR;
8330           bitop2 = BIT_IOR_EXPR;
8331         }
8332       else if (code == LT_EXPR)
8333         {
8334           bitop1 = BIT_NOT_EXPR;
8335           bitop2 = BIT_AND_EXPR;
8336           std::swap (rhs1, rhs2);
8337           std::swap (dts[0], dts[1]);
8338         }
8339       else if (code == LE_EXPR)
8340         {
8341           bitop1 = BIT_NOT_EXPR;
8342           bitop2 = BIT_IOR_EXPR;
8343           std::swap (rhs1, rhs2);
8344           std::swap (dts[0], dts[1]);
8345         }
8346       else
8347         {
8348           bitop1 = BIT_XOR_EXPR;
8349           if (code == EQ_EXPR)
8350             bitop2 = BIT_NOT_EXPR;
8351         }
8352     }
8353
8354   if (!vec_stmt)
8355     {
8356       STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
8357       vect_model_simple_cost (stmt_info, ncopies * (1 + (bitop2 != NOP_EXPR)),
8358                               dts, ndts, NULL, NULL);
8359       if (bitop1 == NOP_EXPR)
8360         return expand_vec_cmp_expr_p (vectype, mask_type, code);
8361       else
8362         {
8363           machine_mode mode = TYPE_MODE (vectype);
8364           optab optab;
8365
8366           optab = optab_for_tree_code (bitop1, vectype, optab_default);
8367           if (!optab || optab_handler (optab, mode) == CODE_FOR_nothing)
8368             return false;
8369
8370           if (bitop2 != NOP_EXPR)
8371             {
8372               optab = optab_for_tree_code (bitop2, vectype, optab_default);
8373               if (!optab || optab_handler (optab, mode) == CODE_FOR_nothing)
8374                 return false;
8375             }
8376           return true;
8377         }
8378     }
8379
8380   /* Transform.  */
8381   if (!slp_node)
8382     {
8383       vec_oprnds0.create (1);
8384       vec_oprnds1.create (1);
8385     }
8386
8387   /* Handle def.  */
8388   lhs = gimple_assign_lhs (stmt);
8389   mask = vect_create_destination_var (lhs, mask_type);
8390
8391   /* Handle cmp expr.  */
8392   for (j = 0; j < ncopies; j++)
8393     {
8394       gassign *new_stmt = NULL;
8395       if (j == 0)
8396         {
8397           if (slp_node)
8398             {
8399               auto_vec<tree, 2> ops;
8400               auto_vec<vec<tree>, 2> vec_defs;
8401
8402               ops.safe_push (rhs1);
8403               ops.safe_push (rhs2);
8404               vect_get_slp_defs (ops, slp_node, &vec_defs);
8405               vec_oprnds1 = vec_defs.pop ();
8406               vec_oprnds0 = vec_defs.pop ();
8407             }
8408           else
8409             {
8410               vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, vectype);
8411               vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, vectype);
8412             }
8413         }
8414       else
8415         {
8416           vec_rhs1 = vect_get_vec_def_for_stmt_copy (dts[0],
8417                                                      vec_oprnds0.pop ());
8418           vec_rhs2 = vect_get_vec_def_for_stmt_copy (dts[1],
8419                                                      vec_oprnds1.pop ());
8420         }
8421
8422       if (!slp_node)
8423         {
8424           vec_oprnds0.quick_push (vec_rhs1);
8425           vec_oprnds1.quick_push (vec_rhs2);
8426         }
8427
8428       /* Arguments are ready.  Create the new vector stmt.  */
8429       FOR_EACH_VEC_ELT (vec_oprnds0, i, vec_rhs1)
8430         {
8431           vec_rhs2 = vec_oprnds1[i];
8432
8433           new_temp = make_ssa_name (mask);
8434           if (bitop1 == NOP_EXPR)
8435             {
8436               new_stmt = gimple_build_assign (new_temp, code,
8437                                               vec_rhs1, vec_rhs2);
8438               vect_finish_stmt_generation (stmt, new_stmt, gsi);
8439             }
8440           else
8441             {
8442               if (bitop1 == BIT_NOT_EXPR)
8443                 new_stmt = gimple_build_assign (new_temp, bitop1, vec_rhs2);
8444               else
8445                 new_stmt = gimple_build_assign (new_temp, bitop1, vec_rhs1,
8446                                                 vec_rhs2);
8447               vect_finish_stmt_generation (stmt, new_stmt, gsi);
8448               if (bitop2 != NOP_EXPR)
8449                 {
8450                   tree res = make_ssa_name (mask);
8451                   if (bitop2 == BIT_NOT_EXPR)
8452                     new_stmt = gimple_build_assign (res, bitop2, new_temp);
8453                   else
8454                     new_stmt = gimple_build_assign (res, bitop2, vec_rhs1,
8455                                                     new_temp);
8456                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
8457                 }
8458             }
8459           if (slp_node)
8460             SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
8461         }
8462
8463       if (slp_node)
8464         continue;
8465
8466       if (j == 0)
8467         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
8468       else
8469         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
8470
8471       prev_stmt_info = vinfo_for_stmt (new_stmt);
8472     }
8473
8474   vec_oprnds0.release ();
8475   vec_oprnds1.release ();
8476
8477   return true;
8478 }
8479
8480 /* Make sure the statement is vectorizable.  */
8481
8482 bool
8483 vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
8484                    slp_instance node_instance)
8485 {
8486   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
8487   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
8488   enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info);
8489   bool ok;
8490   gimple *pattern_stmt;
8491   gimple_seq pattern_def_seq;
8492
8493   if (dump_enabled_p ())
8494     {
8495       dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: ");
8496       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
8497     }
8498
8499   if (gimple_has_volatile_ops (stmt))
8500     {
8501       if (dump_enabled_p ())
8502         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
8503                          "not vectorized: stmt has volatile operands\n");
8504
8505       return false;
8506     }
8507
8508   /* Skip stmts that do not need to be vectorized. In loops this is expected
8509      to include:
8510      - the COND_EXPR which is the loop exit condition
8511      - any LABEL_EXPRs in the loop
8512      - computations that are used only for array indexing or loop control.
8513      In basic blocks we only analyze statements that are a part of some SLP
8514      instance, therefore, all the statements are relevant.
8515
8516      Pattern statement needs to be analyzed instead of the original statement
8517      if the original statement is not relevant.  Otherwise, we analyze both
8518      statements.  In basic blocks we are called from some SLP instance
8519      traversal, don't analyze pattern stmts instead, the pattern stmts
8520      already will be part of SLP instance.  */
8521
8522   pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
8523   if (!STMT_VINFO_RELEVANT_P (stmt_info)
8524       && !STMT_VINFO_LIVE_P (stmt_info))
8525     {
8526       if (STMT_VINFO_IN_PATTERN_P (stmt_info)
8527           && pattern_stmt
8528           && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
8529               || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
8530         {
8531           /* Analyze PATTERN_STMT instead of the original stmt.  */
8532           stmt = pattern_stmt;
8533           stmt_info = vinfo_for_stmt (pattern_stmt);
8534           if (dump_enabled_p ())
8535             {
8536               dump_printf_loc (MSG_NOTE, vect_location,
8537                                "==> examining pattern statement: ");
8538               dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
8539             }
8540         }
8541       else
8542         {
8543           if (dump_enabled_p ())
8544             dump_printf_loc (MSG_NOTE, vect_location, "irrelevant.\n");
8545
8546           return true;
8547         }
8548     }
8549   else if (STMT_VINFO_IN_PATTERN_P (stmt_info)
8550            && node == NULL
8551            && pattern_stmt
8552            && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
8553                || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
8554     {
8555       /* Analyze PATTERN_STMT too.  */
8556       if (dump_enabled_p ())
8557         {
8558           dump_printf_loc (MSG_NOTE, vect_location,
8559                            "==> examining pattern statement: ");
8560           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
8561         }
8562
8563       if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node,
8564                               node_instance))
8565         return false;
8566    }
8567
8568   if (is_pattern_stmt_p (stmt_info)
8569       && node == NULL
8570       && (pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info)))
8571     {
8572       gimple_stmt_iterator si;
8573
8574       for (si = gsi_start (pattern_def_seq); !gsi_end_p (si); gsi_next (&si))
8575         {
8576           gimple *pattern_def_stmt = gsi_stmt (si);
8577           if (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_def_stmt))
8578               || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_def_stmt)))
8579             {
8580               /* Analyze def stmt of STMT if it's a pattern stmt.  */
8581               if (dump_enabled_p ())
8582                 {
8583                   dump_printf_loc (MSG_NOTE, vect_location,
8584                                    "==> examining pattern def statement: ");
8585                   dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_def_stmt, 0);
8586                 }
8587
8588               if (!vect_analyze_stmt (pattern_def_stmt,
8589                                       need_to_vectorize, node, node_instance))
8590                 return false;
8591             }
8592         }
8593     }
8594
8595   switch (STMT_VINFO_DEF_TYPE (stmt_info))
8596     {
8597       case vect_internal_def:
8598         break;
8599
8600       case vect_reduction_def:
8601       case vect_nested_cycle:
8602          gcc_assert (!bb_vinfo
8603                      && (relevance == vect_used_in_outer
8604                          || relevance == vect_used_in_outer_by_reduction
8605                          || relevance == vect_used_by_reduction
8606                          || relevance == vect_unused_in_scope
8607                          || relevance == vect_used_only_live));
8608          break;
8609
8610       case vect_induction_def:
8611         gcc_assert (!bb_vinfo);
8612         break;
8613
8614       case vect_constant_def:
8615       case vect_external_def:
8616       case vect_unknown_def_type:
8617       default:
8618         gcc_unreachable ();
8619     }
8620
8621   if (STMT_VINFO_RELEVANT_P (stmt_info))
8622     {
8623       gcc_assert (!VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))));
8624       gcc_assert (STMT_VINFO_VECTYPE (stmt_info)
8625                   || (is_gimple_call (stmt)
8626                       && gimple_call_lhs (stmt) == NULL_TREE));
8627       *need_to_vectorize = true;
8628     }
8629
8630   if (PURE_SLP_STMT (stmt_info) && !node)
8631     {
8632       dump_printf_loc (MSG_NOTE, vect_location,
8633                        "handled only by SLP analysis\n");
8634       return true;
8635     }
8636
8637   ok = true;
8638   if (!bb_vinfo
8639       && (STMT_VINFO_RELEVANT_P (stmt_info)
8640           || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
8641     ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node)
8642           || vectorizable_conversion (stmt, NULL, NULL, node)
8643           || vectorizable_shift (stmt, NULL, NULL, node)
8644           || vectorizable_operation (stmt, NULL, NULL, node)
8645           || vectorizable_assignment (stmt, NULL, NULL, node)
8646           || vectorizable_load (stmt, NULL, NULL, node, NULL)
8647           || vectorizable_call (stmt, NULL, NULL, node)
8648           || vectorizable_store (stmt, NULL, NULL, node)
8649           || vectorizable_reduction (stmt, NULL, NULL, node, node_instance)
8650           || vectorizable_induction (stmt, NULL, NULL, node)
8651           || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)
8652           || vectorizable_comparison (stmt, NULL, NULL, NULL, node));
8653   else
8654     {
8655       if (bb_vinfo)
8656         ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node)
8657               || vectorizable_conversion (stmt, NULL, NULL, node)
8658               || vectorizable_shift (stmt, NULL, NULL, node)
8659               || vectorizable_operation (stmt, NULL, NULL, node)
8660               || vectorizable_assignment (stmt, NULL, NULL, node)
8661               || vectorizable_load (stmt, NULL, NULL, node, NULL)
8662               || vectorizable_call (stmt, NULL, NULL, node)
8663               || vectorizable_store (stmt, NULL, NULL, node)
8664               || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)
8665               || vectorizable_comparison (stmt, NULL, NULL, NULL, node));
8666     }
8667
8668   if (!ok)
8669     {
8670       if (dump_enabled_p ())
8671         {
8672           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
8673                            "not vectorized: relevant stmt not ");
8674           dump_printf (MSG_MISSED_OPTIMIZATION, "supported: ");
8675           dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
8676         }
8677
8678       return false;
8679     }
8680
8681   if (bb_vinfo)
8682     return true;
8683
8684   /* Stmts that are (also) "live" (i.e. - that are used out of the loop)
8685       need extra handling, except for vectorizable reductions.  */
8686   if (STMT_VINFO_LIVE_P (stmt_info)
8687       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
8688     ok = vectorizable_live_operation (stmt, NULL, NULL, -1, NULL);
8689
8690   if (!ok)
8691     {
8692       if (dump_enabled_p ())
8693         {
8694           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
8695                            "not vectorized: live stmt not ");
8696           dump_printf (MSG_MISSED_OPTIMIZATION,  "supported: ");
8697           dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
8698         }
8699
8700        return false;
8701     }
8702
8703   return true;
8704 }
8705
8706
8707 /* Function vect_transform_stmt.
8708
8709    Create a vectorized stmt to replace STMT, and insert it at BSI.  */
8710
8711 bool
8712 vect_transform_stmt (gimple *stmt, gimple_stmt_iterator *gsi,
8713                      bool *grouped_store, slp_tree slp_node,
8714                      slp_instance slp_node_instance)
8715 {
8716   bool is_store = false;
8717   gimple *vec_stmt = NULL;
8718   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
8719   bool done;
8720
8721   gcc_assert (slp_node || !PURE_SLP_STMT (stmt_info));
8722   gimple *old_vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
8723
8724   switch (STMT_VINFO_TYPE (stmt_info))
8725     {
8726     case type_demotion_vec_info_type:
8727     case type_promotion_vec_info_type:
8728     case type_conversion_vec_info_type:
8729       done = vectorizable_conversion (stmt, gsi, &vec_stmt, slp_node);
8730       gcc_assert (done);
8731       break;
8732
8733     case induc_vec_info_type:
8734       done = vectorizable_induction (stmt, gsi, &vec_stmt, slp_node);
8735       gcc_assert (done);
8736       break;
8737
8738     case shift_vec_info_type:
8739       done = vectorizable_shift (stmt, gsi, &vec_stmt, slp_node);
8740       gcc_assert (done);
8741       break;
8742
8743     case op_vec_info_type:
8744       done = vectorizable_operation (stmt, gsi, &vec_stmt, slp_node);
8745       gcc_assert (done);
8746       break;
8747
8748     case assignment_vec_info_type:
8749       done = vectorizable_assignment (stmt, gsi, &vec_stmt, slp_node);
8750       gcc_assert (done);
8751       break;
8752
8753     case load_vec_info_type:
8754       done = vectorizable_load (stmt, gsi, &vec_stmt, slp_node,
8755                                 slp_node_instance);
8756       gcc_assert (done);
8757       break;
8758
8759     case store_vec_info_type:
8760       done = vectorizable_store (stmt, gsi, &vec_stmt, slp_node);
8761       gcc_assert (done);
8762       if (STMT_VINFO_GROUPED_ACCESS (stmt_info) && !slp_node)
8763         {
8764           /* In case of interleaving, the whole chain is vectorized when the
8765              last store in the chain is reached.  Store stmts before the last
8766              one are skipped, and there vec_stmt_info shouldn't be freed
8767              meanwhile.  */
8768           *grouped_store = true;
8769           if (STMT_VINFO_VEC_STMT (stmt_info))
8770             is_store = true;
8771           }
8772       else
8773         is_store = true;
8774       break;
8775
8776     case condition_vec_info_type:
8777       done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0, slp_node);
8778       gcc_assert (done);
8779       break;
8780
8781     case comparison_vec_info_type:
8782       done = vectorizable_comparison (stmt, gsi, &vec_stmt, NULL, slp_node);
8783       gcc_assert (done);
8784       break;
8785
8786     case call_vec_info_type:
8787       done = vectorizable_call (stmt, gsi, &vec_stmt, slp_node);
8788       stmt = gsi_stmt (*gsi);
8789       if (gimple_call_internal_p (stmt, IFN_MASK_STORE))
8790         is_store = true;
8791       break;
8792
8793     case call_simd_clone_vec_info_type:
8794       done = vectorizable_simd_clone_call (stmt, gsi, &vec_stmt, slp_node);
8795       stmt = gsi_stmt (*gsi);
8796       break;
8797
8798     case reduc_vec_info_type:
8799       done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node,
8800                                      slp_node_instance);
8801       gcc_assert (done);
8802       break;
8803
8804     default:
8805       if (!STMT_VINFO_LIVE_P (stmt_info))
8806         {
8807           if (dump_enabled_p ())
8808             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
8809                              "stmt not supported.\n");
8810           gcc_unreachable ();
8811         }
8812     }
8813
8814   /* Verify SLP vectorization doesn't mess with STMT_VINFO_VEC_STMT.
8815      This would break hybrid SLP vectorization.  */
8816   if (slp_node)
8817     gcc_assert (!vec_stmt
8818                 && STMT_VINFO_VEC_STMT (stmt_info) == old_vec_stmt);
8819
8820   /* Handle inner-loop stmts whose DEF is used in the loop-nest that
8821      is being vectorized, but outside the immediately enclosing loop.  */
8822   if (vec_stmt
8823       && STMT_VINFO_LOOP_VINFO (stmt_info)
8824       && nested_in_vect_loop_p (LOOP_VINFO_LOOP (
8825                                 STMT_VINFO_LOOP_VINFO (stmt_info)), stmt)
8826       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type
8827       && (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_outer
8828           || STMT_VINFO_RELEVANT (stmt_info) ==
8829                                            vect_used_in_outer_by_reduction))
8830     {
8831       struct loop *innerloop = LOOP_VINFO_LOOP (
8832                                 STMT_VINFO_LOOP_VINFO (stmt_info))->inner;
8833       imm_use_iterator imm_iter;
8834       use_operand_p use_p;
8835       tree scalar_dest;
8836       gimple *exit_phi;
8837
8838       if (dump_enabled_p ())
8839         dump_printf_loc (MSG_NOTE, vect_location,
8840                          "Record the vdef for outer-loop vectorization.\n");
8841
8842       /* Find the relevant loop-exit phi-node, and reord the vec_stmt there
8843         (to be used when vectorizing outer-loop stmts that use the DEF of
8844         STMT).  */
8845       if (gimple_code (stmt) == GIMPLE_PHI)
8846         scalar_dest = PHI_RESULT (stmt);
8847       else
8848         scalar_dest = gimple_assign_lhs (stmt);
8849
8850       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
8851        {
8852          if (!flow_bb_inside_loop_p (innerloop, gimple_bb (USE_STMT (use_p))))
8853            {
8854              exit_phi = USE_STMT (use_p);
8855              STMT_VINFO_VEC_STMT (vinfo_for_stmt (exit_phi)) = vec_stmt;
8856            }
8857        }
8858     }
8859
8860   /* Handle stmts whose DEF is used outside the loop-nest that is
8861      being vectorized.  */
8862   if (slp_node)
8863     {
8864       gimple *slp_stmt;
8865       int i;
8866       if (STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
8867         FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, slp_stmt)
8868           {
8869             stmt_vec_info slp_stmt_info = vinfo_for_stmt (slp_stmt);
8870             if (STMT_VINFO_LIVE_P (slp_stmt_info))
8871               {
8872                 done = vectorizable_live_operation (slp_stmt, gsi, slp_node, i,
8873                                                     &vec_stmt);
8874                 gcc_assert (done);
8875               }
8876           }
8877     }
8878   else if (STMT_VINFO_LIVE_P (stmt_info)
8879            && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
8880     {
8881       done = vectorizable_live_operation (stmt, gsi, slp_node, -1, &vec_stmt);
8882       gcc_assert (done);
8883     }
8884
8885   if (vec_stmt)
8886     STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
8887
8888   return is_store;
8889 }
8890
8891
8892 /* Remove a group of stores (for SLP or interleaving), free their
8893    stmt_vec_info.  */
8894
8895 void
8896 vect_remove_stores (gimple *first_stmt)
8897 {
8898   gimple *next = first_stmt;
8899   gimple *tmp;
8900   gimple_stmt_iterator next_si;
8901
8902   while (next)
8903     {
8904       stmt_vec_info stmt_info = vinfo_for_stmt (next);
8905
8906       tmp = GROUP_NEXT_ELEMENT (stmt_info);
8907       if (is_pattern_stmt_p (stmt_info))
8908         next = STMT_VINFO_RELATED_STMT (stmt_info);
8909       /* Free the attached stmt_vec_info and remove the stmt.  */
8910       next_si = gsi_for_stmt (next);
8911       unlink_stmt_vdef (next);
8912       gsi_remove (&next_si, true);
8913       release_defs (next);
8914       free_stmt_vec_info (next);
8915       next = tmp;
8916     }
8917 }
8918
8919
8920 /* Function new_stmt_vec_info.
8921
8922    Create and initialize a new stmt_vec_info struct for STMT.  */
8923
8924 stmt_vec_info
8925 new_stmt_vec_info (gimple *stmt, vec_info *vinfo)
8926 {
8927   stmt_vec_info res;
8928   res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
8929
8930   STMT_VINFO_TYPE (res) = undef_vec_info_type;
8931   STMT_VINFO_STMT (res) = stmt;
8932   res->vinfo = vinfo;
8933   STMT_VINFO_RELEVANT (res) = vect_unused_in_scope;
8934   STMT_VINFO_LIVE_P (res) = false;
8935   STMT_VINFO_VECTYPE (res) = NULL;
8936   STMT_VINFO_VEC_STMT (res) = NULL;
8937   STMT_VINFO_VECTORIZABLE (res) = true;
8938   STMT_VINFO_IN_PATTERN_P (res) = false;
8939   STMT_VINFO_RELATED_STMT (res) = NULL;
8940   STMT_VINFO_PATTERN_DEF_SEQ (res) = NULL;
8941   STMT_VINFO_DATA_REF (res) = NULL;
8942   STMT_VINFO_VEC_REDUCTION_TYPE (res) = TREE_CODE_REDUCTION;
8943   STMT_VINFO_VEC_CONST_COND_REDUC_CODE (res) = ERROR_MARK;
8944
8945   if (gimple_code (stmt) == GIMPLE_PHI
8946       && is_loop_header_bb_p (gimple_bb (stmt)))
8947     STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
8948   else
8949     STMT_VINFO_DEF_TYPE (res) = vect_internal_def;
8950
8951   STMT_VINFO_SAME_ALIGN_REFS (res).create (0);
8952   STMT_SLP_TYPE (res) = loop_vect;
8953   STMT_VINFO_NUM_SLP_USES (res) = 0;
8954
8955   GROUP_FIRST_ELEMENT (res) = NULL;
8956   GROUP_NEXT_ELEMENT (res) = NULL;
8957   GROUP_SIZE (res) = 0;
8958   GROUP_STORE_COUNT (res) = 0;
8959   GROUP_GAP (res) = 0;
8960   GROUP_SAME_DR_STMT (res) = NULL;
8961
8962   return res;
8963 }
8964
8965
8966 /* Create a hash table for stmt_vec_info. */
8967
8968 void
8969 init_stmt_vec_info_vec (void)
8970 {
8971   gcc_assert (!stmt_vec_info_vec.exists ());
8972   stmt_vec_info_vec.create (50);
8973 }
8974
8975
8976 /* Free hash table for stmt_vec_info. */
8977
8978 void
8979 free_stmt_vec_info_vec (void)
8980 {
8981   unsigned int i;
8982   stmt_vec_info info;
8983   FOR_EACH_VEC_ELT (stmt_vec_info_vec, i, info)
8984     if (info != NULL)
8985       free_stmt_vec_info (STMT_VINFO_STMT (info));
8986   gcc_assert (stmt_vec_info_vec.exists ());
8987   stmt_vec_info_vec.release ();
8988 }
8989
8990
8991 /* Free stmt vectorization related info.  */
8992
8993 void
8994 free_stmt_vec_info (gimple *stmt)
8995 {
8996   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
8997
8998   if (!stmt_info)
8999     return;
9000
9001   /* Check if this statement has a related "pattern stmt"
9002      (introduced by the vectorizer during the pattern recognition
9003      pass).  Free pattern's stmt_vec_info and def stmt's stmt_vec_info
9004      too.  */
9005   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
9006     {
9007       stmt_vec_info patt_info
9008         = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info));
9009       if (patt_info)
9010         {
9011           gimple_seq seq = STMT_VINFO_PATTERN_DEF_SEQ (patt_info);
9012           gimple *patt_stmt = STMT_VINFO_STMT (patt_info);
9013           gimple_set_bb (patt_stmt, NULL);
9014           tree lhs = gimple_get_lhs (patt_stmt);
9015           if (lhs && TREE_CODE (lhs) == SSA_NAME)
9016             release_ssa_name (lhs);
9017           if (seq)
9018             {
9019               gimple_stmt_iterator si;
9020               for (si = gsi_start (seq); !gsi_end_p (si); gsi_next (&si))
9021                 {
9022                   gimple *seq_stmt = gsi_stmt (si);
9023                   gimple_set_bb (seq_stmt, NULL);
9024                   lhs = gimple_get_lhs (seq_stmt);
9025                   if (lhs && TREE_CODE (lhs) == SSA_NAME)
9026                     release_ssa_name (lhs);
9027                   free_stmt_vec_info (seq_stmt);
9028                 }
9029             }
9030           free_stmt_vec_info (patt_stmt);
9031         }
9032     }
9033
9034   STMT_VINFO_SAME_ALIGN_REFS (stmt_info).release ();
9035   STMT_VINFO_SIMD_CLONE_INFO (stmt_info).release ();
9036   set_vinfo_for_stmt (stmt, NULL);
9037   free (stmt_info);
9038 }
9039
9040
9041 /* Function get_vectype_for_scalar_type_and_size.
9042
9043    Returns the vector type corresponding to SCALAR_TYPE  and SIZE as supported
9044    by the target.  */
9045
9046 static tree
9047 get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
9048 {
9049   tree orig_scalar_type = scalar_type;
9050   machine_mode inner_mode = TYPE_MODE (scalar_type);
9051   machine_mode simd_mode;
9052   unsigned int nbytes = GET_MODE_SIZE (inner_mode);
9053   int nunits;
9054   tree vectype;
9055
9056   if (nbytes == 0)
9057     return NULL_TREE;
9058
9059   if (GET_MODE_CLASS (inner_mode) != MODE_INT
9060       && GET_MODE_CLASS (inner_mode) != MODE_FLOAT)
9061     return NULL_TREE;
9062
9063   /* For vector types of elements whose mode precision doesn't
9064      match their types precision we use a element type of mode
9065      precision.  The vectorization routines will have to make sure
9066      they support the proper result truncation/extension.
9067      We also make sure to build vector types with INTEGER_TYPE
9068      component type only.  */
9069   if (INTEGRAL_TYPE_P (scalar_type)
9070       && (GET_MODE_BITSIZE (inner_mode) != TYPE_PRECISION (scalar_type)
9071           || TREE_CODE (scalar_type) != INTEGER_TYPE))
9072     scalar_type = build_nonstandard_integer_type (GET_MODE_BITSIZE (inner_mode),
9073                                                   TYPE_UNSIGNED (scalar_type));
9074
9075   /* We shouldn't end up building VECTOR_TYPEs of non-scalar components.
9076      When the component mode passes the above test simply use a type
9077      corresponding to that mode.  The theory is that any use that
9078      would cause problems with this will disable vectorization anyway.  */
9079   else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
9080            && !INTEGRAL_TYPE_P (scalar_type))
9081     scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
9082
9083   /* We can't build a vector type of elements with alignment bigger than
9084      their size.  */
9085   else if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
9086     scalar_type = lang_hooks.types.type_for_mode (inner_mode, 
9087                                                   TYPE_UNSIGNED (scalar_type));
9088
9089   /* If we felt back to using the mode fail if there was
9090      no scalar type for it.  */
9091   if (scalar_type == NULL_TREE)
9092     return NULL_TREE;
9093
9094   /* If no size was supplied use the mode the target prefers.   Otherwise
9095      lookup a vector mode of the specified size.  */
9096   if (size == 0)
9097     simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
9098   else
9099     simd_mode = mode_for_vector (inner_mode, size / nbytes);
9100   nunits = GET_MODE_SIZE (simd_mode) / nbytes;
9101   if (nunits <= 1)
9102     return NULL_TREE;
9103
9104   vectype = build_vector_type (scalar_type, nunits);
9105
9106   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
9107       && !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
9108     return NULL_TREE;
9109
9110   /* Re-attach the address-space qualifier if we canonicalized the scalar
9111      type.  */
9112   if (TYPE_ADDR_SPACE (orig_scalar_type) != TYPE_ADDR_SPACE (vectype))
9113     return build_qualified_type
9114              (vectype, KEEP_QUAL_ADDR_SPACE (TYPE_QUALS (orig_scalar_type)));
9115
9116   return vectype;
9117 }
9118
9119 unsigned int current_vector_size;
9120
9121 /* Function get_vectype_for_scalar_type.
9122
9123    Returns the vector type corresponding to SCALAR_TYPE as supported
9124    by the target.  */
9125
9126 tree
9127 get_vectype_for_scalar_type (tree scalar_type)
9128 {
9129   tree vectype;
9130   vectype = get_vectype_for_scalar_type_and_size (scalar_type,
9131                                                   current_vector_size);
9132   if (vectype
9133       && current_vector_size == 0)
9134     current_vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
9135   return vectype;
9136 }
9137
9138 /* Function get_mask_type_for_scalar_type.
9139
9140    Returns the mask type corresponding to a result of comparison
9141    of vectors of specified SCALAR_TYPE as supported by target.  */
9142
9143 tree
9144 get_mask_type_for_scalar_type (tree scalar_type)
9145 {
9146   tree vectype = get_vectype_for_scalar_type (scalar_type);
9147
9148   if (!vectype)
9149     return NULL;
9150
9151   return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (vectype),
9152                                   current_vector_size);
9153 }
9154
9155 /* Function get_same_sized_vectype
9156
9157    Returns a vector type corresponding to SCALAR_TYPE of size
9158    VECTOR_TYPE if supported by the target.  */
9159
9160 tree
9161 get_same_sized_vectype (tree scalar_type, tree vector_type)
9162 {
9163   if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type))
9164     return build_same_sized_truth_vector_type (vector_type);
9165
9166   return get_vectype_for_scalar_type_and_size
9167            (scalar_type, GET_MODE_SIZE (TYPE_MODE (vector_type)));
9168 }
9169
9170 /* Function vect_is_simple_use.
9171
9172    Input:
9173    VINFO - the vect info of the loop or basic block that is being vectorized.
9174    OPERAND - operand in the loop or bb.
9175    Output:
9176    DEF_STMT - the defining stmt in case OPERAND is an SSA_NAME.
9177    DT - the type of definition
9178
9179    Returns whether a stmt with OPERAND can be vectorized.
9180    For loops, supportable operands are constants, loop invariants, and operands
9181    that are defined by the current iteration of the loop.  Unsupportable
9182    operands are those that are defined by a previous iteration of the loop (as
9183    is the case in reduction/induction computations).
9184    For basic blocks, supportable operands are constants and bb invariants.
9185    For now, operands defined outside the basic block are not supported.  */
9186
9187 bool
9188 vect_is_simple_use (tree operand, vec_info *vinfo,
9189                     gimple **def_stmt, enum vect_def_type *dt)
9190 {
9191   *def_stmt = NULL;
9192   *dt = vect_unknown_def_type;
9193
9194   if (dump_enabled_p ())
9195     {
9196       dump_printf_loc (MSG_NOTE, vect_location,
9197                        "vect_is_simple_use: operand ");
9198       dump_generic_expr (MSG_NOTE, TDF_SLIM, operand);
9199       dump_printf (MSG_NOTE, "\n");
9200     }
9201
9202   if (CONSTANT_CLASS_P (operand))
9203     {
9204       *dt = vect_constant_def;
9205       return true;
9206     }
9207
9208   if (is_gimple_min_invariant (operand))
9209     {
9210       *dt = vect_external_def;
9211       return true;
9212     }
9213
9214   if (TREE_CODE (operand) != SSA_NAME)
9215     {
9216       if (dump_enabled_p ())
9217         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
9218                          "not ssa-name.\n");
9219       return false;
9220     }
9221
9222   if (SSA_NAME_IS_DEFAULT_DEF (operand))
9223     {
9224       *dt = vect_external_def;
9225       return true;
9226     }
9227
9228   *def_stmt = SSA_NAME_DEF_STMT (operand);
9229   if (dump_enabled_p ())
9230     {
9231       dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: ");
9232       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, *def_stmt, 0);
9233     }
9234
9235   if (! vect_stmt_in_region_p (vinfo, *def_stmt))
9236     *dt = vect_external_def;
9237   else
9238     {
9239       stmt_vec_info stmt_vinfo = vinfo_for_stmt (*def_stmt);
9240       *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);
9241     }
9242
9243   if (dump_enabled_p ())
9244     {
9245       dump_printf_loc (MSG_NOTE, vect_location, "type of def: ");
9246       switch (*dt)
9247         {
9248         case vect_uninitialized_def:
9249           dump_printf (MSG_NOTE, "uninitialized\n");
9250           break;
9251         case vect_constant_def:
9252           dump_printf (MSG_NOTE, "constant\n");
9253           break;
9254         case vect_external_def:
9255           dump_printf (MSG_NOTE, "external\n");
9256           break;
9257         case vect_internal_def:
9258           dump_printf (MSG_NOTE, "internal\n");
9259           break;
9260         case vect_induction_def:
9261           dump_printf (MSG_NOTE, "induction\n");
9262           break;
9263         case vect_reduction_def:
9264           dump_printf (MSG_NOTE, "reduction\n");
9265           break;
9266         case vect_double_reduction_def:
9267           dump_printf (MSG_NOTE, "double reduction\n");
9268           break;
9269         case vect_nested_cycle:
9270           dump_printf (MSG_NOTE, "nested cycle\n");
9271           break;
9272         case vect_unknown_def_type:
9273           dump_printf (MSG_NOTE, "unknown\n");
9274           break;
9275         }
9276     }
9277
9278   if (*dt == vect_unknown_def_type)
9279     {
9280       if (dump_enabled_p ())
9281         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
9282                          "Unsupported pattern.\n");
9283       return false;
9284     }
9285
9286   switch (gimple_code (*def_stmt))
9287     {
9288     case GIMPLE_PHI:
9289     case GIMPLE_ASSIGN:
9290     case GIMPLE_CALL:
9291       break;
9292     default:
9293       if (dump_enabled_p ())
9294         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
9295                          "unsupported defining stmt:\n");
9296       return false;
9297     }
9298
9299   return true;
9300 }
9301
9302 /* Function vect_is_simple_use.
9303
9304    Same as vect_is_simple_use but also determines the vector operand
9305    type of OPERAND and stores it to *VECTYPE.  If the definition of
9306    OPERAND is vect_uninitialized_def, vect_constant_def or
9307    vect_external_def *VECTYPE will be set to NULL_TREE and the caller
9308    is responsible to compute the best suited vector type for the
9309    scalar operand.  */
9310
9311 bool
9312 vect_is_simple_use (tree operand, vec_info *vinfo,
9313                     gimple **def_stmt, enum vect_def_type *dt, tree *vectype)
9314 {
9315   if (!vect_is_simple_use (operand, vinfo, def_stmt, dt))
9316     return false;
9317
9318   /* Now get a vector type if the def is internal, otherwise supply
9319      NULL_TREE and leave it up to the caller to figure out a proper
9320      type for the use stmt.  */
9321   if (*dt == vect_internal_def
9322       || *dt == vect_induction_def
9323       || *dt == vect_reduction_def
9324       || *dt == vect_double_reduction_def
9325       || *dt == vect_nested_cycle)
9326     {
9327       stmt_vec_info stmt_info = vinfo_for_stmt (*def_stmt);
9328
9329       if (STMT_VINFO_IN_PATTERN_P (stmt_info)
9330           && !STMT_VINFO_RELEVANT (stmt_info)
9331           && !STMT_VINFO_LIVE_P (stmt_info))
9332         stmt_info = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info));
9333
9334       *vectype = STMT_VINFO_VECTYPE (stmt_info);
9335       gcc_assert (*vectype != NULL_TREE);
9336     }
9337   else if (*dt == vect_uninitialized_def
9338            || *dt == vect_constant_def
9339            || *dt == vect_external_def)
9340     *vectype = NULL_TREE;
9341   else
9342     gcc_unreachable ();
9343
9344   return true;
9345 }
9346
9347
9348 /* Function supportable_widening_operation
9349
9350    Check whether an operation represented by the code CODE is a
9351    widening operation that is supported by the target platform in
9352    vector form (i.e., when operating on arguments of type VECTYPE_IN
9353    producing a result of type VECTYPE_OUT).
9354
9355    Widening operations we currently support are NOP (CONVERT), FLOAT
9356    and WIDEN_MULT.  This function checks if these operations are supported
9357    by the target platform either directly (via vector tree-codes), or via
9358    target builtins.
9359
9360    Output:
9361    - CODE1 and CODE2 are codes of vector operations to be used when
9362    vectorizing the operation, if available.
9363    - MULTI_STEP_CVT determines the number of required intermediate steps in
9364    case of multi-step conversion (like char->short->int - in that case
9365    MULTI_STEP_CVT will be 1).
9366    - INTERM_TYPES contains the intermediate type required to perform the
9367    widening operation (short in the above example).  */
9368
9369 bool
9370 supportable_widening_operation (enum tree_code code, gimple *stmt,
9371                                 tree vectype_out, tree vectype_in,
9372                                 enum tree_code *code1, enum tree_code *code2,
9373                                 int *multi_step_cvt,
9374                                 vec<tree> *interm_types)
9375 {
9376   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
9377   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info);
9378   struct loop *vect_loop = NULL;
9379   machine_mode vec_mode;
9380   enum insn_code icode1, icode2;
9381   optab optab1, optab2;
9382   tree vectype = vectype_in;
9383   tree wide_vectype = vectype_out;
9384   enum tree_code c1, c2;
9385   int i;
9386   tree prev_type, intermediate_type;
9387   machine_mode intermediate_mode, prev_mode;
9388   optab optab3, optab4;
9389
9390   *multi_step_cvt = 0;
9391   if (loop_info)
9392     vect_loop = LOOP_VINFO_LOOP (loop_info);
9393
9394   switch (code)
9395     {
9396     case WIDEN_MULT_EXPR:
9397       /* The result of a vectorized widening operation usually requires
9398          two vectors (because the widened results do not fit into one vector).
9399          The generated vector results would normally be expected to be
9400          generated in the same order as in the original scalar computation,
9401          i.e. if 8 results are generated in each vector iteration, they are
9402          to be organized as follows:
9403                 vect1: [res1,res2,res3,res4],
9404                 vect2: [res5,res6,res7,res8].
9405
9406          However, in the special case that the result of the widening
9407          operation is used in a reduction computation only, the order doesn't
9408          matter (because when vectorizing a reduction we change the order of
9409          the computation).  Some targets can take advantage of this and
9410          generate more efficient code.  For example, targets like Altivec,
9411          that support widen_mult using a sequence of {mult_even,mult_odd}
9412          generate the following vectors:
9413                 vect1: [res1,res3,res5,res7],
9414                 vect2: [res2,res4,res6,res8].
9415
9416          When vectorizing outer-loops, we execute the inner-loop sequentially
9417          (each vectorized inner-loop iteration contributes to VF outer-loop
9418          iterations in parallel).  We therefore don't allow to change the
9419          order of the computation in the inner-loop during outer-loop
9420          vectorization.  */
9421       /* TODO: Another case in which order doesn't *really* matter is when we
9422          widen and then contract again, e.g. (short)((int)x * y >> 8).
9423          Normally, pack_trunc performs an even/odd permute, whereas the 
9424          repack from an even/odd expansion would be an interleave, which
9425          would be significantly simpler for e.g. AVX2.  */
9426       /* In any case, in order to avoid duplicating the code below, recurse
9427          on VEC_WIDEN_MULT_EVEN_EXPR.  If it succeeds, all the return values
9428          are properly set up for the caller.  If we fail, we'll continue with
9429          a VEC_WIDEN_MULT_LO/HI_EXPR check.  */
9430       if (vect_loop
9431           && STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
9432           && !nested_in_vect_loop_p (vect_loop, stmt)
9433           && supportable_widening_operation (VEC_WIDEN_MULT_EVEN_EXPR,
9434                                              stmt, vectype_out, vectype_in,
9435                                              code1, code2, multi_step_cvt,
9436                                              interm_types))
9437         {
9438           /* Elements in a vector with vect_used_by_reduction property cannot
9439              be reordered if the use chain with this property does not have the
9440              same operation.  One such an example is s += a * b, where elements
9441              in a and b cannot be reordered.  Here we check if the vector defined
9442              by STMT is only directly used in the reduction statement.  */
9443           tree lhs = gimple_assign_lhs (stmt);
9444           use_operand_p dummy;
9445           gimple *use_stmt;
9446           stmt_vec_info use_stmt_info = NULL;
9447           if (single_imm_use (lhs, &dummy, &use_stmt)
9448               && (use_stmt_info = vinfo_for_stmt (use_stmt))
9449               && STMT_VINFO_DEF_TYPE (use_stmt_info) == vect_reduction_def)
9450             return true;
9451         }
9452       c1 = VEC_WIDEN_MULT_LO_EXPR;
9453       c2 = VEC_WIDEN_MULT_HI_EXPR;
9454       break;
9455
9456     case DOT_PROD_EXPR:
9457       c1 = DOT_PROD_EXPR;
9458       c2 = DOT_PROD_EXPR;
9459       break;
9460
9461     case SAD_EXPR:
9462       c1 = SAD_EXPR;
9463       c2 = SAD_EXPR;
9464       break;
9465
9466     case VEC_WIDEN_MULT_EVEN_EXPR:
9467       /* Support the recursion induced just above.  */
9468       c1 = VEC_WIDEN_MULT_EVEN_EXPR;
9469       c2 = VEC_WIDEN_MULT_ODD_EXPR;
9470       break;
9471
9472     case WIDEN_LSHIFT_EXPR:
9473       c1 = VEC_WIDEN_LSHIFT_LO_EXPR;
9474       c2 = VEC_WIDEN_LSHIFT_HI_EXPR;
9475       break;
9476
9477     CASE_CONVERT:
9478       c1 = VEC_UNPACK_LO_EXPR;
9479       c2 = VEC_UNPACK_HI_EXPR;
9480       break;
9481
9482     case FLOAT_EXPR:
9483       c1 = VEC_UNPACK_FLOAT_LO_EXPR;
9484       c2 = VEC_UNPACK_FLOAT_HI_EXPR;
9485       break;
9486
9487     case FIX_TRUNC_EXPR:
9488       /* ??? Not yet implemented due to missing VEC_UNPACK_FIX_TRUNC_HI_EXPR/
9489          VEC_UNPACK_FIX_TRUNC_LO_EXPR tree codes and optabs used for
9490          computing the operation.  */
9491       return false;
9492
9493     default:
9494       gcc_unreachable ();
9495     }
9496
9497   if (BYTES_BIG_ENDIAN && c1 != VEC_WIDEN_MULT_EVEN_EXPR)
9498     std::swap (c1, c2);
9499
9500   if (code == FIX_TRUNC_EXPR)
9501     {
9502       /* The signedness is determined from output operand.  */
9503       optab1 = optab_for_tree_code (c1, vectype_out, optab_default);
9504       optab2 = optab_for_tree_code (c2, vectype_out, optab_default);
9505     }
9506   else
9507     {
9508       optab1 = optab_for_tree_code (c1, vectype, optab_default);
9509       optab2 = optab_for_tree_code (c2, vectype, optab_default);
9510     }
9511
9512   if (!optab1 || !optab2)
9513     return false;
9514
9515   vec_mode = TYPE_MODE (vectype);
9516   if ((icode1 = optab_handler (optab1, vec_mode)) == CODE_FOR_nothing
9517        || (icode2 = optab_handler (optab2, vec_mode)) == CODE_FOR_nothing)
9518     return false;
9519
9520   *code1 = c1;
9521   *code2 = c2;
9522
9523   if (insn_data[icode1].operand[0].mode == TYPE_MODE (wide_vectype)
9524       && insn_data[icode2].operand[0].mode == TYPE_MODE (wide_vectype))
9525       /* For scalar masks we may have different boolean
9526          vector types having the same QImode.  Thus we
9527          add additional check for elements number.  */
9528     return (!VECTOR_BOOLEAN_TYPE_P (vectype)
9529             || (TYPE_VECTOR_SUBPARTS (vectype) / 2
9530                 == TYPE_VECTOR_SUBPARTS (wide_vectype)));
9531
9532   /* Check if it's a multi-step conversion that can be done using intermediate
9533      types.  */
9534
9535   prev_type = vectype;
9536   prev_mode = vec_mode;
9537
9538   if (!CONVERT_EXPR_CODE_P (code))
9539     return false;
9540
9541   /* We assume here that there will not be more than MAX_INTERM_CVT_STEPS
9542      intermediate steps in promotion sequence.  We try
9543      MAX_INTERM_CVT_STEPS to get to NARROW_VECTYPE, and fail if we do
9544      not.  */
9545   interm_types->create (MAX_INTERM_CVT_STEPS);
9546   for (i = 0; i < MAX_INTERM_CVT_STEPS; i++)
9547     {
9548       intermediate_mode = insn_data[icode1].operand[0].mode;
9549       if (VECTOR_BOOLEAN_TYPE_P (prev_type))
9550         {
9551           intermediate_type
9552             = build_truth_vector_type (TYPE_VECTOR_SUBPARTS (prev_type) / 2,
9553                                        current_vector_size);
9554           if (intermediate_mode != TYPE_MODE (intermediate_type))
9555             return false;
9556         }
9557       else
9558         intermediate_type
9559           = lang_hooks.types.type_for_mode (intermediate_mode,
9560                                             TYPE_UNSIGNED (prev_type));
9561
9562       optab3 = optab_for_tree_code (c1, intermediate_type, optab_default);
9563       optab4 = optab_for_tree_code (c2, intermediate_type, optab_default);
9564
9565       if (!optab3 || !optab4
9566           || (icode1 = optab_handler (optab1, prev_mode)) == CODE_FOR_nothing
9567           || insn_data[icode1].operand[0].mode != intermediate_mode
9568           || (icode2 = optab_handler (optab2, prev_mode)) == CODE_FOR_nothing
9569           || insn_data[icode2].operand[0].mode != intermediate_mode
9570           || ((icode1 = optab_handler (optab3, intermediate_mode))
9571               == CODE_FOR_nothing)
9572           || ((icode2 = optab_handler (optab4, intermediate_mode))
9573               == CODE_FOR_nothing))
9574         break;
9575
9576       interm_types->quick_push (intermediate_type);
9577       (*multi_step_cvt)++;
9578
9579       if (insn_data[icode1].operand[0].mode == TYPE_MODE (wide_vectype)
9580           && insn_data[icode2].operand[0].mode == TYPE_MODE (wide_vectype))
9581         return (!VECTOR_BOOLEAN_TYPE_P (vectype)
9582                 || (TYPE_VECTOR_SUBPARTS (intermediate_type) / 2
9583                     == TYPE_VECTOR_SUBPARTS (wide_vectype)));
9584
9585       prev_type = intermediate_type;
9586       prev_mode = intermediate_mode;
9587     }
9588
9589   interm_types->release ();
9590   return false;
9591 }
9592
9593
9594 /* Function supportable_narrowing_operation
9595
9596    Check whether an operation represented by the code CODE is a
9597    narrowing operation that is supported by the target platform in
9598    vector form (i.e., when operating on arguments of type VECTYPE_IN
9599    and producing a result of type VECTYPE_OUT).
9600
9601    Narrowing operations we currently support are NOP (CONVERT) and
9602    FIX_TRUNC.  This function checks if these operations are supported by
9603    the target platform directly via vector tree-codes.
9604
9605    Output:
9606    - CODE1 is the code of a vector operation to be used when
9607    vectorizing the operation, if available.
9608    - MULTI_STEP_CVT determines the number of required intermediate steps in
9609    case of multi-step conversion (like int->short->char - in that case
9610    MULTI_STEP_CVT will be 1).
9611    - INTERM_TYPES contains the intermediate type required to perform the
9612    narrowing operation (short in the above example).   */
9613
9614 bool
9615 supportable_narrowing_operation (enum tree_code code,
9616                                  tree vectype_out, tree vectype_in,
9617                                  enum tree_code *code1, int *multi_step_cvt,
9618                                  vec<tree> *interm_types)
9619 {
9620   machine_mode vec_mode;
9621   enum insn_code icode1;
9622   optab optab1, interm_optab;
9623   tree vectype = vectype_in;
9624   tree narrow_vectype = vectype_out;
9625   enum tree_code c1;
9626   tree intermediate_type, prev_type;
9627   machine_mode intermediate_mode, prev_mode;
9628   int i;
9629   bool uns;
9630
9631   *multi_step_cvt = 0;
9632   switch (code)
9633     {
9634     CASE_CONVERT:
9635       c1 = VEC_PACK_TRUNC_EXPR;
9636       break;
9637
9638     case FIX_TRUNC_EXPR:
9639       c1 = VEC_PACK_FIX_TRUNC_EXPR;
9640       break;
9641
9642     case FLOAT_EXPR:
9643       /* ??? Not yet implemented due to missing VEC_PACK_FLOAT_EXPR
9644          tree code and optabs used for computing the operation.  */
9645       return false;
9646
9647     default:
9648       gcc_unreachable ();
9649     }
9650
9651   if (code == FIX_TRUNC_EXPR)
9652     /* The signedness is determined from output operand.  */
9653     optab1 = optab_for_tree_code (c1, vectype_out, optab_default);
9654   else
9655     optab1 = optab_for_tree_code (c1, vectype, optab_default);
9656
9657   if (!optab1)
9658     return false;
9659
9660   vec_mode = TYPE_MODE (vectype);
9661   if ((icode1 = optab_handler (optab1, vec_mode)) == CODE_FOR_nothing)
9662     return false;
9663
9664   *code1 = c1;
9665
9666   if (insn_data[icode1].operand[0].mode == TYPE_MODE (narrow_vectype))
9667     /* For scalar masks we may have different boolean
9668        vector types having the same QImode.  Thus we
9669        add additional check for elements number.  */
9670     return (!VECTOR_BOOLEAN_TYPE_P (vectype)
9671             || (TYPE_VECTOR_SUBPARTS (vectype) * 2
9672                 == TYPE_VECTOR_SUBPARTS (narrow_vectype)));
9673
9674   /* Check if it's a multi-step conversion that can be done using intermediate
9675      types.  */
9676   prev_mode = vec_mode;
9677   prev_type = vectype;
9678   if (code == FIX_TRUNC_EXPR)
9679     uns = TYPE_UNSIGNED (vectype_out);
9680   else
9681     uns = TYPE_UNSIGNED (vectype);
9682
9683   /* For multi-step FIX_TRUNC_EXPR prefer signed floating to integer
9684      conversion over unsigned, as unsigned FIX_TRUNC_EXPR is often more
9685      costly than signed.  */
9686   if (code == FIX_TRUNC_EXPR && uns)
9687     {
9688       enum insn_code icode2;
9689
9690       intermediate_type
9691         = lang_hooks.types.type_for_mode (TYPE_MODE (vectype_out), 0);
9692       interm_optab
9693         = optab_for_tree_code (c1, intermediate_type, optab_default);
9694       if (interm_optab != unknown_optab
9695           && (icode2 = optab_handler (optab1, vec_mode)) != CODE_FOR_nothing
9696           && insn_data[icode1].operand[0].mode
9697              == insn_data[icode2].operand[0].mode)
9698         {
9699           uns = false;
9700           optab1 = interm_optab;
9701           icode1 = icode2;
9702         }
9703     }
9704
9705   /* We assume here that there will not be more than MAX_INTERM_CVT_STEPS
9706      intermediate steps in promotion sequence.  We try
9707      MAX_INTERM_CVT_STEPS to get to NARROW_VECTYPE, and fail if we do not.  */
9708   interm_types->create (MAX_INTERM_CVT_STEPS);
9709   for (i = 0; i < MAX_INTERM_CVT_STEPS; i++)
9710     {
9711       intermediate_mode = insn_data[icode1].operand[0].mode;
9712       if (VECTOR_BOOLEAN_TYPE_P (prev_type))
9713         {
9714           intermediate_type
9715             = build_truth_vector_type (TYPE_VECTOR_SUBPARTS (prev_type) * 2,
9716                                        current_vector_size);
9717           if (intermediate_mode != TYPE_MODE (intermediate_type))
9718               return false;
9719         }
9720       else
9721         intermediate_type
9722           = lang_hooks.types.type_for_mode (intermediate_mode, uns);
9723       interm_optab
9724         = optab_for_tree_code (VEC_PACK_TRUNC_EXPR, intermediate_type,
9725                                optab_default);
9726       if (!interm_optab
9727           || ((icode1 = optab_handler (optab1, prev_mode)) == CODE_FOR_nothing)
9728           || insn_data[icode1].operand[0].mode != intermediate_mode
9729           || ((icode1 = optab_handler (interm_optab, intermediate_mode))
9730               == CODE_FOR_nothing))
9731         break;
9732
9733       interm_types->quick_push (intermediate_type);
9734       (*multi_step_cvt)++;
9735
9736       if (insn_data[icode1].operand[0].mode == TYPE_MODE (narrow_vectype))
9737         return (!VECTOR_BOOLEAN_TYPE_P (vectype)
9738                 || (TYPE_VECTOR_SUBPARTS (intermediate_type) * 2
9739                     == TYPE_VECTOR_SUBPARTS (narrow_vectype)));
9740
9741       prev_mode = intermediate_mode;
9742       prev_type = intermediate_type;
9743       optab1 = interm_optab;
9744     }
9745
9746   interm_types->release ();
9747   return false;
9748 }