gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / tree-vect-patterns.c
1 /* Analysis Utilities for Loop Vectorization.
2    Copyright (C) 2006-2018 Free Software Foundation, Inc.
3    Contributed by Dorit Nuzman <dorit@il.ibm.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ssa.h"
29 #include "expmed.h"
30 #include "optabs-tree.h"
31 #include "insn-config.h"
32 #include "recog.h"              /* FIXME: for insn_data */
33 #include "fold-const.h"
34 #include "stor-layout.h"
35 #include "tree-eh.h"
36 #include "gimplify.h"
37 #include "gimple-iterator.h"
38 #include "cfgloop.h"
39 #include "tree-vectorizer.h"
40 #include "dumpfile.h"
41 #include "builtins.h"
42 #include "internal-fn.h"
43 #include "case-cfn-macros.h"
44 #include "fold-const-call.h"
45 #include "attribs.h"
46 #include "cgraph.h"
47 #include "omp-simd-clone.h"
48
49 /* Pattern recognition functions  */
50 static gimple *vect_recog_widen_sum_pattern (vec<gimple *> *, tree *,
51                                             tree *);
52 static gimple *vect_recog_widen_mult_pattern (vec<gimple *> *, tree *,
53                                              tree *);
54 static gimple *vect_recog_dot_prod_pattern (vec<gimple *> *, tree *,
55                                            tree *);
56 static gimple *vect_recog_sad_pattern (vec<gimple *> *, tree *,
57                                       tree *);
58 static gimple *vect_recog_pow_pattern (vec<gimple *> *, tree *, tree *);
59 static gimple *vect_recog_over_widening_pattern (vec<gimple *> *, tree *,
60                                                  tree *);
61 static gimple *vect_recog_widen_shift_pattern (vec<gimple *> *,
62                                         tree *, tree *);
63 static gimple *vect_recog_rotate_pattern (vec<gimple *> *, tree *, tree *);
64 static gimple *vect_recog_vector_vector_shift_pattern (vec<gimple *> *,
65                                                       tree *, tree *);
66 static gimple *vect_recog_divmod_pattern (vec<gimple *> *,
67                                          tree *, tree *);
68
69 static gimple *vect_recog_mult_pattern (vec<gimple *> *,
70                                        tree *, tree *);
71
72 static gimple *vect_recog_mixed_size_cond_pattern (vec<gimple *> *,
73                                                   tree *, tree *);
74 static gimple *vect_recog_bool_pattern (vec<gimple *> *, tree *, tree *);
75 static gimple *vect_recog_mask_conversion_pattern (vec<gimple *> *, tree *, tree *);
76 static gimple *vect_recog_gather_scatter_pattern (vec<gimple *> *, tree *,
77                                                   tree *);
78
79 struct vect_recog_func
80 {
81   vect_recog_func_ptr fn;
82   const char *name;
83 };
84
85 /* Note that ordering matters - the first pattern matching on a stmt
86    is taken which means usually the more complex one needs to preceed
87    the less comples onex (widen_sum only after dot_prod or sad for example).  */
88 static vect_recog_func vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
89       { vect_recog_widen_mult_pattern, "widen_mult" },
90       { vect_recog_dot_prod_pattern, "dot_prod" },
91       { vect_recog_sad_pattern, "sad" },
92       { vect_recog_widen_sum_pattern, "widen_sum" },
93       { vect_recog_pow_pattern, "pow" },
94       { vect_recog_widen_shift_pattern, "widen_shift" },
95       { vect_recog_over_widening_pattern, "over_widening" },
96       { vect_recog_rotate_pattern, "rotate" },
97       { vect_recog_vector_vector_shift_pattern, "vector_vector_shift" },
98       { vect_recog_divmod_pattern, "divmod" },
99       { vect_recog_mult_pattern, "mult" },
100       { vect_recog_mixed_size_cond_pattern, "mixed_size_cond" },
101       { vect_recog_bool_pattern, "bool" },
102       /* This must come before mask conversion, and includes the parts
103          of mask conversion that are needed for gather and scatter
104          internal functions.  */
105       { vect_recog_gather_scatter_pattern, "gather_scatter" },
106       { vect_recog_mask_conversion_pattern, "mask_conversion" }
107 };
108
109 static inline void
110 append_pattern_def_seq (stmt_vec_info stmt_info, gimple *stmt)
111 {
112   gimple_seq_add_stmt_without_update (&STMT_VINFO_PATTERN_DEF_SEQ (stmt_info),
113                                       stmt);
114 }
115
116 static inline void
117 new_pattern_def_seq (stmt_vec_info stmt_info, gimple *stmt)
118 {
119   STMT_VINFO_PATTERN_DEF_SEQ (stmt_info) = NULL;
120   append_pattern_def_seq (stmt_info, stmt);
121 }
122
123 /* Check whether STMT2 is in the same loop or basic block as STMT1.
124    Which of the two applies depends on whether we're currently doing
125    loop-based or basic-block-based vectorization, as determined by
126    the vinfo_for_stmt for STMT1 (which must be defined).
127
128    If this returns true, vinfo_for_stmt for STMT2 is guaranteed
129    to be defined as well.  */
130
131 static bool
132 vect_same_loop_or_bb_p (gimple *stmt1, gimple *stmt2)
133 {
134   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt1);
135   return vect_stmt_in_region_p (stmt_vinfo->vinfo, stmt2);
136 }
137
138 /* If the LHS of DEF_STMT has a single use, and that statement is
139    in the same loop or basic block, return it.  */
140
141 static gimple *
142 vect_single_imm_use (gimple *def_stmt)
143 {
144   tree lhs = gimple_assign_lhs (def_stmt);
145   use_operand_p use_p;
146   gimple *use_stmt;
147
148   if (!single_imm_use (lhs, &use_p, &use_stmt))
149     return NULL;
150
151   if (!vect_same_loop_or_bb_p (def_stmt, use_stmt))
152     return NULL;
153
154   return use_stmt;
155 }
156
157 /* Check whether NAME, an ssa-name used in USE_STMT,
158    is a result of a type promotion, such that:
159      DEF_STMT: NAME = NOP (name0)
160    If CHECK_SIGN is TRUE, check that either both types are signed or both are
161    unsigned.  */
162
163 static bool
164 type_conversion_p (tree name, gimple *use_stmt, bool check_sign,
165                    tree *orig_type, gimple **def_stmt, bool *promotion)
166 {
167   gimple *dummy_gimple;
168   stmt_vec_info stmt_vinfo;
169   tree type = TREE_TYPE (name);
170   tree oprnd0;
171   enum vect_def_type dt;
172
173   stmt_vinfo = vinfo_for_stmt (use_stmt);
174   if (!vect_is_simple_use (name, stmt_vinfo->vinfo, def_stmt, &dt))
175     return false;
176
177   if (dt != vect_internal_def
178       && dt != vect_external_def && dt != vect_constant_def)
179     return false;
180
181   if (!*def_stmt)
182     return false;
183
184   if (dt == vect_internal_def)
185     {
186       stmt_vec_info def_vinfo = vinfo_for_stmt (*def_stmt);
187       if (STMT_VINFO_IN_PATTERN_P (def_vinfo))
188         return false;
189     }
190
191   if (!is_gimple_assign (*def_stmt))
192     return false;
193
194   if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (*def_stmt)))
195     return false;
196
197   oprnd0 = gimple_assign_rhs1 (*def_stmt);
198
199   *orig_type = TREE_TYPE (oprnd0);
200   if (!INTEGRAL_TYPE_P (type) || !INTEGRAL_TYPE_P (*orig_type)
201       || ((TYPE_UNSIGNED (type) != TYPE_UNSIGNED (*orig_type)) && check_sign))
202     return false;
203
204   if (TYPE_PRECISION (type) >= (TYPE_PRECISION (*orig_type) * 2))
205     *promotion = true;
206   else
207     *promotion = false;
208
209   if (!vect_is_simple_use (oprnd0, stmt_vinfo->vinfo, &dummy_gimple, &dt))
210     return false;
211
212   return true;
213 }
214
215 /* Helper to return a new temporary for pattern of TYPE for STMT.  If STMT
216    is NULL, the caller must set SSA_NAME_DEF_STMT for the returned SSA var. */
217
218 static tree
219 vect_recog_temp_ssa_var (tree type, gimple *stmt)
220 {
221   return make_temp_ssa_name (type, stmt, "patt");
222 }
223
224 /* Return true if STMT_VINFO describes a reduction for which reassociation
225    is allowed.  If STMT_INFO is part of a group, assume that it's part of
226    a reduction chain and optimistically assume that all statements
227    except the last allow reassociation.  */
228
229 static bool
230 vect_reassociating_reduction_p (stmt_vec_info stmt_vinfo)
231 {
232   return (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
233           ? STMT_VINFO_REDUC_TYPE (stmt_vinfo) != FOLD_LEFT_REDUCTION
234           : GROUP_FIRST_ELEMENT (stmt_vinfo) != NULL);
235 }
236
237 /* Function vect_recog_dot_prod_pattern
238
239    Try to find the following pattern:
240
241      type x_t, y_t;
242      TYPE1 prod;
243      TYPE2 sum = init;
244    loop:
245      sum_0 = phi <init, sum_1>
246      S1  x_t = ...
247      S2  y_t = ...
248      S3  x_T = (TYPE1) x_t;
249      S4  y_T = (TYPE1) y_t;
250      S5  prod = x_T * y_T;
251      [S6  prod = (TYPE2) prod;  #optional]
252      S7  sum_1 = prod + sum_0;
253
254    where 'TYPE1' is exactly double the size of type 'type', and 'TYPE2' is the
255    same size of 'TYPE1' or bigger. This is a special case of a reduction
256    computation.
257
258    Input:
259
260    * STMTS: Contains a stmt from which the pattern search begins.  In the
261    example, when this function is called with S7, the pattern {S3,S4,S5,S6,S7}
262    will be detected.
263
264    Output:
265
266    * TYPE_IN: The type of the input arguments to the pattern.
267
268    * TYPE_OUT: The type of the output  of this pattern.
269
270    * Return value: A new stmt that will be used to replace the sequence of
271    stmts that constitute the pattern. In this case it will be:
272         WIDEN_DOT_PRODUCT <x_t, y_t, sum_0>
273
274    Note: The dot-prod idiom is a widening reduction pattern that is
275          vectorized without preserving all the intermediate results. It
276          produces only N/2 (widened) results (by summing up pairs of
277          intermediate results) rather than all N results.  Therefore, we
278          cannot allow this pattern when we want to get all the results and in
279          the correct order (as is the case when this computation is in an
280          inner-loop nested in an outer-loop that us being vectorized).  */
281
282 static gimple *
283 vect_recog_dot_prod_pattern (vec<gimple *> *stmts, tree *type_in,
284                              tree *type_out)
285 {
286   gimple *stmt, *last_stmt = (*stmts)[0];
287   tree oprnd0, oprnd1;
288   tree oprnd00, oprnd01;
289   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
290   tree type, half_type;
291   gimple *pattern_stmt;
292   tree prod_type;
293   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
294   struct loop *loop;
295   tree var;
296   bool promotion;
297
298   if (!loop_info)
299     return NULL;
300
301   loop = LOOP_VINFO_LOOP (loop_info);
302
303   /* We don't allow changing the order of the computation in the inner-loop
304      when doing outer-loop vectorization.  */
305   if (loop && nested_in_vect_loop_p (loop, last_stmt))
306     return NULL;
307
308   if (!is_gimple_assign (last_stmt))
309     return NULL;
310
311   type = gimple_expr_type (last_stmt);
312
313   /* Look for the following pattern
314           DX = (TYPE1) X;
315           DY = (TYPE1) Y;
316           DPROD = DX * DY;
317           DDPROD = (TYPE2) DPROD;
318           sum_1 = DDPROD + sum_0;
319      In which
320      - DX is double the size of X
321      - DY is double the size of Y
322      - DX, DY, DPROD all have the same type
323      - sum is the same size of DPROD or bigger
324      - sum has been recognized as a reduction variable.
325
326      This is equivalent to:
327        DPROD = X w* Y;          #widen mult
328        sum_1 = DPROD w+ sum_0;  #widen summation
329      or
330        DPROD = X w* Y;          #widen mult
331        sum_1 = DPROD + sum_0;   #summation
332    */
333
334   /* Starting from LAST_STMT, follow the defs of its uses in search
335      of the above pattern.  */
336
337   if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
338     return NULL;
339
340   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
341     {
342       /* Has been detected as widening-summation?  */
343
344       stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
345       type = gimple_expr_type (stmt);
346       if (gimple_assign_rhs_code (stmt) != WIDEN_SUM_EXPR)
347         return NULL;
348       oprnd0 = gimple_assign_rhs1 (stmt);
349       oprnd1 = gimple_assign_rhs2 (stmt);
350       half_type = TREE_TYPE (oprnd0);
351     }
352   else
353     {
354       gimple *def_stmt;
355
356       if (!vect_reassociating_reduction_p (stmt_vinfo))
357         return NULL;
358       oprnd0 = gimple_assign_rhs1 (last_stmt);
359       oprnd1 = gimple_assign_rhs2 (last_stmt);
360       if (!types_compatible_p (TREE_TYPE (oprnd0), type)
361           || !types_compatible_p (TREE_TYPE (oprnd1), type))
362         return NULL;
363       stmt = last_stmt;
364
365       if (type_conversion_p (oprnd0, stmt, true, &half_type, &def_stmt,
366                              &promotion)
367           && promotion)
368         {
369           stmt = def_stmt;
370           oprnd0 = gimple_assign_rhs1 (stmt);
371         }
372       else
373         half_type = type;
374     }
375
376   /* So far so good.  Since last_stmt was detected as a (summation) reduction,
377      we know that oprnd1 is the reduction variable (defined by a loop-header
378      phi), and oprnd0 is an ssa-name defined by a stmt in the loop body.
379      Left to check that oprnd0 is defined by a (widen_)mult_expr  */
380   if (TREE_CODE (oprnd0) != SSA_NAME)
381     return NULL;
382
383   prod_type = half_type;
384   stmt = SSA_NAME_DEF_STMT (oprnd0);
385
386   /* It could not be the dot_prod pattern if the stmt is outside the loop.  */
387   if (!gimple_bb (stmt) || !flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
388     return NULL;
389
390   /* FORNOW.  Can continue analyzing the def-use chain when this stmt in a phi
391      inside the loop (in case we are analyzing an outer-loop).  */
392   if (!is_gimple_assign (stmt))
393     return NULL;
394   stmt_vinfo = vinfo_for_stmt (stmt);
395   gcc_assert (stmt_vinfo);
396   if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_internal_def)
397     return NULL;
398   if (gimple_assign_rhs_code (stmt) != MULT_EXPR)
399     return NULL;
400   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
401     {
402       /* Has been detected as a widening multiplication?  */
403
404       stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
405       if (gimple_assign_rhs_code (stmt) != WIDEN_MULT_EXPR)
406         return NULL;
407       stmt_vinfo = vinfo_for_stmt (stmt);
408       gcc_assert (stmt_vinfo);
409       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_internal_def);
410       oprnd00 = gimple_assign_rhs1 (stmt);
411       oprnd01 = gimple_assign_rhs2 (stmt);
412       STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (last_stmt))
413           = STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo);
414     }
415   else
416     {
417       tree half_type0, half_type1;
418       gimple *def_stmt;
419       tree oprnd0, oprnd1;
420
421       oprnd0 = gimple_assign_rhs1 (stmt);
422       oprnd1 = gimple_assign_rhs2 (stmt);
423       if (!types_compatible_p (TREE_TYPE (oprnd0), prod_type)
424           || !types_compatible_p (TREE_TYPE (oprnd1), prod_type))
425         return NULL;
426       if (!type_conversion_p (oprnd0, stmt, true, &half_type0, &def_stmt,
427                               &promotion)
428           || !promotion)
429         return NULL;
430       oprnd00 = gimple_assign_rhs1 (def_stmt);
431       if (!type_conversion_p (oprnd1, stmt, true, &half_type1, &def_stmt,
432                               &promotion)
433           || !promotion)
434         return NULL;
435       oprnd01 = gimple_assign_rhs1 (def_stmt);
436       if (!types_compatible_p (half_type0, half_type1))
437         return NULL;
438       if (TYPE_PRECISION (prod_type) != TYPE_PRECISION (half_type0) * 2)
439         return NULL;
440     }
441
442   half_type = TREE_TYPE (oprnd00);
443   *type_in = half_type;
444   *type_out = type;
445
446   /* Pattern detected. Create a stmt to be used to replace the pattern: */
447   var = vect_recog_temp_ssa_var (type, NULL);
448   pattern_stmt = gimple_build_assign (var, DOT_PROD_EXPR,
449                                       oprnd00, oprnd01, oprnd1);
450
451   if (dump_enabled_p ())
452     {
453       dump_printf_loc (MSG_NOTE, vect_location,
454                        "vect_recog_dot_prod_pattern: detected: ");
455       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
456     }
457
458   return pattern_stmt;
459 }
460
461
462 /* Function vect_recog_sad_pattern
463
464    Try to find the following Sum of Absolute Difference (SAD) pattern:
465
466      type x_t, y_t;
467      signed TYPE1 diff, abs_diff;
468      TYPE2 sum = init;
469    loop:
470      sum_0 = phi <init, sum_1>
471      S1  x_t = ...
472      S2  y_t = ...
473      S3  x_T = (TYPE1) x_t;
474      S4  y_T = (TYPE1) y_t;
475      S5  diff = x_T - y_T;
476      S6  abs_diff = ABS_EXPR <diff>;
477      [S7  abs_diff = (TYPE2) abs_diff;  #optional]
478      S8  sum_1 = abs_diff + sum_0;
479
480    where 'TYPE1' is at least double the size of type 'type', and 'TYPE2' is the
481    same size of 'TYPE1' or bigger. This is a special case of a reduction
482    computation.
483
484    Input:
485
486    * STMTS: Contains a stmt from which the pattern search begins.  In the
487    example, when this function is called with S8, the pattern
488    {S3,S4,S5,S6,S7,S8} will be detected.
489
490    Output:
491
492    * TYPE_IN: The type of the input arguments to the pattern.
493
494    * TYPE_OUT: The type of the output of this pattern.
495
496    * Return value: A new stmt that will be used to replace the sequence of
497    stmts that constitute the pattern. In this case it will be:
498         SAD_EXPR <x_t, y_t, sum_0>
499   */
500
501 static gimple *
502 vect_recog_sad_pattern (vec<gimple *> *stmts, tree *type_in,
503                              tree *type_out)
504 {
505   gimple *last_stmt = (*stmts)[0];
506   tree sad_oprnd0, sad_oprnd1;
507   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
508   tree half_type;
509   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
510   struct loop *loop;
511   bool promotion;
512
513   if (!loop_info)
514     return NULL;
515
516   loop = LOOP_VINFO_LOOP (loop_info);
517
518   /* We don't allow changing the order of the computation in the inner-loop
519      when doing outer-loop vectorization.  */
520   if (loop && nested_in_vect_loop_p (loop, last_stmt))
521     return NULL;
522
523   if (!is_gimple_assign (last_stmt))
524     return NULL;
525
526   tree sum_type = gimple_expr_type (last_stmt);
527
528   /* Look for the following pattern
529           DX = (TYPE1) X;
530           DY = (TYPE1) Y;
531           DDIFF = DX - DY;
532           DAD = ABS_EXPR <DDIFF>;
533           DDPROD = (TYPE2) DPROD;
534           sum_1 = DAD + sum_0;
535      In which
536      - DX is at least double the size of X
537      - DY is at least double the size of Y
538      - DX, DY, DDIFF, DAD all have the same type
539      - sum is the same size of DAD or bigger
540      - sum has been recognized as a reduction variable.
541
542      This is equivalent to:
543        DDIFF = X w- Y;          #widen sub
544        DAD = ABS_EXPR <DDIFF>;
545        sum_1 = DAD w+ sum_0;    #widen summation
546      or
547        DDIFF = X w- Y;          #widen sub
548        DAD = ABS_EXPR <DDIFF>;
549        sum_1 = DAD + sum_0;     #summation
550    */
551
552   /* Starting from LAST_STMT, follow the defs of its uses in search
553      of the above pattern.  */
554
555   if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
556     return NULL;
557
558   tree plus_oprnd0, plus_oprnd1;
559
560   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
561     {
562       /* Has been detected as widening-summation?  */
563
564       gimple *stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
565       sum_type = gimple_expr_type (stmt);
566       if (gimple_assign_rhs_code (stmt) != WIDEN_SUM_EXPR)
567         return NULL;
568       plus_oprnd0 = gimple_assign_rhs1 (stmt);
569       plus_oprnd1 = gimple_assign_rhs2 (stmt);
570       half_type = TREE_TYPE (plus_oprnd0);
571     }
572   else
573     {
574       gimple *def_stmt;
575
576       if (!vect_reassociating_reduction_p (stmt_vinfo))
577         return NULL;
578       plus_oprnd0 = gimple_assign_rhs1 (last_stmt);
579       plus_oprnd1 = gimple_assign_rhs2 (last_stmt);
580       if (!types_compatible_p (TREE_TYPE (plus_oprnd0), sum_type)
581           || !types_compatible_p (TREE_TYPE (plus_oprnd1), sum_type))
582         return NULL;
583
584       /* The type conversion could be promotion, demotion,
585          or just signed -> unsigned.  */
586       if (type_conversion_p (plus_oprnd0, last_stmt, false,
587                              &half_type, &def_stmt, &promotion))
588         plus_oprnd0 = gimple_assign_rhs1 (def_stmt);
589       else
590         half_type = sum_type;
591     }
592
593   /* So far so good.  Since last_stmt was detected as a (summation) reduction,
594      we know that plus_oprnd1 is the reduction variable (defined by a loop-header
595      phi), and plus_oprnd0 is an ssa-name defined by a stmt in the loop body.
596      Then check that plus_oprnd0 is defined by an abs_expr.  */
597
598   if (TREE_CODE (plus_oprnd0) != SSA_NAME)
599     return NULL;
600
601   tree abs_type = half_type;
602   gimple *abs_stmt = SSA_NAME_DEF_STMT (plus_oprnd0);
603
604   /* It could not be the sad pattern if the abs_stmt is outside the loop.  */
605   if (!gimple_bb (abs_stmt) || !flow_bb_inside_loop_p (loop, gimple_bb (abs_stmt)))
606     return NULL;
607
608   /* FORNOW.  Can continue analyzing the def-use chain when this stmt in a phi
609      inside the loop (in case we are analyzing an outer-loop).  */
610   if (!is_gimple_assign (abs_stmt))
611     return NULL;
612
613   stmt_vec_info abs_stmt_vinfo = vinfo_for_stmt (abs_stmt);
614   gcc_assert (abs_stmt_vinfo);
615   if (STMT_VINFO_DEF_TYPE (abs_stmt_vinfo) != vect_internal_def)
616     return NULL;
617   if (gimple_assign_rhs_code (abs_stmt) != ABS_EXPR)
618     return NULL;
619
620   tree abs_oprnd = gimple_assign_rhs1 (abs_stmt);
621   if (!types_compatible_p (TREE_TYPE (abs_oprnd), abs_type))
622     return NULL;
623   if (TYPE_UNSIGNED (abs_type))
624     return NULL;
625
626   /* We then detect if the operand of abs_expr is defined by a minus_expr.  */
627
628   if (TREE_CODE (abs_oprnd) != SSA_NAME)
629     return NULL;
630
631   gimple *diff_stmt = SSA_NAME_DEF_STMT (abs_oprnd);
632
633   /* It could not be the sad pattern if the diff_stmt is outside the loop.  */
634   if (!gimple_bb (diff_stmt)
635       || !flow_bb_inside_loop_p (loop, gimple_bb (diff_stmt)))
636     return NULL;
637
638   /* FORNOW.  Can continue analyzing the def-use chain when this stmt in a phi
639      inside the loop (in case we are analyzing an outer-loop).  */
640   if (!is_gimple_assign (diff_stmt))
641     return NULL;
642
643   stmt_vec_info diff_stmt_vinfo = vinfo_for_stmt (diff_stmt);
644   gcc_assert (diff_stmt_vinfo);
645   if (STMT_VINFO_DEF_TYPE (diff_stmt_vinfo) != vect_internal_def)
646     return NULL;
647   if (gimple_assign_rhs_code (diff_stmt) != MINUS_EXPR)
648     return NULL;
649
650   tree half_type0, half_type1;
651   gimple *def_stmt;
652
653   tree minus_oprnd0 = gimple_assign_rhs1 (diff_stmt);
654   tree minus_oprnd1 = gimple_assign_rhs2 (diff_stmt);
655
656   if (!types_compatible_p (TREE_TYPE (minus_oprnd0), abs_type)
657       || !types_compatible_p (TREE_TYPE (minus_oprnd1), abs_type))
658     return NULL;
659   if (!type_conversion_p (minus_oprnd0, diff_stmt, false,
660                           &half_type0, &def_stmt, &promotion)
661       || !promotion)
662     return NULL;
663   sad_oprnd0 = gimple_assign_rhs1 (def_stmt);
664
665   if (!type_conversion_p (minus_oprnd1, diff_stmt, false,
666                           &half_type1, &def_stmt, &promotion)
667       || !promotion)
668     return NULL;
669   sad_oprnd1 = gimple_assign_rhs1 (def_stmt);
670
671   if (!types_compatible_p (half_type0, half_type1))
672     return NULL;
673   if (TYPE_PRECISION (abs_type) < TYPE_PRECISION (half_type0) * 2
674       || TYPE_PRECISION (sum_type) < TYPE_PRECISION (half_type0) * 2)
675     return NULL;
676
677   *type_in = TREE_TYPE (sad_oprnd0);
678   *type_out = sum_type;
679
680   /* Pattern detected. Create a stmt to be used to replace the pattern: */
681   tree var = vect_recog_temp_ssa_var (sum_type, NULL);
682   gimple *pattern_stmt = gimple_build_assign (var, SAD_EXPR, sad_oprnd0,
683                                               sad_oprnd1, plus_oprnd1);
684
685   if (dump_enabled_p ())
686     {
687       dump_printf_loc (MSG_NOTE, vect_location,
688                        "vect_recog_sad_pattern: detected: ");
689       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
690     }
691
692   return pattern_stmt;
693 }
694
695
696 /* Handle widening operation by a constant.  At the moment we support MULT_EXPR
697    and LSHIFT_EXPR.
698
699    For MULT_EXPR we check that CONST_OPRND fits HALF_TYPE, and for LSHIFT_EXPR
700    we check that CONST_OPRND is less or equal to the size of HALF_TYPE.
701
702    Otherwise, if the type of the result (TYPE) is at least 4 times bigger than
703    HALF_TYPE, and there is an intermediate type (2 times smaller than TYPE)
704    that satisfies the above restrictions,  we can perform a widening opeartion
705    from the intermediate type to TYPE and replace a_T = (TYPE) a_t;
706    with a_it = (interm_type) a_t;  Store such operation in *WSTMT.  */
707
708 static bool
709 vect_handle_widen_op_by_const (gimple *stmt, enum tree_code code,
710                                tree const_oprnd, tree *oprnd,
711                                gimple **wstmt, tree type,
712                                tree *half_type, gimple *def_stmt)
713 {
714   tree new_type, new_oprnd;
715
716   if (code != MULT_EXPR && code != LSHIFT_EXPR)
717     return false;
718
719   if (((code == MULT_EXPR && int_fits_type_p (const_oprnd, *half_type))
720         || (code == LSHIFT_EXPR
721             && compare_tree_int (const_oprnd, TYPE_PRECISION (*half_type))
722                 != 1))
723       && TYPE_PRECISION (type) == (TYPE_PRECISION (*half_type) * 2))
724     {
725       /* CONST_OPRND is a constant of HALF_TYPE.  */
726       *oprnd = gimple_assign_rhs1 (def_stmt);
727       return true;
728     }
729
730   if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4))
731     return false;
732
733   if (!vect_same_loop_or_bb_p (stmt, def_stmt))
734     return false;
735
736   /* TYPE is 4 times bigger than HALF_TYPE, try widening operation for
737      a type 2 times bigger than HALF_TYPE.  */
738   new_type = build_nonstandard_integer_type (TYPE_PRECISION (type) / 2,
739                                              TYPE_UNSIGNED (type));
740   if ((code == MULT_EXPR && !int_fits_type_p (const_oprnd, new_type))
741       || (code == LSHIFT_EXPR
742           && compare_tree_int (const_oprnd, TYPE_PRECISION (new_type)) == 1))
743     return false;
744
745   /* Use NEW_TYPE for widening operation and create a_T = (NEW_TYPE) a_t;  */
746   *oprnd = gimple_assign_rhs1 (def_stmt);
747   new_oprnd = make_ssa_name (new_type);
748   *wstmt = gimple_build_assign (new_oprnd, NOP_EXPR, *oprnd);
749   *oprnd = new_oprnd;
750
751   *half_type = new_type;
752   return true;
753 }
754
755
756 /* Function vect_recog_widen_mult_pattern
757
758    Try to find the following pattern:
759
760      type1 a_t;
761      type2 b_t;
762      TYPE a_T, b_T, prod_T;
763
764      S1  a_t = ;
765      S2  b_t = ;
766      S3  a_T = (TYPE) a_t;
767      S4  b_T = (TYPE) b_t;
768      S5  prod_T = a_T * b_T;
769
770    where type 'TYPE' is at least double the size of type 'type1' and 'type2'.
771
772    Also detect unsigned cases:
773
774      unsigned type1 a_t;
775      unsigned type2 b_t;
776      unsigned TYPE u_prod_T;
777      TYPE a_T, b_T, prod_T;
778
779      S1  a_t = ;
780      S2  b_t = ;
781      S3  a_T = (TYPE) a_t;
782      S4  b_T = (TYPE) b_t;
783      S5  prod_T = a_T * b_T;
784      S6  u_prod_T = (unsigned TYPE) prod_T;
785
786    and multiplication by constants:
787
788      type a_t;
789      TYPE a_T, prod_T;
790
791      S1  a_t = ;
792      S3  a_T = (TYPE) a_t;
793      S5  prod_T = a_T * CONST;
794
795    A special case of multiplication by constants is when 'TYPE' is 4 times
796    bigger than 'type', but CONST fits an intermediate type 2 times smaller
797    than 'TYPE'.  In that case we create an additional pattern stmt for S3
798    to create a variable of the intermediate type, and perform widen-mult
799    on the intermediate type as well:
800
801      type a_t;
802      interm_type a_it;
803      TYPE a_T, prod_T,  prod_T';
804
805      S1  a_t = ;
806      S3  a_T = (TYPE) a_t;
807            '--> a_it = (interm_type) a_t;
808      S5  prod_T = a_T * CONST;
809            '--> prod_T' = a_it w* CONST;
810
811    Input/Output:
812
813    * STMTS: Contains a stmt from which the pattern search begins.  In the
814    example, when this function is called with S5, the pattern {S3,S4,S5,(S6)}
815    is detected.  In case of unsigned widen-mult, the original stmt (S5) is
816    replaced with S6 in STMTS.  In case of multiplication by a constant
817    of an intermediate type (the last case above), STMTS also contains S3
818    (inserted before S5).
819
820    Output:
821
822    * TYPE_IN: The type of the input arguments to the pattern.
823
824    * TYPE_OUT: The type of the output of this pattern.
825
826    * Return value: A new stmt that will be used to replace the sequence of
827    stmts that constitute the pattern.  In this case it will be:
828         WIDEN_MULT <a_t, b_t>
829    If the result of WIDEN_MULT needs to be converted to a larger type, the
830    returned stmt will be this type conversion stmt.
831 */
832
833 static gimple *
834 vect_recog_widen_mult_pattern (vec<gimple *> *stmts,
835                                tree *type_in, tree *type_out)
836 {
837   gimple *last_stmt = stmts->pop ();
838   gimple *def_stmt0, *def_stmt1;
839   tree oprnd0, oprnd1;
840   tree type, half_type0, half_type1;
841   gimple *new_stmt = NULL, *pattern_stmt = NULL;
842   tree vectype, vecitype;
843   tree var;
844   enum tree_code dummy_code;
845   int dummy_int;
846   vec<tree> dummy_vec;
847   bool op1_ok;
848   bool promotion;
849
850   if (!is_gimple_assign (last_stmt))
851     return NULL;
852
853   type = gimple_expr_type (last_stmt);
854
855   /* Starting from LAST_STMT, follow the defs of its uses in search
856      of the above pattern.  */
857
858   if (gimple_assign_rhs_code (last_stmt) != MULT_EXPR)
859     return NULL;
860
861   oprnd0 = gimple_assign_rhs1 (last_stmt);
862   oprnd1 = gimple_assign_rhs2 (last_stmt);
863   if (!types_compatible_p (TREE_TYPE (oprnd0), type)
864       || !types_compatible_p (TREE_TYPE (oprnd1), type))
865     return NULL;
866
867   /* Check argument 0.  */
868   if (!type_conversion_p (oprnd0, last_stmt, false, &half_type0, &def_stmt0,
869                          &promotion)
870       || !promotion)
871      return NULL;
872   /* Check argument 1.  */
873   op1_ok = type_conversion_p (oprnd1, last_stmt, false, &half_type1,
874                               &def_stmt1, &promotion);
875
876   if (op1_ok && promotion)
877     {
878       oprnd0 = gimple_assign_rhs1 (def_stmt0);
879       oprnd1 = gimple_assign_rhs1 (def_stmt1);
880     }          
881   else
882     {
883       if (TREE_CODE (oprnd1) == INTEGER_CST
884           && TREE_CODE (half_type0) == INTEGER_TYPE
885           && vect_handle_widen_op_by_const (last_stmt, MULT_EXPR, oprnd1,
886                                             &oprnd0, &new_stmt, type,
887                                             &half_type0, def_stmt0))
888         {
889           half_type1 = half_type0;
890           oprnd1 = fold_convert (half_type1, oprnd1);
891         }
892       else
893         return NULL;
894     }
895
896   /* If the two arguments have different sizes, convert the one with
897      the smaller type into the larger type.  */
898   if (TYPE_PRECISION (half_type0) != TYPE_PRECISION (half_type1))
899     {
900       /* If we already used up the single-stmt slot give up.  */
901       if (new_stmt)
902         return NULL;
903
904       tree* oprnd = NULL;
905       gimple *def_stmt = NULL;
906
907       if (TYPE_PRECISION (half_type0) < TYPE_PRECISION (half_type1))
908         {
909           def_stmt = def_stmt0;
910           half_type0 = half_type1;
911           oprnd = &oprnd0;
912         }
913       else
914         {
915           def_stmt = def_stmt1;
916           half_type1 = half_type0;
917           oprnd = &oprnd1;
918         }
919
920       tree old_oprnd = gimple_assign_rhs1 (def_stmt);
921       tree new_oprnd = make_ssa_name (half_type0);
922       new_stmt = gimple_build_assign (new_oprnd, NOP_EXPR, old_oprnd);
923       *oprnd = new_oprnd;
924     }
925
926   /* Handle unsigned case.  Look for
927      S6  u_prod_T = (unsigned TYPE) prod_T;
928      Use unsigned TYPE as the type for WIDEN_MULT_EXPR.  */
929   if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (half_type0))
930     {
931       gimple *use_stmt;
932       tree use_lhs;
933       tree use_type;
934
935       if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (half_type1))
936         return NULL;
937
938       use_stmt = vect_single_imm_use (last_stmt);
939       if (!use_stmt || !is_gimple_assign (use_stmt)
940           || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)))
941         return NULL;
942
943       use_lhs = gimple_assign_lhs (use_stmt);
944       use_type = TREE_TYPE (use_lhs);
945       if (!INTEGRAL_TYPE_P (use_type)
946           || (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (use_type))
947           || (TYPE_PRECISION (type) != TYPE_PRECISION (use_type)))
948         return NULL;
949
950       type = use_type;
951       last_stmt = use_stmt;
952     }
953
954   if (!types_compatible_p (half_type0, half_type1))
955     return NULL;
956
957   /* If TYPE is more than twice larger than HALF_TYPE, we use WIDEN_MULT
958      to get an intermediate result of type ITYPE.  In this case we need
959      to build a statement to convert this intermediate result to type TYPE.  */
960   tree itype = type;
961   if (TYPE_PRECISION (type) > TYPE_PRECISION (half_type0) * 2)
962     itype = build_nonstandard_integer_type
963               (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (half_type0)) * 2,
964                TYPE_UNSIGNED (type));
965
966   /* Pattern detected.  */
967   if (dump_enabled_p ())
968     dump_printf_loc (MSG_NOTE, vect_location,
969                      "vect_recog_widen_mult_pattern: detected:\n");
970
971   /* Check target support  */
972   vectype = get_vectype_for_scalar_type (half_type0);
973   vecitype = get_vectype_for_scalar_type (itype);
974   if (!vectype
975       || !vecitype
976       || !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt,
977                                           vecitype, vectype,
978                                           &dummy_code, &dummy_code,
979                                           &dummy_int, &dummy_vec))
980     return NULL;
981
982   *type_in = vectype;
983   *type_out = get_vectype_for_scalar_type (type);
984
985   /* Pattern supported. Create a stmt to be used to replace the pattern: */
986   var = vect_recog_temp_ssa_var (itype, NULL);
987   pattern_stmt = gimple_build_assign (var, WIDEN_MULT_EXPR, oprnd0, oprnd1);
988
989   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
990   STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) = NULL;
991
992   /* If the original two operands have different sizes, we may need to convert
993      the smaller one into the larget type.  If this is the case, at this point
994      the new stmt is already built.  */
995   if (new_stmt)
996     {
997       append_pattern_def_seq (stmt_vinfo, new_stmt);
998       stmt_vec_info new_stmt_info
999         = new_stmt_vec_info (new_stmt, stmt_vinfo->vinfo);
1000       set_vinfo_for_stmt (new_stmt, new_stmt_info);
1001       STMT_VINFO_VECTYPE (new_stmt_info) = vectype;
1002     }
1003
1004   /* If ITYPE is not TYPE, we need to build a type convertion stmt to convert
1005      the result of the widen-mult operation into type TYPE.  */
1006   if (itype != type)
1007     {
1008       append_pattern_def_seq (stmt_vinfo, pattern_stmt);
1009       stmt_vec_info pattern_stmt_info
1010         = new_stmt_vec_info (pattern_stmt, stmt_vinfo->vinfo);
1011       set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
1012       STMT_VINFO_VECTYPE (pattern_stmt_info) = vecitype;
1013       pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (type, NULL),
1014                                           NOP_EXPR,
1015                                           gimple_assign_lhs (pattern_stmt));
1016     }
1017
1018   if (dump_enabled_p ())
1019     dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
1020
1021   stmts->safe_push (last_stmt);
1022   return pattern_stmt;
1023 }
1024
1025
1026 /* Function vect_recog_pow_pattern
1027
1028    Try to find the following pattern:
1029
1030      x = POW (y, N);
1031
1032    with POW being one of pow, powf, powi, powif and N being
1033    either 2 or 0.5.
1034
1035    Input:
1036
1037    * LAST_STMT: A stmt from which the pattern search begins.
1038
1039    Output:
1040
1041    * TYPE_IN: The type of the input arguments to the pattern.
1042
1043    * TYPE_OUT: The type of the output of this pattern.
1044
1045    * Return value: A new stmt that will be used to replace the sequence of
1046    stmts that constitute the pattern. In this case it will be:
1047         x = x * x
1048    or
1049         x = sqrt (x)
1050 */
1051
1052 static gimple *
1053 vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
1054                         tree *type_out)
1055 {
1056   gimple *last_stmt = (*stmts)[0];
1057   tree base, exp;
1058   gimple *stmt;
1059   tree var;
1060
1061   if (!is_gimple_call (last_stmt) || gimple_call_lhs (last_stmt) == NULL)
1062     return NULL;
1063
1064   switch (gimple_call_combined_fn (last_stmt))
1065     {
1066     CASE_CFN_POW:
1067     CASE_CFN_POWI:
1068       break;
1069
1070     default:
1071       return NULL;
1072     }
1073
1074   base = gimple_call_arg (last_stmt, 0);
1075   exp = gimple_call_arg (last_stmt, 1);
1076   if (TREE_CODE (exp) != REAL_CST
1077       && TREE_CODE (exp) != INTEGER_CST)
1078     {
1079       if (flag_unsafe_math_optimizations
1080           && TREE_CODE (base) == REAL_CST
1081           && !gimple_call_internal_p (last_stmt))
1082         {
1083           combined_fn log_cfn;
1084           built_in_function exp_bfn;
1085           switch (DECL_FUNCTION_CODE (gimple_call_fndecl (last_stmt)))
1086             {
1087             case BUILT_IN_POW:
1088               log_cfn = CFN_BUILT_IN_LOG;
1089               exp_bfn = BUILT_IN_EXP;
1090               break;
1091             case BUILT_IN_POWF:
1092               log_cfn = CFN_BUILT_IN_LOGF;
1093               exp_bfn = BUILT_IN_EXPF;
1094               break;
1095             case BUILT_IN_POWL:
1096               log_cfn = CFN_BUILT_IN_LOGL;
1097               exp_bfn = BUILT_IN_EXPL;
1098               break;
1099             default:
1100               return NULL;
1101             }
1102           tree logc = fold_const_call (log_cfn, TREE_TYPE (base), base);
1103           tree exp_decl = builtin_decl_implicit (exp_bfn);
1104           /* Optimize pow (C, x) as exp (log (C) * x).  Normally match.pd
1105              does that, but if C is a power of 2, we want to use
1106              exp2 (log2 (C) * x) in the non-vectorized version, but for
1107              vectorization we don't have vectorized exp2.  */
1108           if (logc
1109               && TREE_CODE (logc) == REAL_CST
1110               && exp_decl
1111               && lookup_attribute ("omp declare simd",
1112                                    DECL_ATTRIBUTES (exp_decl)))
1113             {
1114               cgraph_node *node = cgraph_node::get_create (exp_decl);
1115               if (node->simd_clones == NULL)
1116                 {
1117                   if (targetm.simd_clone.compute_vecsize_and_simdlen == NULL
1118                       || node->definition)
1119                     return NULL;
1120                   expand_simd_clones (node);
1121                   if (node->simd_clones == NULL)
1122                     return NULL;
1123                 }
1124               stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
1125               tree def = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL);
1126               gimple *g = gimple_build_assign (def, MULT_EXPR, exp, logc);
1127               new_pattern_def_seq (stmt_vinfo, g);
1128               *type_in = TREE_TYPE (base);
1129               *type_out = NULL_TREE;
1130               tree res = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL);
1131               g = gimple_build_call (exp_decl, 1, def);
1132               gimple_call_set_lhs (g, res);
1133               return g;
1134             }
1135         }
1136
1137       return NULL;
1138     }
1139
1140   /* We now have a pow or powi builtin function call with a constant
1141      exponent.  */
1142
1143   *type_out = NULL_TREE;
1144
1145   /* Catch squaring.  */
1146   if ((tree_fits_shwi_p (exp)
1147        && tree_to_shwi (exp) == 2)
1148       || (TREE_CODE (exp) == REAL_CST
1149           && real_equal (&TREE_REAL_CST (exp), &dconst2)))
1150     {
1151       *type_in = TREE_TYPE (base);
1152
1153       var = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL);
1154       stmt = gimple_build_assign (var, MULT_EXPR, base, base);
1155       return stmt;
1156     }
1157
1158   /* Catch square root.  */
1159   if (TREE_CODE (exp) == REAL_CST
1160       && real_equal (&TREE_REAL_CST (exp), &dconsthalf))
1161     {
1162       *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
1163       if (*type_in
1164           && direct_internal_fn_supported_p (IFN_SQRT, *type_in,
1165                                              OPTIMIZE_FOR_SPEED))
1166         {
1167           gcall *stmt = gimple_build_call_internal (IFN_SQRT, 1, base);
1168           var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt);
1169           gimple_call_set_lhs (stmt, var);
1170           gimple_call_set_nothrow (stmt, true);
1171           return stmt;
1172         }
1173     }
1174
1175   return NULL;
1176 }
1177
1178
1179 /* Function vect_recog_widen_sum_pattern
1180
1181    Try to find the following pattern:
1182
1183      type x_t;
1184      TYPE x_T, sum = init;
1185    loop:
1186      sum_0 = phi <init, sum_1>
1187      S1  x_t = *p;
1188      S2  x_T = (TYPE) x_t;
1189      S3  sum_1 = x_T + sum_0;
1190
1191    where type 'TYPE' is at least double the size of type 'type', i.e - we're
1192    summing elements of type 'type' into an accumulator of type 'TYPE'. This is
1193    a special case of a reduction computation.
1194
1195    Input:
1196
1197    * LAST_STMT: A stmt from which the pattern search begins. In the example,
1198    when this function is called with S3, the pattern {S2,S3} will be detected.
1199
1200    Output:
1201
1202    * TYPE_IN: The type of the input arguments to the pattern.
1203
1204    * TYPE_OUT: The type of the output of this pattern.
1205
1206    * Return value: A new stmt that will be used to replace the sequence of
1207    stmts that constitute the pattern. In this case it will be:
1208         WIDEN_SUM <x_t, sum_0>
1209
1210    Note: The widening-sum idiom is a widening reduction pattern that is
1211          vectorized without preserving all the intermediate results. It
1212          produces only N/2 (widened) results (by summing up pairs of
1213          intermediate results) rather than all N results.  Therefore, we
1214          cannot allow this pattern when we want to get all the results and in
1215          the correct order (as is the case when this computation is in an
1216          inner-loop nested in an outer-loop that us being vectorized).  */
1217
1218 static gimple *
1219 vect_recog_widen_sum_pattern (vec<gimple *> *stmts, tree *type_in,
1220                               tree *type_out)
1221 {
1222   gimple *stmt, *last_stmt = (*stmts)[0];
1223   tree oprnd0, oprnd1;
1224   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
1225   tree type, half_type;
1226   gimple *pattern_stmt;
1227   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
1228   struct loop *loop;
1229   tree var;
1230   bool promotion;
1231
1232   if (!loop_info)
1233     return NULL;
1234
1235   loop = LOOP_VINFO_LOOP (loop_info);
1236
1237   /* We don't allow changing the order of the computation in the inner-loop
1238      when doing outer-loop vectorization.  */
1239   if (loop && nested_in_vect_loop_p (loop, last_stmt))
1240     return NULL;
1241
1242   if (!is_gimple_assign (last_stmt))
1243     return NULL;
1244
1245   type = gimple_expr_type (last_stmt);
1246
1247   /* Look for the following pattern
1248           DX = (TYPE) X;
1249           sum_1 = DX + sum_0;
1250      In which DX is at least double the size of X, and sum_1 has been
1251      recognized as a reduction variable.
1252    */
1253
1254   /* Starting from LAST_STMT, follow the defs of its uses in search
1255      of the above pattern.  */
1256
1257   if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
1258     return NULL;
1259
1260   if (!vect_reassociating_reduction_p (stmt_vinfo))
1261     return NULL;
1262
1263   oprnd0 = gimple_assign_rhs1 (last_stmt);
1264   oprnd1 = gimple_assign_rhs2 (last_stmt);
1265   if (!types_compatible_p (TREE_TYPE (oprnd0), type)
1266       || !types_compatible_p (TREE_TYPE (oprnd1), type))
1267     return NULL;
1268
1269   /* So far so good.  Since last_stmt was detected as a (summation) reduction,
1270      we know that oprnd1 is the reduction variable (defined by a loop-header
1271      phi), and oprnd0 is an ssa-name defined by a stmt in the loop body.
1272      Left to check that oprnd0 is defined by a cast from type 'type' to type
1273      'TYPE'.  */
1274
1275   if (!type_conversion_p (oprnd0, last_stmt, true, &half_type, &stmt,
1276                           &promotion)
1277       || !promotion)
1278      return NULL;
1279
1280   oprnd0 = gimple_assign_rhs1 (stmt);
1281   *type_in = half_type;
1282   *type_out = type;
1283
1284   /* Pattern detected. Create a stmt to be used to replace the pattern: */
1285   var = vect_recog_temp_ssa_var (type, NULL);
1286   pattern_stmt = gimple_build_assign (var, WIDEN_SUM_EXPR, oprnd0, oprnd1);
1287
1288   if (dump_enabled_p ())
1289     {
1290       dump_printf_loc (MSG_NOTE, vect_location,
1291                        "vect_recog_widen_sum_pattern: detected: ");
1292       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
1293     }
1294
1295   return pattern_stmt;
1296 }
1297
1298
1299 /* Return TRUE if the operation in STMT can be performed on a smaller type.
1300
1301    Input:
1302    STMT - a statement to check.
1303    DEF - we support operations with two operands, one of which is constant.
1304          The other operand can be defined by a demotion operation, or by a
1305          previous statement in a sequence of over-promoted operations.  In the
1306          later case DEF is used to replace that operand.  (It is defined by a
1307          pattern statement we created for the previous statement in the
1308          sequence).
1309
1310    Input/output:
1311    NEW_TYPE - Output: a smaller type that we are trying to use.  Input: if not
1312          NULL, it's the type of DEF.
1313    STMTS - additional pattern statements.  If a pattern statement (type
1314          conversion) is created in this function, its original statement is
1315          added to STMTS.
1316
1317    Output:
1318    OP0, OP1 - if the operation fits a smaller type, OP0 and OP1 are the new
1319          operands to use in the new pattern statement for STMT (will be created
1320          in vect_recog_over_widening_pattern ()).
1321    NEW_DEF_STMT - in case DEF has to be promoted, we create two pattern
1322          statements for STMT: the first one is a type promotion and the second
1323          one is the operation itself.  We return the type promotion statement
1324          in NEW_DEF_STMT and further store it in STMT_VINFO_PATTERN_DEF_SEQ of
1325          the second pattern statement.  */
1326
1327 static bool
1328 vect_operation_fits_smaller_type (gimple *stmt, tree def, tree *new_type,
1329                                   tree *op0, tree *op1, gimple **new_def_stmt,
1330                                   vec<gimple *> *stmts)
1331 {
1332   enum tree_code code;
1333   tree const_oprnd, oprnd;
1334   tree interm_type = NULL_TREE, half_type, new_oprnd, type;
1335   gimple *def_stmt, *new_stmt;
1336   bool first = false;
1337   bool promotion;
1338
1339   *op0 = NULL_TREE;
1340   *op1 = NULL_TREE;
1341   *new_def_stmt = NULL;
1342
1343   if (!is_gimple_assign (stmt))
1344     return false;
1345
1346   code = gimple_assign_rhs_code (stmt);
1347   if (code != LSHIFT_EXPR && code != RSHIFT_EXPR
1348       && code != BIT_IOR_EXPR && code != BIT_XOR_EXPR && code != BIT_AND_EXPR)
1349     return false;
1350
1351   oprnd = gimple_assign_rhs1 (stmt);
1352   const_oprnd = gimple_assign_rhs2 (stmt);
1353   type = gimple_expr_type (stmt);
1354
1355   if (TREE_CODE (oprnd) != SSA_NAME
1356       || TREE_CODE (const_oprnd) != INTEGER_CST)
1357     return false;
1358
1359   /* If oprnd has other uses besides that in stmt we cannot mark it
1360      as being part of a pattern only.  */
1361   if (!has_single_use (oprnd))
1362     return false;
1363
1364   /* If we are in the middle of a sequence, we use DEF from a previous
1365      statement.  Otherwise, OPRND has to be a result of type promotion.  */
1366   if (*new_type)
1367     {
1368       half_type = *new_type;
1369       oprnd = def;
1370     }
1371   else
1372     {
1373       first = true;
1374       if (!type_conversion_p (oprnd, stmt, false, &half_type, &def_stmt,
1375                               &promotion)
1376           || !promotion
1377           || !vect_same_loop_or_bb_p (stmt, def_stmt))
1378         return false;
1379     }
1380
1381   /* Can we perform the operation on a smaller type?  */
1382   switch (code)
1383     {
1384       case BIT_IOR_EXPR:
1385       case BIT_XOR_EXPR:
1386       case BIT_AND_EXPR:
1387         if (!int_fits_type_p (const_oprnd, half_type))
1388           {
1389             /* HALF_TYPE is not enough.  Try a bigger type if possible.  */
1390             if (TYPE_PRECISION (type) < (TYPE_PRECISION (half_type) * 4))
1391               return false;
1392
1393             interm_type = build_nonstandard_integer_type (
1394                         TYPE_PRECISION (half_type) * 2, TYPE_UNSIGNED (type));
1395             if (!int_fits_type_p (const_oprnd, interm_type))
1396               return false;
1397           }
1398
1399         break;
1400
1401       case LSHIFT_EXPR:
1402         /* Try intermediate type - HALF_TYPE is not enough for sure.  */
1403         if (TYPE_PRECISION (type) < (TYPE_PRECISION (half_type) * 4))
1404           return false;
1405
1406         /* Check that HALF_TYPE size + shift amount <= INTERM_TYPE size.
1407           (e.g., if the original value was char, the shift amount is at most 8
1408            if we want to use short).  */
1409         if (compare_tree_int (const_oprnd, TYPE_PRECISION (half_type)) == 1)
1410           return false;
1411
1412         interm_type = build_nonstandard_integer_type (
1413                         TYPE_PRECISION (half_type) * 2, TYPE_UNSIGNED (type));
1414
1415         if (!vect_supportable_shift (code, interm_type))
1416           return false;
1417
1418         break;
1419
1420       case RSHIFT_EXPR:
1421         if (vect_supportable_shift (code, half_type))
1422           break;
1423
1424         /* Try intermediate type - HALF_TYPE is not supported.  */
1425         if (TYPE_PRECISION (type) < (TYPE_PRECISION (half_type) * 4))
1426           return false;
1427
1428         interm_type = build_nonstandard_integer_type (
1429                         TYPE_PRECISION (half_type) * 2, TYPE_UNSIGNED (type));
1430
1431         if (!vect_supportable_shift (code, interm_type))
1432           return false;
1433
1434         break;
1435
1436       default:
1437         gcc_unreachable ();
1438     }
1439
1440   /* There are four possible cases:
1441      1. OPRND is defined by a type promotion (in that case FIRST is TRUE, it's
1442         the first statement in the sequence)
1443         a. The original, HALF_TYPE, is not enough - we replace the promotion
1444            from HALF_TYPE to TYPE with a promotion to INTERM_TYPE.
1445         b. HALF_TYPE is sufficient, OPRND is set as the RHS of the original
1446            promotion.
1447      2. OPRND is defined by a pattern statement we created.
1448         a. Its type is not sufficient for the operation, we create a new stmt:
1449            a type conversion for OPRND from HALF_TYPE to INTERM_TYPE.  We store
1450            this statement in NEW_DEF_STMT, and it is later put in
1451            STMT_VINFO_PATTERN_DEF_SEQ of the pattern statement for STMT.
1452         b. OPRND is good to use in the new statement.  */
1453   if (first)
1454     {
1455       if (interm_type)
1456         {
1457           /* Replace the original type conversion HALF_TYPE->TYPE with
1458              HALF_TYPE->INTERM_TYPE.  */
1459           if (STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)))
1460             {
1461               new_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt));
1462               /* Check if the already created pattern stmt is what we need.  */
1463               if (!is_gimple_assign (new_stmt)
1464                   || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (new_stmt))
1465                   || TREE_TYPE (gimple_assign_lhs (new_stmt)) != interm_type)
1466                 return false;
1467
1468               stmts->safe_push (def_stmt);
1469               oprnd = gimple_assign_lhs (new_stmt);
1470             }
1471           else
1472             {
1473               /* Create NEW_OPRND = (INTERM_TYPE) OPRND.  */
1474               oprnd = gimple_assign_rhs1 (def_stmt);
1475               new_oprnd = make_ssa_name (interm_type);
1476               new_stmt = gimple_build_assign (new_oprnd, NOP_EXPR, oprnd);
1477               STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt;
1478               stmts->safe_push (def_stmt);
1479               oprnd = new_oprnd;
1480             }
1481         }
1482       else
1483         {
1484           /* Retrieve the operand before the type promotion.  */
1485           oprnd = gimple_assign_rhs1 (def_stmt);
1486         }
1487     }
1488   else
1489     {
1490       if (interm_type)
1491         {
1492           /* Create a type conversion HALF_TYPE->INTERM_TYPE.  */
1493           new_oprnd = make_ssa_name (interm_type);
1494           new_stmt = gimple_build_assign (new_oprnd, NOP_EXPR, oprnd);
1495           oprnd = new_oprnd;
1496           *new_def_stmt = new_stmt;
1497         }
1498
1499       /* Otherwise, OPRND is already set.  */
1500     }
1501
1502   if (interm_type)
1503     *new_type = interm_type;
1504   else
1505     *new_type = half_type;
1506
1507   *op0 = oprnd;
1508   *op1 = fold_convert (*new_type, const_oprnd);
1509
1510   return true;
1511 }
1512
1513
1514 /* Try to find a statement or a sequence of statements that can be performed
1515    on a smaller type:
1516
1517      type x_t;
1518      TYPE x_T, res0_T, res1_T;
1519    loop:
1520      S1  x_t = *p;
1521      S2  x_T = (TYPE) x_t;
1522      S3  res0_T = op (x_T, C0);
1523      S4  res1_T = op (res0_T, C1);
1524      S5  ... = () res1_T;  - type demotion
1525
1526    where type 'TYPE' is at least double the size of type 'type', C0 and C1 are
1527    constants.
1528    Check if S3 and S4 can be done on a smaller type than 'TYPE', it can either
1529    be 'type' or some intermediate type.  For now, we expect S5 to be a type
1530    demotion operation.  We also check that S3 and S4 have only one use.  */
1531
1532 static gimple *
1533 vect_recog_over_widening_pattern (vec<gimple *> *stmts,
1534                                   tree *type_in, tree *type_out)
1535 {
1536   gimple *stmt = stmts->pop ();
1537   gimple *pattern_stmt = NULL, *new_def_stmt, *prev_stmt = NULL,
1538          *use_stmt = NULL;
1539   tree op0, op1, vectype = NULL_TREE, use_lhs, use_type;
1540   tree var = NULL_TREE, new_type = NULL_TREE, new_oprnd;
1541   bool first;
1542   tree type = NULL;
1543
1544   first = true;
1545   while (1)
1546     {
1547       if (!vinfo_for_stmt (stmt)
1548           || STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt)))
1549         return NULL;
1550
1551       new_def_stmt = NULL;
1552       if (!vect_operation_fits_smaller_type (stmt, var, &new_type,
1553                                              &op0, &op1, &new_def_stmt,
1554                                              stmts))
1555         {
1556           if (first)
1557             return NULL;
1558           else
1559             break;
1560         }
1561
1562       /* STMT can be performed on a smaller type.  Check its uses.  */
1563       use_stmt = vect_single_imm_use (stmt);
1564       if (!use_stmt || !is_gimple_assign (use_stmt))
1565         return NULL;
1566
1567       /* Create pattern statement for STMT.  */
1568       vectype = get_vectype_for_scalar_type (new_type);
1569       if (!vectype)
1570         return NULL;
1571
1572       /* We want to collect all the statements for which we create pattern
1573          statetments, except for the case when the last statement in the
1574          sequence doesn't have a corresponding pattern statement.  In such
1575          case we associate the last pattern statement with the last statement
1576          in the sequence.  Therefore, we only add the original statement to
1577          the list if we know that it is not the last.  */
1578       if (prev_stmt)
1579         stmts->safe_push (prev_stmt);
1580
1581       var = vect_recog_temp_ssa_var (new_type, NULL);
1582       pattern_stmt
1583         = gimple_build_assign (var, gimple_assign_rhs_code (stmt), op0, op1);
1584       STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt)) = pattern_stmt;
1585       new_pattern_def_seq (vinfo_for_stmt (stmt), new_def_stmt);
1586
1587       if (dump_enabled_p ())
1588         {
1589           dump_printf_loc (MSG_NOTE, vect_location,
1590                            "created pattern stmt: ");
1591           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
1592         }
1593
1594       type = gimple_expr_type (stmt);
1595       prev_stmt = stmt;
1596       stmt = use_stmt;
1597
1598       first = false;
1599     }
1600
1601   /* We got a sequence.  We expect it to end with a type demotion operation.
1602      Otherwise, we quit (for now).  There are three possible cases: the
1603      conversion is to NEW_TYPE (we don't do anything), the conversion is to
1604      a type bigger than NEW_TYPE and/or the signedness of USE_TYPE and
1605      NEW_TYPE differs (we create a new conversion statement).  */
1606   if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)))
1607     {
1608       use_lhs = gimple_assign_lhs (use_stmt);
1609       use_type = TREE_TYPE (use_lhs);
1610       /* Support only type demotion or signedess change.  */
1611       if (!INTEGRAL_TYPE_P (use_type)
1612           || TYPE_PRECISION (type) <= TYPE_PRECISION (use_type))
1613         return NULL;
1614
1615       /* Check that NEW_TYPE is not bigger than the conversion result.  */
1616       if (TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type))
1617         return NULL;
1618
1619       if (TYPE_UNSIGNED (new_type) != TYPE_UNSIGNED (use_type)
1620           || TYPE_PRECISION (new_type) != TYPE_PRECISION (use_type))
1621         {
1622           /* Create NEW_TYPE->USE_TYPE conversion.  */
1623           new_oprnd = make_ssa_name (use_type);
1624           pattern_stmt = gimple_build_assign (new_oprnd, NOP_EXPR, var);
1625           STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use_stmt)) = pattern_stmt;
1626
1627           *type_in = get_vectype_for_scalar_type (new_type);
1628           *type_out = get_vectype_for_scalar_type (use_type);
1629
1630           /* We created a pattern statement for the last statement in the
1631              sequence, so we don't need to associate it with the pattern
1632              statement created for PREV_STMT.  Therefore, we add PREV_STMT
1633              to the list in order to mark it later in vect_pattern_recog_1.  */
1634           if (prev_stmt)
1635             stmts->safe_push (prev_stmt);
1636         }
1637       else
1638         {
1639           if (prev_stmt)
1640             STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (use_stmt))
1641                = STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (prev_stmt));
1642
1643           *type_in = vectype;
1644           *type_out = NULL_TREE;
1645         }
1646
1647       stmts->safe_push (use_stmt);
1648     }
1649   else
1650     /* TODO: support general case, create a conversion to the correct type.  */
1651     return NULL;
1652
1653   /* Pattern detected.  */
1654   if (dump_enabled_p ())
1655     {
1656       dump_printf_loc (MSG_NOTE, vect_location,
1657                        "vect_recog_over_widening_pattern: detected: ");
1658       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
1659     }
1660
1661   return pattern_stmt;
1662 }
1663
1664 /* Detect widening shift pattern:
1665
1666    type a_t;
1667    TYPE a_T, res_T;
1668
1669    S1 a_t = ;
1670    S2 a_T = (TYPE) a_t;
1671    S3 res_T = a_T << CONST;
1672
1673   where type 'TYPE' is at least double the size of type 'type'.
1674
1675   Also detect cases where the shift result is immediately converted
1676   to another type 'result_type' that is no larger in size than 'TYPE'.
1677   In those cases we perform a widen-shift that directly results in
1678   'result_type', to avoid a possible over-widening situation:
1679
1680   type a_t;
1681   TYPE a_T, res_T;
1682   result_type res_result;
1683
1684   S1 a_t = ;
1685   S2 a_T = (TYPE) a_t;
1686   S3 res_T = a_T << CONST;
1687   S4 res_result = (result_type) res_T;
1688       '--> res_result' = a_t w<< CONST;
1689
1690   And a case when 'TYPE' is 4 times bigger than 'type'.  In that case we
1691   create an additional pattern stmt for S2 to create a variable of an
1692   intermediate type, and perform widen-shift on the intermediate type:
1693
1694   type a_t;
1695   interm_type a_it;
1696   TYPE a_T, res_T, res_T';
1697
1698   S1 a_t = ;
1699   S2 a_T = (TYPE) a_t;
1700       '--> a_it = (interm_type) a_t;
1701   S3 res_T = a_T << CONST;
1702       '--> res_T' = a_it <<* CONST;
1703
1704   Input/Output:
1705
1706   * STMTS: Contains a stmt from which the pattern search begins.
1707     In case of unsigned widen-shift, the original stmt (S3) is replaced with S4
1708     in STMTS.  When an intermediate type is used and a pattern statement is
1709     created for S2, we also put S2 here (before S3).
1710
1711   Output:
1712
1713   * TYPE_IN: The type of the input arguments to the pattern.
1714
1715   * TYPE_OUT: The type of the output of this pattern.
1716
1717   * Return value: A new stmt that will be used to replace the sequence of
1718     stmts that constitute the pattern.  In this case it will be:
1719     WIDEN_LSHIFT_EXPR <a_t, CONST>.  */
1720
1721 static gimple *
1722 vect_recog_widen_shift_pattern (vec<gimple *> *stmts,
1723                                 tree *type_in, tree *type_out)
1724 {
1725   gimple *last_stmt = stmts->pop ();
1726   gimple *def_stmt0;
1727   tree oprnd0, oprnd1;
1728   tree type, half_type0;
1729   gimple *pattern_stmt;
1730   tree vectype, vectype_out = NULL_TREE;
1731   tree var;
1732   enum tree_code dummy_code;
1733   int dummy_int;
1734   vec<tree>  dummy_vec;
1735   gimple *use_stmt;
1736   bool promotion;
1737
1738   if (!is_gimple_assign (last_stmt) || !vinfo_for_stmt (last_stmt))
1739     return NULL;
1740
1741   if (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (last_stmt)))
1742     return NULL;
1743
1744   if (gimple_assign_rhs_code (last_stmt) != LSHIFT_EXPR)
1745     return NULL;
1746
1747   oprnd0 = gimple_assign_rhs1 (last_stmt);
1748   oprnd1 = gimple_assign_rhs2 (last_stmt);
1749   if (TREE_CODE (oprnd0) != SSA_NAME || TREE_CODE (oprnd1) != INTEGER_CST)
1750     return NULL;
1751
1752   /* Check operand 0: it has to be defined by a type promotion.  */
1753   if (!type_conversion_p (oprnd0, last_stmt, false, &half_type0, &def_stmt0,
1754                           &promotion)
1755       || !promotion)
1756      return NULL;
1757
1758   /* Check operand 1: has to be positive.  We check that it fits the type
1759      in vect_handle_widen_op_by_const ().  */
1760   if (tree_int_cst_compare (oprnd1, size_zero_node) <= 0)
1761     return NULL;
1762
1763   oprnd0 = gimple_assign_rhs1 (def_stmt0);
1764   type = gimple_expr_type (last_stmt);
1765
1766   /* Check for subsequent conversion to another type.  */
1767   use_stmt = vect_single_imm_use (last_stmt);
1768   if (use_stmt && is_gimple_assign (use_stmt)
1769       && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))
1770       && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
1771     {
1772       tree use_lhs = gimple_assign_lhs (use_stmt);
1773       tree use_type = TREE_TYPE (use_lhs);
1774
1775       if (INTEGRAL_TYPE_P (use_type)
1776           && TYPE_PRECISION (use_type) <= TYPE_PRECISION (type))
1777         {
1778           last_stmt = use_stmt;
1779           type = use_type;
1780         }
1781     }
1782
1783   /* Check if this a widening operation.  */
1784   gimple *wstmt = NULL;
1785   if (!vect_handle_widen_op_by_const (last_stmt, LSHIFT_EXPR, oprnd1,
1786                                       &oprnd0, &wstmt,
1787                                       type, &half_type0, def_stmt0))
1788     return NULL;
1789
1790   /* Pattern detected.  */
1791   if (dump_enabled_p ())
1792     dump_printf_loc (MSG_NOTE, vect_location,
1793                      "vect_recog_widen_shift_pattern: detected:\n");
1794
1795   /* Check target support.  */
1796   vectype = get_vectype_for_scalar_type (half_type0);
1797   vectype_out = get_vectype_for_scalar_type (type);
1798
1799   if (!vectype
1800       || !vectype_out
1801       || !supportable_widening_operation (WIDEN_LSHIFT_EXPR, last_stmt,
1802                                           vectype_out, vectype,
1803                                           &dummy_code, &dummy_code,
1804                                           &dummy_int, &dummy_vec))
1805     return NULL;
1806
1807   *type_in = vectype;
1808   *type_out = vectype_out;
1809
1810   /* Pattern supported.  Create a stmt to be used to replace the pattern.  */
1811   var = vect_recog_temp_ssa_var (type, NULL);
1812   pattern_stmt
1813     = gimple_build_assign (var, WIDEN_LSHIFT_EXPR, oprnd0, oprnd1);
1814   if (wstmt)
1815     {
1816       stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
1817       new_pattern_def_seq (stmt_vinfo, wstmt);
1818       stmt_vec_info new_stmt_info
1819         = new_stmt_vec_info (wstmt, stmt_vinfo->vinfo);
1820       set_vinfo_for_stmt (wstmt, new_stmt_info);
1821       STMT_VINFO_VECTYPE (new_stmt_info) = vectype;
1822     }
1823
1824   if (dump_enabled_p ())
1825     dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
1826
1827   stmts->safe_push (last_stmt);
1828   return pattern_stmt;
1829 }
1830
1831 /* Detect a rotate pattern wouldn't be otherwise vectorized:
1832
1833    type a_t, b_t, c_t;
1834
1835    S0 a_t = b_t r<< c_t;
1836
1837   Input/Output:
1838
1839   * STMTS: Contains a stmt from which the pattern search begins,
1840     i.e. the shift/rotate stmt.  The original stmt (S0) is replaced
1841     with a sequence:
1842
1843    S1 d_t = -c_t;
1844    S2 e_t = d_t & (B - 1);
1845    S3 f_t = b_t << c_t;
1846    S4 g_t = b_t >> e_t;
1847    S0 a_t = f_t | g_t;
1848
1849     where B is element bitsize of type.
1850
1851   Output:
1852
1853   * TYPE_IN: The type of the input arguments to the pattern.
1854
1855   * TYPE_OUT: The type of the output of this pattern.
1856
1857   * Return value: A new stmt that will be used to replace the rotate
1858     S0 stmt.  */
1859
1860 static gimple *
1861 vect_recog_rotate_pattern (vec<gimple *> *stmts, tree *type_in, tree *type_out)
1862 {
1863   gimple *last_stmt = stmts->pop ();
1864   tree oprnd0, oprnd1, lhs, var, var1, var2, vectype, type, stype, def, def2;
1865   gimple *pattern_stmt, *def_stmt;
1866   enum tree_code rhs_code;
1867   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
1868   vec_info *vinfo = stmt_vinfo->vinfo;
1869   enum vect_def_type dt;
1870   optab optab1, optab2;
1871   edge ext_def = NULL;
1872
1873   if (!is_gimple_assign (last_stmt))
1874     return NULL;
1875
1876   rhs_code = gimple_assign_rhs_code (last_stmt);
1877   switch (rhs_code)
1878     {
1879     case LROTATE_EXPR:
1880     case RROTATE_EXPR:
1881       break;
1882     default:
1883       return NULL;
1884     }
1885
1886   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
1887     return NULL;
1888
1889   lhs = gimple_assign_lhs (last_stmt);
1890   oprnd0 = gimple_assign_rhs1 (last_stmt);
1891   type = TREE_TYPE (oprnd0);
1892   oprnd1 = gimple_assign_rhs2 (last_stmt);
1893   if (TREE_CODE (oprnd0) != SSA_NAME
1894       || TYPE_PRECISION (TREE_TYPE (lhs)) != TYPE_PRECISION (type)
1895       || !INTEGRAL_TYPE_P (type)
1896       || !TYPE_UNSIGNED (type))
1897     return NULL;
1898
1899   if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
1900     return NULL;
1901
1902   if (dt != vect_internal_def
1903       && dt != vect_constant_def
1904       && dt != vect_external_def)
1905     return NULL;
1906
1907   vectype = get_vectype_for_scalar_type (type);
1908   if (vectype == NULL_TREE)
1909     return NULL;
1910
1911   /* If vector/vector or vector/scalar rotate is supported by the target,
1912      don't do anything here.  */
1913   optab1 = optab_for_tree_code (rhs_code, vectype, optab_vector);
1914   if (optab1
1915       && optab_handler (optab1, TYPE_MODE (vectype)) != CODE_FOR_nothing)
1916     return NULL;
1917
1918   if (is_a <bb_vec_info> (vinfo) || dt != vect_internal_def)
1919     {
1920       optab2 = optab_for_tree_code (rhs_code, vectype, optab_scalar);
1921       if (optab2
1922           && optab_handler (optab2, TYPE_MODE (vectype)) != CODE_FOR_nothing)
1923         return NULL;
1924     }
1925
1926   /* If vector/vector or vector/scalar shifts aren't supported by the target,
1927      don't do anything here either.  */
1928   optab1 = optab_for_tree_code (LSHIFT_EXPR, vectype, optab_vector);
1929   optab2 = optab_for_tree_code (RSHIFT_EXPR, vectype, optab_vector);
1930   if (!optab1
1931       || optab_handler (optab1, TYPE_MODE (vectype)) == CODE_FOR_nothing
1932       || !optab2
1933       || optab_handler (optab2, TYPE_MODE (vectype)) == CODE_FOR_nothing)
1934     {
1935       if (! is_a <bb_vec_info> (vinfo) && dt == vect_internal_def)
1936         return NULL;
1937       optab1 = optab_for_tree_code (LSHIFT_EXPR, vectype, optab_scalar);
1938       optab2 = optab_for_tree_code (RSHIFT_EXPR, vectype, optab_scalar);
1939       if (!optab1
1940           || optab_handler (optab1, TYPE_MODE (vectype)) == CODE_FOR_nothing
1941           || !optab2
1942           || optab_handler (optab2, TYPE_MODE (vectype)) == CODE_FOR_nothing)
1943         return NULL;
1944     }
1945
1946   *type_in = vectype;
1947   *type_out = vectype;
1948   if (*type_in == NULL_TREE)
1949     return NULL;
1950
1951   if (dt == vect_external_def
1952       && TREE_CODE (oprnd1) == SSA_NAME
1953       && is_a <loop_vec_info> (vinfo))
1954     {
1955       struct loop *loop = as_a <loop_vec_info> (vinfo)->loop;
1956       ext_def = loop_preheader_edge (loop);
1957       if (!SSA_NAME_IS_DEFAULT_DEF (oprnd1))
1958         {
1959           basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (oprnd1));
1960           if (bb == NULL
1961               || !dominated_by_p (CDI_DOMINATORS, ext_def->dest, bb))
1962             ext_def = NULL;
1963         }
1964     }
1965
1966   def = NULL_TREE;
1967   scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
1968   if (TREE_CODE (oprnd1) == INTEGER_CST
1969       || TYPE_MODE (TREE_TYPE (oprnd1)) == mode)
1970     def = oprnd1;
1971   else if (def_stmt && gimple_assign_cast_p (def_stmt))
1972     {
1973       tree rhs1 = gimple_assign_rhs1 (def_stmt);
1974       if (TYPE_MODE (TREE_TYPE (rhs1)) == mode
1975           && TYPE_PRECISION (TREE_TYPE (rhs1))
1976              == TYPE_PRECISION (type))
1977         def = rhs1;
1978     }
1979
1980   STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) = NULL;
1981   if (def == NULL_TREE)
1982     {
1983       def = vect_recog_temp_ssa_var (type, NULL);
1984       def_stmt = gimple_build_assign (def, NOP_EXPR, oprnd1);
1985       if (ext_def)
1986         {
1987           basic_block new_bb
1988             = gsi_insert_on_edge_immediate (ext_def, def_stmt);
1989           gcc_assert (!new_bb);
1990         }
1991       else
1992         append_pattern_def_seq (stmt_vinfo, def_stmt);
1993     }
1994   stype = TREE_TYPE (def);
1995   scalar_int_mode smode = SCALAR_INT_TYPE_MODE (stype);
1996
1997   if (TREE_CODE (def) == INTEGER_CST)
1998     {
1999       if (!tree_fits_uhwi_p (def)
2000           || tree_to_uhwi (def) >= GET_MODE_PRECISION (mode)
2001           || integer_zerop (def))
2002         return NULL;
2003       def2 = build_int_cst (stype,
2004                             GET_MODE_PRECISION (mode) - tree_to_uhwi (def));
2005     }
2006   else
2007     {
2008       tree vecstype = get_vectype_for_scalar_type (stype);
2009       stmt_vec_info def_stmt_vinfo;
2010
2011       if (vecstype == NULL_TREE)
2012         return NULL;
2013       def2 = vect_recog_temp_ssa_var (stype, NULL);
2014       def_stmt = gimple_build_assign (def2, NEGATE_EXPR, def);
2015       if (ext_def)
2016         {
2017           basic_block new_bb
2018             = gsi_insert_on_edge_immediate (ext_def, def_stmt);
2019           gcc_assert (!new_bb);
2020         }
2021       else
2022         {
2023           def_stmt_vinfo = new_stmt_vec_info (def_stmt, vinfo);
2024           set_vinfo_for_stmt (def_stmt, def_stmt_vinfo);
2025           STMT_VINFO_VECTYPE (def_stmt_vinfo) = vecstype;
2026           append_pattern_def_seq (stmt_vinfo, def_stmt);
2027         }
2028
2029       def2 = vect_recog_temp_ssa_var (stype, NULL);
2030       tree mask = build_int_cst (stype, GET_MODE_PRECISION (smode) - 1);
2031       def_stmt = gimple_build_assign (def2, BIT_AND_EXPR,
2032                                       gimple_assign_lhs (def_stmt), mask);
2033       if (ext_def)
2034         {
2035           basic_block new_bb
2036             = gsi_insert_on_edge_immediate (ext_def, def_stmt);
2037           gcc_assert (!new_bb);
2038         }
2039       else
2040         {
2041           def_stmt_vinfo = new_stmt_vec_info (def_stmt, vinfo);
2042           set_vinfo_for_stmt (def_stmt, def_stmt_vinfo);
2043           STMT_VINFO_VECTYPE (def_stmt_vinfo) = vecstype;
2044           append_pattern_def_seq (stmt_vinfo, def_stmt);
2045         }
2046     }
2047
2048   var1 = vect_recog_temp_ssa_var (type, NULL);
2049   def_stmt = gimple_build_assign (var1, rhs_code == LROTATE_EXPR
2050                                         ? LSHIFT_EXPR : RSHIFT_EXPR,
2051                                   oprnd0, def);
2052   append_pattern_def_seq (stmt_vinfo, def_stmt);
2053
2054   var2 = vect_recog_temp_ssa_var (type, NULL);
2055   def_stmt = gimple_build_assign (var2, rhs_code == LROTATE_EXPR
2056                                         ? RSHIFT_EXPR : LSHIFT_EXPR,
2057                                   oprnd0, def2);
2058   append_pattern_def_seq (stmt_vinfo, def_stmt);
2059
2060   /* Pattern detected.  */
2061   if (dump_enabled_p ())
2062     dump_printf_loc (MSG_NOTE, vect_location,
2063                      "vect_recog_rotate_pattern: detected:\n");
2064
2065   /* Pattern supported.  Create a stmt to be used to replace the pattern.  */
2066   var = vect_recog_temp_ssa_var (type, NULL);
2067   pattern_stmt = gimple_build_assign (var, BIT_IOR_EXPR, var1, var2);
2068
2069   if (dump_enabled_p ())
2070     dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
2071
2072   stmts->safe_push (last_stmt);
2073   return pattern_stmt;
2074 }
2075
2076 /* Detect a vector by vector shift pattern that wouldn't be otherwise
2077    vectorized:
2078
2079    type a_t;
2080    TYPE b_T, res_T;
2081
2082    S1 a_t = ;
2083    S2 b_T = ;
2084    S3 res_T = b_T op a_t;
2085
2086   where type 'TYPE' is a type with different size than 'type',
2087   and op is <<, >> or rotate.
2088
2089   Also detect cases:
2090
2091    type a_t;
2092    TYPE b_T, c_T, res_T;
2093
2094    S0 c_T = ;
2095    S1 a_t = (type) c_T;
2096    S2 b_T = ;
2097    S3 res_T = b_T op a_t;
2098
2099   Input/Output:
2100
2101   * STMTS: Contains a stmt from which the pattern search begins,
2102     i.e. the shift/rotate stmt.  The original stmt (S3) is replaced
2103     with a shift/rotate which has same type on both operands, in the
2104     second case just b_T op c_T, in the first case with added cast
2105     from a_t to c_T in STMT_VINFO_PATTERN_DEF_SEQ.
2106
2107   Output:
2108
2109   * TYPE_IN: The type of the input arguments to the pattern.
2110
2111   * TYPE_OUT: The type of the output of this pattern.
2112
2113   * Return value: A new stmt that will be used to replace the shift/rotate
2114     S3 stmt.  */
2115
2116 static gimple *
2117 vect_recog_vector_vector_shift_pattern (vec<gimple *> *stmts,
2118                                         tree *type_in, tree *type_out)
2119 {
2120   gimple *last_stmt = stmts->pop ();
2121   tree oprnd0, oprnd1, lhs, var;
2122   gimple *pattern_stmt, *def_stmt;
2123   enum tree_code rhs_code;
2124   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
2125   vec_info *vinfo = stmt_vinfo->vinfo;
2126   enum vect_def_type dt;
2127
2128   if (!is_gimple_assign (last_stmt))
2129     return NULL;
2130
2131   rhs_code = gimple_assign_rhs_code (last_stmt);
2132   switch (rhs_code)
2133     {
2134     case LSHIFT_EXPR:
2135     case RSHIFT_EXPR:
2136     case LROTATE_EXPR:
2137     case RROTATE_EXPR:
2138       break;
2139     default:
2140       return NULL;
2141     }
2142
2143   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
2144     return NULL;
2145
2146   lhs = gimple_assign_lhs (last_stmt);
2147   oprnd0 = gimple_assign_rhs1 (last_stmt);
2148   oprnd1 = gimple_assign_rhs2 (last_stmt);
2149   if (TREE_CODE (oprnd0) != SSA_NAME
2150       || TREE_CODE (oprnd1) != SSA_NAME
2151       || TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1))
2152       || !type_has_mode_precision_p (TREE_TYPE (oprnd1))
2153       || TYPE_PRECISION (TREE_TYPE (lhs))
2154          != TYPE_PRECISION (TREE_TYPE (oprnd0)))
2155     return NULL;
2156
2157   if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
2158     return NULL;
2159
2160   if (dt != vect_internal_def)
2161     return NULL;
2162
2163   *type_in = get_vectype_for_scalar_type (TREE_TYPE (oprnd0));
2164   *type_out = *type_in;
2165   if (*type_in == NULL_TREE)
2166     return NULL;
2167
2168   tree def = NULL_TREE;
2169   stmt_vec_info def_vinfo = vinfo_for_stmt (def_stmt);
2170   if (!STMT_VINFO_IN_PATTERN_P (def_vinfo) && gimple_assign_cast_p (def_stmt))
2171     {
2172       tree rhs1 = gimple_assign_rhs1 (def_stmt);
2173       if (TYPE_MODE (TREE_TYPE (rhs1)) == TYPE_MODE (TREE_TYPE (oprnd0))
2174           && TYPE_PRECISION (TREE_TYPE (rhs1))
2175              == TYPE_PRECISION (TREE_TYPE (oprnd0)))
2176         {
2177           if (TYPE_PRECISION (TREE_TYPE (oprnd1))
2178               >= TYPE_PRECISION (TREE_TYPE (rhs1)))
2179             def = rhs1;
2180           else
2181             {
2182               tree mask
2183                 = build_low_bits_mask (TREE_TYPE (rhs1),
2184                                        TYPE_PRECISION (TREE_TYPE (oprnd1)));
2185               def = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL);
2186               def_stmt = gimple_build_assign (def, BIT_AND_EXPR, rhs1, mask);
2187               new_pattern_def_seq (stmt_vinfo, def_stmt);
2188             }
2189         }
2190     }
2191
2192   if (def == NULL_TREE)
2193     {
2194       def = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
2195       def_stmt = gimple_build_assign (def, NOP_EXPR, oprnd1);
2196       new_pattern_def_seq (stmt_vinfo, def_stmt);
2197     }
2198
2199   /* Pattern detected.  */
2200   if (dump_enabled_p ())
2201     dump_printf_loc (MSG_NOTE, vect_location,
2202                      "vect_recog_vector_vector_shift_pattern: detected:\n");
2203
2204   /* Pattern supported.  Create a stmt to be used to replace the pattern.  */
2205   var = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
2206   pattern_stmt = gimple_build_assign (var, rhs_code, oprnd0, def);
2207
2208   if (dump_enabled_p ())
2209     dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
2210
2211   stmts->safe_push (last_stmt);
2212   return pattern_stmt;
2213 }
2214
2215 /* Return true iff the target has a vector optab implementing the operation
2216    CODE on type VECTYPE.  */
2217
2218 static bool
2219 target_has_vecop_for_code (tree_code code, tree vectype)
2220 {
2221   optab voptab = optab_for_tree_code (code, vectype, optab_vector);
2222   return voptab
2223          && optab_handler (voptab, TYPE_MODE (vectype)) != CODE_FOR_nothing;
2224 }
2225
2226 /* Verify that the target has optabs of VECTYPE to perform all the steps
2227    needed by the multiplication-by-immediate synthesis algorithm described by
2228    ALG and VAR.  If SYNTH_SHIFT_P is true ensure that vector addition is
2229    present.  Return true iff the target supports all the steps.  */
2230
2231 static bool
2232 target_supports_mult_synth_alg (struct algorithm *alg, mult_variant var,
2233                                  tree vectype, bool synth_shift_p)
2234 {
2235   if (alg->op[0] != alg_zero && alg->op[0] != alg_m)
2236     return false;
2237
2238   bool supports_vminus = target_has_vecop_for_code (MINUS_EXPR, vectype);
2239   bool supports_vplus = target_has_vecop_for_code (PLUS_EXPR, vectype);
2240
2241   if (var == negate_variant
2242       && !target_has_vecop_for_code (NEGATE_EXPR, vectype))
2243     return false;
2244
2245   /* If we must synthesize shifts with additions make sure that vector
2246      addition is available.  */
2247   if ((var == add_variant || synth_shift_p) && !supports_vplus)
2248     return false;
2249
2250   for (int i = 1; i < alg->ops; i++)
2251     {
2252       switch (alg->op[i])
2253         {
2254         case alg_shift:
2255           break;
2256         case alg_add_t_m2:
2257         case alg_add_t2_m:
2258         case alg_add_factor:
2259           if (!supports_vplus)
2260             return false;
2261           break;
2262         case alg_sub_t_m2:
2263         case alg_sub_t2_m:
2264         case alg_sub_factor:
2265           if (!supports_vminus)
2266             return false;
2267           break;
2268         case alg_unknown:
2269         case alg_m:
2270         case alg_zero:
2271         case alg_impossible:
2272           return false;
2273         default:
2274           gcc_unreachable ();
2275         }
2276     }
2277
2278   return true;
2279 }
2280
2281 /* Synthesize a left shift of OP by AMNT bits using a series of additions and
2282    putting the final result in DEST.  Append all statements but the last into
2283    VINFO.  Return the last statement.  */
2284
2285 static gimple *
2286 synth_lshift_by_additions (tree dest, tree op, HOST_WIDE_INT amnt,
2287                            stmt_vec_info vinfo)
2288 {
2289   HOST_WIDE_INT i;
2290   tree itype = TREE_TYPE (op);
2291   tree prev_res = op;
2292   gcc_assert (amnt >= 0);
2293   for (i = 0; i < amnt; i++)
2294     {
2295       tree tmp_var = (i < amnt - 1) ? vect_recog_temp_ssa_var (itype, NULL)
2296                       : dest;
2297       gimple *stmt
2298         = gimple_build_assign (tmp_var, PLUS_EXPR, prev_res, prev_res);
2299       prev_res = tmp_var;
2300       if (i < amnt - 1)
2301         append_pattern_def_seq (vinfo, stmt);
2302       else
2303         return stmt;
2304     }
2305   gcc_unreachable ();
2306   return NULL;
2307 }
2308
2309 /* Helper for vect_synth_mult_by_constant.  Apply a binary operation
2310    CODE to operands OP1 and OP2, creating a new temporary SSA var in
2311    the process if necessary.  Append the resulting assignment statements
2312    to the sequence in STMT_VINFO.  Return the SSA variable that holds the
2313    result of the binary operation.  If SYNTH_SHIFT_P is true synthesize
2314    left shifts using additions.  */
2315
2316 static tree
2317 apply_binop_and_append_stmt (tree_code code, tree op1, tree op2,
2318                              stmt_vec_info stmt_vinfo, bool synth_shift_p)
2319 {
2320   if (integer_zerop (op2)
2321       && (code == LSHIFT_EXPR
2322           || code == PLUS_EXPR))
2323     {
2324       gcc_assert (TREE_CODE (op1) == SSA_NAME);
2325       return op1;
2326     }
2327
2328   gimple *stmt;
2329   tree itype = TREE_TYPE (op1);
2330   tree tmp_var = vect_recog_temp_ssa_var (itype, NULL);
2331
2332   if (code == LSHIFT_EXPR
2333       && synth_shift_p)
2334     {
2335       stmt = synth_lshift_by_additions (tmp_var, op1, TREE_INT_CST_LOW (op2),
2336                                          stmt_vinfo);
2337       append_pattern_def_seq (stmt_vinfo, stmt);
2338       return tmp_var;
2339     }
2340
2341   stmt = gimple_build_assign (tmp_var, code, op1, op2);
2342   append_pattern_def_seq (stmt_vinfo, stmt);
2343   return tmp_var;
2344 }
2345
2346 /* Synthesize a multiplication of OP by an INTEGER_CST VAL using shifts
2347    and simple arithmetic operations to be vectorized.  Record the statements
2348    produced in STMT_VINFO and return the last statement in the sequence or
2349    NULL if it's not possible to synthesize such a multiplication.
2350    This function mirrors the behavior of expand_mult_const in expmed.c but
2351    works on tree-ssa form.  */
2352
2353 static gimple *
2354 vect_synth_mult_by_constant (tree op, tree val,
2355                              stmt_vec_info stmt_vinfo)
2356 {
2357   tree itype = TREE_TYPE (op);
2358   machine_mode mode = TYPE_MODE (itype);
2359   struct algorithm alg;
2360   mult_variant variant;
2361   if (!tree_fits_shwi_p (val))
2362     return NULL;
2363
2364   /* Multiplication synthesis by shifts, adds and subs can introduce
2365      signed overflow where the original operation didn't.  Perform the
2366      operations on an unsigned type and cast back to avoid this.
2367      In the future we may want to relax this for synthesis algorithms
2368      that we can prove do not cause unexpected overflow.  */
2369   bool cast_to_unsigned_p = !TYPE_OVERFLOW_WRAPS (itype);
2370
2371   tree multtype = cast_to_unsigned_p ? unsigned_type_for (itype) : itype;
2372
2373   /* Targets that don't support vector shifts but support vector additions
2374      can synthesize shifts that way.  */
2375   bool synth_shift_p = !vect_supportable_shift (LSHIFT_EXPR, multtype);
2376
2377   HOST_WIDE_INT hwval = tree_to_shwi (val);
2378   /* Use MAX_COST here as we don't want to limit the sequence on rtx costs.
2379      The vectorizer's benefit analysis will decide whether it's beneficial
2380      to do this.  */
2381   bool possible = choose_mult_variant (mode, hwval, &alg,
2382                                         &variant, MAX_COST);
2383   if (!possible)
2384     return NULL;
2385
2386   tree vectype = get_vectype_for_scalar_type (multtype);
2387
2388   if (!vectype
2389       || !target_supports_mult_synth_alg (&alg, variant,
2390                                            vectype, synth_shift_p))
2391     return NULL;
2392
2393   tree accumulator;
2394
2395   /* Clear out the sequence of statements so we can populate it below.  */
2396   STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) = NULL;
2397   gimple *stmt = NULL;
2398
2399   if (cast_to_unsigned_p)
2400     {
2401       tree tmp_op = vect_recog_temp_ssa_var (multtype, NULL);
2402       stmt = gimple_build_assign (tmp_op, CONVERT_EXPR, op);
2403       append_pattern_def_seq (stmt_vinfo, stmt);
2404       op = tmp_op;
2405     }
2406
2407   if (alg.op[0] == alg_zero)
2408     accumulator = build_int_cst (multtype, 0);
2409   else
2410     accumulator = op;
2411
2412   bool needs_fixup = (variant == negate_variant)
2413                       || (variant == add_variant);
2414
2415   for (int i = 1; i < alg.ops; i++)
2416     {
2417       tree shft_log = build_int_cst (multtype, alg.log[i]);
2418       tree accum_tmp = vect_recog_temp_ssa_var (multtype, NULL);
2419       tree tmp_var = NULL_TREE;
2420
2421       switch (alg.op[i])
2422         {
2423         case alg_shift:
2424           if (synth_shift_p)
2425             stmt
2426               = synth_lshift_by_additions (accum_tmp, accumulator, alg.log[i],
2427                                             stmt_vinfo);
2428           else
2429             stmt = gimple_build_assign (accum_tmp, LSHIFT_EXPR, accumulator,
2430                                          shft_log);
2431           break;
2432         case alg_add_t_m2:
2433           tmp_var
2434             = apply_binop_and_append_stmt (LSHIFT_EXPR, op, shft_log,
2435                                             stmt_vinfo, synth_shift_p);
2436           stmt = gimple_build_assign (accum_tmp, PLUS_EXPR, accumulator,
2437                                        tmp_var);
2438           break;
2439         case alg_sub_t_m2:
2440           tmp_var = apply_binop_and_append_stmt (LSHIFT_EXPR, op,
2441                                                   shft_log, stmt_vinfo,
2442                                                   synth_shift_p);
2443           /* In some algorithms the first step involves zeroing the
2444              accumulator.  If subtracting from such an accumulator
2445              just emit the negation directly.  */
2446           if (integer_zerop (accumulator))
2447             stmt = gimple_build_assign (accum_tmp, NEGATE_EXPR, tmp_var);
2448           else
2449             stmt = gimple_build_assign (accum_tmp, MINUS_EXPR, accumulator,
2450                                         tmp_var);
2451           break;
2452         case alg_add_t2_m:
2453           tmp_var
2454             = apply_binop_and_append_stmt (LSHIFT_EXPR, accumulator, shft_log,
2455                                            stmt_vinfo, synth_shift_p);
2456           stmt = gimple_build_assign (accum_tmp, PLUS_EXPR, tmp_var, op);
2457           break;
2458         case alg_sub_t2_m:
2459           tmp_var
2460             = apply_binop_and_append_stmt (LSHIFT_EXPR, accumulator, shft_log,
2461                                            stmt_vinfo, synth_shift_p);
2462           stmt = gimple_build_assign (accum_tmp, MINUS_EXPR, tmp_var, op);
2463           break;
2464         case alg_add_factor:
2465           tmp_var
2466             = apply_binop_and_append_stmt (LSHIFT_EXPR, accumulator, shft_log,
2467                                             stmt_vinfo, synth_shift_p);
2468           stmt = gimple_build_assign (accum_tmp, PLUS_EXPR, accumulator,
2469                                        tmp_var);
2470           break;
2471         case alg_sub_factor:
2472           tmp_var
2473             = apply_binop_and_append_stmt (LSHIFT_EXPR, accumulator, shft_log,
2474                                            stmt_vinfo, synth_shift_p);
2475           stmt = gimple_build_assign (accum_tmp, MINUS_EXPR, tmp_var,
2476                                       accumulator);
2477           break;
2478         default:
2479           gcc_unreachable ();
2480         }
2481       /* We don't want to append the last stmt in the sequence to stmt_vinfo
2482          but rather return it directly.  */
2483
2484       if ((i < alg.ops - 1) || needs_fixup || cast_to_unsigned_p)
2485         append_pattern_def_seq (stmt_vinfo, stmt);
2486       accumulator = accum_tmp;
2487     }
2488   if (variant == negate_variant)
2489     {
2490       tree accum_tmp = vect_recog_temp_ssa_var (multtype, NULL);
2491       stmt = gimple_build_assign (accum_tmp, NEGATE_EXPR, accumulator);
2492       accumulator = accum_tmp;
2493       if (cast_to_unsigned_p)
2494         append_pattern_def_seq (stmt_vinfo, stmt);
2495     }
2496   else if (variant == add_variant)
2497     {
2498       tree accum_tmp = vect_recog_temp_ssa_var (multtype, NULL);
2499       stmt = gimple_build_assign (accum_tmp, PLUS_EXPR, accumulator, op);
2500       accumulator = accum_tmp;
2501       if (cast_to_unsigned_p)
2502         append_pattern_def_seq (stmt_vinfo, stmt);
2503     }
2504   /* Move back to a signed if needed.  */
2505   if (cast_to_unsigned_p)
2506     {
2507       tree accum_tmp = vect_recog_temp_ssa_var (itype, NULL);
2508       stmt = gimple_build_assign (accum_tmp, CONVERT_EXPR, accumulator);
2509     }
2510
2511   return stmt;
2512 }
2513
2514 /* Detect multiplication by constant and convert it into a sequence of
2515    shifts and additions, subtractions, negations.  We reuse the
2516    choose_mult_variant algorithms from expmed.c
2517
2518    Input/Output:
2519
2520    STMTS: Contains a stmt from which the pattern search begins,
2521    i.e. the mult stmt.
2522
2523  Output:
2524
2525   * TYPE_IN: The type of the input arguments to the pattern.
2526
2527   * TYPE_OUT: The type of the output of this pattern.
2528
2529   * Return value: A new stmt that will be used to replace
2530     the multiplication.  */
2531
2532 static gimple *
2533 vect_recog_mult_pattern (vec<gimple *> *stmts,
2534                          tree *type_in, tree *type_out)
2535 {
2536   gimple *last_stmt = stmts->pop ();
2537   tree oprnd0, oprnd1, vectype, itype;
2538   gimple *pattern_stmt;
2539   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
2540
2541   if (!is_gimple_assign (last_stmt))
2542     return NULL;
2543
2544   if (gimple_assign_rhs_code (last_stmt) != MULT_EXPR)
2545     return NULL;
2546
2547   oprnd0 = gimple_assign_rhs1 (last_stmt);
2548   oprnd1 = gimple_assign_rhs2 (last_stmt);
2549   itype = TREE_TYPE (oprnd0);
2550
2551   if (TREE_CODE (oprnd0) != SSA_NAME
2552       || TREE_CODE (oprnd1) != INTEGER_CST
2553       || !INTEGRAL_TYPE_P (itype)
2554       || !type_has_mode_precision_p (itype))
2555     return NULL;
2556
2557   vectype = get_vectype_for_scalar_type (itype);
2558   if (vectype == NULL_TREE)
2559     return NULL;
2560
2561   /* If the target can handle vectorized multiplication natively,
2562      don't attempt to optimize this.  */
2563   optab mul_optab = optab_for_tree_code (MULT_EXPR, vectype, optab_default);
2564   if (mul_optab != unknown_optab)
2565     {
2566       machine_mode vec_mode = TYPE_MODE (vectype);
2567       int icode = (int) optab_handler (mul_optab, vec_mode);
2568       if (icode != CODE_FOR_nothing)
2569        return NULL;
2570     }
2571
2572   pattern_stmt = vect_synth_mult_by_constant (oprnd0, oprnd1, stmt_vinfo);
2573   if (!pattern_stmt)
2574     return NULL;
2575
2576   /* Pattern detected.  */
2577   if (dump_enabled_p ())
2578     dump_printf_loc (MSG_NOTE, vect_location,
2579                      "vect_recog_mult_pattern: detected:\n");
2580
2581   if (dump_enabled_p ())
2582     dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM,
2583                           pattern_stmt,0);
2584
2585   stmts->safe_push (last_stmt);
2586   *type_in = vectype;
2587   *type_out = vectype;
2588
2589   return pattern_stmt;
2590 }
2591
2592 /* Detect a signed division by a constant that wouldn't be
2593    otherwise vectorized:
2594
2595    type a_t, b_t;
2596
2597    S1 a_t = b_t / N;
2598
2599   where type 'type' is an integral type and N is a constant.
2600
2601   Similarly handle modulo by a constant:
2602
2603    S4 a_t = b_t % N;
2604
2605   Input/Output:
2606
2607   * STMTS: Contains a stmt from which the pattern search begins,
2608     i.e. the division stmt.  S1 is replaced by if N is a power
2609     of two constant and type is signed:
2610   S3  y_t = b_t < 0 ? N - 1 : 0;
2611   S2  x_t = b_t + y_t;
2612   S1' a_t = x_t >> log2 (N);
2613
2614     S4 is replaced if N is a power of two constant and
2615     type is signed by (where *_T temporaries have unsigned type):
2616   S9  y_T = b_t < 0 ? -1U : 0U;
2617   S8  z_T = y_T >> (sizeof (type_t) * CHAR_BIT - log2 (N));
2618   S7  z_t = (type) z_T;
2619   S6  w_t = b_t + z_t;
2620   S5  x_t = w_t & (N - 1);
2621   S4' a_t = x_t - z_t;
2622
2623   Output:
2624
2625   * TYPE_IN: The type of the input arguments to the pattern.
2626
2627   * TYPE_OUT: The type of the output of this pattern.
2628
2629   * Return value: A new stmt that will be used to replace the division
2630     S1 or modulo S4 stmt.  */
2631
2632 static gimple *
2633 vect_recog_divmod_pattern (vec<gimple *> *stmts,
2634                            tree *type_in, tree *type_out)
2635 {
2636   gimple *last_stmt = stmts->pop ();
2637   tree oprnd0, oprnd1, vectype, itype, cond;
2638   gimple *pattern_stmt, *def_stmt;
2639   enum tree_code rhs_code;
2640   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
2641   vec_info *vinfo = stmt_vinfo->vinfo;
2642   optab optab;
2643   tree q;
2644   int dummy_int, prec;
2645   stmt_vec_info def_stmt_vinfo;
2646
2647   if (!is_gimple_assign (last_stmt))
2648     return NULL;
2649
2650   rhs_code = gimple_assign_rhs_code (last_stmt);
2651   switch (rhs_code)
2652     {
2653     case TRUNC_DIV_EXPR:
2654     case TRUNC_MOD_EXPR:
2655       break;
2656     default:
2657       return NULL;
2658     }
2659
2660   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
2661     return NULL;
2662
2663   oprnd0 = gimple_assign_rhs1 (last_stmt);
2664   oprnd1 = gimple_assign_rhs2 (last_stmt);
2665   itype = TREE_TYPE (oprnd0);
2666   if (TREE_CODE (oprnd0) != SSA_NAME
2667       || TREE_CODE (oprnd1) != INTEGER_CST
2668       || TREE_CODE (itype) != INTEGER_TYPE
2669       || !type_has_mode_precision_p (itype))
2670     return NULL;
2671
2672   scalar_int_mode itype_mode = SCALAR_INT_TYPE_MODE (itype);
2673   vectype = get_vectype_for_scalar_type (itype);
2674   if (vectype == NULL_TREE)
2675     return NULL;
2676
2677   /* If the target can handle vectorized division or modulo natively,
2678      don't attempt to optimize this.  */
2679   optab = optab_for_tree_code (rhs_code, vectype, optab_default);
2680   if (optab != unknown_optab)
2681     {
2682       machine_mode vec_mode = TYPE_MODE (vectype);
2683       int icode = (int) optab_handler (optab, vec_mode);
2684       if (icode != CODE_FOR_nothing)
2685         return NULL;
2686     }
2687
2688   prec = TYPE_PRECISION (itype);
2689   if (integer_pow2p (oprnd1))
2690     {
2691       if (TYPE_UNSIGNED (itype) || tree_int_cst_sgn (oprnd1) != 1)
2692         return NULL;
2693
2694       /* Pattern detected.  */
2695       if (dump_enabled_p ())
2696         dump_printf_loc (MSG_NOTE, vect_location,
2697                          "vect_recog_divmod_pattern: detected:\n");
2698
2699       cond = build2 (LT_EXPR, boolean_type_node, oprnd0,
2700                      build_int_cst (itype, 0));
2701       if (rhs_code == TRUNC_DIV_EXPR)
2702         {
2703           tree var = vect_recog_temp_ssa_var (itype, NULL);
2704           tree shift;
2705           def_stmt
2706             = gimple_build_assign (var, COND_EXPR, cond,
2707                                    fold_build2 (MINUS_EXPR, itype, oprnd1,
2708                                                 build_int_cst (itype, 1)),
2709                                    build_int_cst (itype, 0));
2710           new_pattern_def_seq (stmt_vinfo, def_stmt);
2711           var = vect_recog_temp_ssa_var (itype, NULL);
2712           def_stmt
2713             = gimple_build_assign (var, PLUS_EXPR, oprnd0,
2714                                    gimple_assign_lhs (def_stmt));
2715           append_pattern_def_seq (stmt_vinfo, def_stmt);
2716
2717           shift = build_int_cst (itype, tree_log2 (oprnd1));
2718           pattern_stmt
2719             = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
2720                                    RSHIFT_EXPR, var, shift);
2721         }
2722       else
2723         {
2724           tree signmask;
2725           STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) = NULL;
2726           if (compare_tree_int (oprnd1, 2) == 0)
2727             {
2728               signmask = vect_recog_temp_ssa_var (itype, NULL);
2729               def_stmt = gimple_build_assign (signmask, COND_EXPR, cond,
2730                                               build_int_cst (itype, 1),
2731                                               build_int_cst (itype, 0));
2732               append_pattern_def_seq (stmt_vinfo, def_stmt);
2733             }
2734           else
2735             {
2736               tree utype
2737                 = build_nonstandard_integer_type (prec, 1);
2738               tree vecutype = get_vectype_for_scalar_type (utype);
2739               tree shift
2740                 = build_int_cst (utype, GET_MODE_BITSIZE (itype_mode)
2741                                         - tree_log2 (oprnd1));
2742               tree var = vect_recog_temp_ssa_var (utype, NULL);
2743
2744               def_stmt = gimple_build_assign (var, COND_EXPR, cond,
2745                                               build_int_cst (utype, -1),
2746                                               build_int_cst (utype, 0));
2747               def_stmt_vinfo = new_stmt_vec_info (def_stmt, vinfo);
2748               set_vinfo_for_stmt (def_stmt, def_stmt_vinfo);
2749               STMT_VINFO_VECTYPE (def_stmt_vinfo) = vecutype;
2750               append_pattern_def_seq (stmt_vinfo, def_stmt);
2751               var = vect_recog_temp_ssa_var (utype, NULL);
2752               def_stmt = gimple_build_assign (var, RSHIFT_EXPR,
2753                                               gimple_assign_lhs (def_stmt),
2754                                               shift);
2755               def_stmt_vinfo = new_stmt_vec_info (def_stmt, vinfo);
2756               set_vinfo_for_stmt (def_stmt, def_stmt_vinfo);
2757               STMT_VINFO_VECTYPE (def_stmt_vinfo) = vecutype;
2758               append_pattern_def_seq (stmt_vinfo, def_stmt);
2759               signmask = vect_recog_temp_ssa_var (itype, NULL);
2760               def_stmt
2761                 = gimple_build_assign (signmask, NOP_EXPR, var);
2762               append_pattern_def_seq (stmt_vinfo, def_stmt);
2763             }
2764           def_stmt
2765             = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
2766                                    PLUS_EXPR, oprnd0, signmask);
2767           append_pattern_def_seq (stmt_vinfo, def_stmt);
2768           def_stmt
2769             = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
2770                                    BIT_AND_EXPR, gimple_assign_lhs (def_stmt),
2771                                    fold_build2 (MINUS_EXPR, itype, oprnd1,
2772                                                 build_int_cst (itype, 1)));
2773           append_pattern_def_seq (stmt_vinfo, def_stmt);
2774
2775           pattern_stmt
2776             = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
2777                                    MINUS_EXPR, gimple_assign_lhs (def_stmt),
2778                                    signmask);
2779         }
2780
2781       if (dump_enabled_p ())
2782         dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt,
2783                               0);
2784
2785       stmts->safe_push (last_stmt);
2786
2787       *type_in = vectype;
2788       *type_out = vectype;
2789       return pattern_stmt;
2790     }
2791
2792   if (prec > HOST_BITS_PER_WIDE_INT
2793       || integer_zerop (oprnd1))
2794     return NULL;
2795
2796   if (!can_mult_highpart_p (TYPE_MODE (vectype), TYPE_UNSIGNED (itype)))
2797     return NULL;
2798
2799   STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) = NULL;
2800
2801   if (TYPE_UNSIGNED (itype))
2802     {
2803       unsigned HOST_WIDE_INT mh, ml;
2804       int pre_shift, post_shift;
2805       unsigned HOST_WIDE_INT d = (TREE_INT_CST_LOW (oprnd1)
2806                                   & GET_MODE_MASK (itype_mode));
2807       tree t1, t2, t3, t4;
2808
2809       if (d >= (HOST_WIDE_INT_1U << (prec - 1)))
2810         /* FIXME: Can transform this into oprnd0 >= oprnd1 ? 1 : 0.  */
2811         return NULL;
2812
2813       /* Find a suitable multiplier and right shift count
2814          instead of multiplying with D.  */
2815       mh = choose_multiplier (d, prec, prec, &ml, &post_shift, &dummy_int);
2816
2817       /* If the suggested multiplier is more than SIZE bits, we can do better
2818          for even divisors, using an initial right shift.  */
2819       if (mh != 0 && (d & 1) == 0)
2820         {
2821           pre_shift = ctz_or_zero (d);
2822           mh = choose_multiplier (d >> pre_shift, prec, prec - pre_shift,
2823                                   &ml, &post_shift, &dummy_int);
2824           gcc_assert (!mh);
2825         }
2826       else
2827         pre_shift = 0;
2828
2829       if (mh != 0)
2830         {
2831           if (post_shift - 1 >= prec)
2832             return NULL;
2833
2834           /* t1 = oprnd0 h* ml;
2835              t2 = oprnd0 - t1;
2836              t3 = t2 >> 1;
2837              t4 = t1 + t3;
2838              q = t4 >> (post_shift - 1);  */
2839           t1 = vect_recog_temp_ssa_var (itype, NULL);
2840           def_stmt = gimple_build_assign (t1, MULT_HIGHPART_EXPR, oprnd0,
2841                                           build_int_cst (itype, ml));
2842           append_pattern_def_seq (stmt_vinfo, def_stmt);
2843
2844           t2 = vect_recog_temp_ssa_var (itype, NULL);
2845           def_stmt
2846             = gimple_build_assign (t2, MINUS_EXPR, oprnd0, t1);
2847           append_pattern_def_seq (stmt_vinfo, def_stmt);
2848
2849           t3 = vect_recog_temp_ssa_var (itype, NULL);
2850           def_stmt
2851             = gimple_build_assign (t3, RSHIFT_EXPR, t2, integer_one_node);
2852           append_pattern_def_seq (stmt_vinfo, def_stmt);
2853
2854           t4 = vect_recog_temp_ssa_var (itype, NULL);
2855           def_stmt
2856             = gimple_build_assign (t4, PLUS_EXPR, t1, t3);
2857
2858           if (post_shift != 1)
2859             {
2860               append_pattern_def_seq (stmt_vinfo, def_stmt);
2861
2862               q = vect_recog_temp_ssa_var (itype, NULL);
2863               pattern_stmt
2864                 = gimple_build_assign (q, RSHIFT_EXPR, t4,
2865                                        build_int_cst (itype, post_shift - 1));
2866             }
2867           else
2868             {
2869               q = t4;
2870               pattern_stmt = def_stmt;
2871             }
2872         }
2873       else
2874         {
2875           if (pre_shift >= prec || post_shift >= prec)
2876             return NULL;
2877
2878           /* t1 = oprnd0 >> pre_shift;
2879              t2 = t1 h* ml;
2880              q = t2 >> post_shift;  */
2881           if (pre_shift)
2882             {
2883               t1 = vect_recog_temp_ssa_var (itype, NULL);
2884               def_stmt
2885                 = gimple_build_assign (t1, RSHIFT_EXPR, oprnd0,
2886                                        build_int_cst (NULL, pre_shift));
2887               append_pattern_def_seq (stmt_vinfo, def_stmt);
2888             }
2889           else
2890             t1 = oprnd0;
2891
2892           t2 = vect_recog_temp_ssa_var (itype, NULL);
2893           def_stmt = gimple_build_assign (t2, MULT_HIGHPART_EXPR, t1,
2894                                           build_int_cst (itype, ml));
2895
2896           if (post_shift)
2897             {
2898               append_pattern_def_seq (stmt_vinfo, def_stmt);
2899
2900               q = vect_recog_temp_ssa_var (itype, NULL);
2901               def_stmt
2902                 = gimple_build_assign (q, RSHIFT_EXPR, t2,
2903                                        build_int_cst (itype, post_shift));
2904             }
2905           else
2906             q = t2;
2907
2908           pattern_stmt = def_stmt;
2909         }
2910     }
2911   else
2912     {
2913       unsigned HOST_WIDE_INT ml;
2914       int post_shift;
2915       HOST_WIDE_INT d = TREE_INT_CST_LOW (oprnd1);
2916       unsigned HOST_WIDE_INT abs_d;
2917       bool add = false;
2918       tree t1, t2, t3, t4;
2919
2920       /* Give up for -1.  */
2921       if (d == -1)
2922         return NULL;
2923
2924       /* Since d might be INT_MIN, we have to cast to
2925          unsigned HOST_WIDE_INT before negating to avoid
2926          undefined signed overflow.  */
2927       abs_d = (d >= 0
2928                ? (unsigned HOST_WIDE_INT) d
2929                : - (unsigned HOST_WIDE_INT) d);
2930
2931       /* n rem d = n rem -d */
2932       if (rhs_code == TRUNC_MOD_EXPR && d < 0)
2933         {
2934           d = abs_d;
2935           oprnd1 = build_int_cst (itype, abs_d);
2936         }
2937       else if (HOST_BITS_PER_WIDE_INT >= prec
2938                && abs_d == HOST_WIDE_INT_1U << (prec - 1))
2939         /* This case is not handled correctly below.  */
2940         return NULL;
2941
2942       choose_multiplier (abs_d, prec, prec - 1, &ml, &post_shift, &dummy_int);
2943       if (ml >= HOST_WIDE_INT_1U << (prec - 1))
2944         {
2945           add = true;
2946           ml |= HOST_WIDE_INT_M1U << (prec - 1);
2947         }
2948       if (post_shift >= prec)
2949         return NULL;
2950
2951       /* t1 = oprnd0 h* ml;  */
2952       t1 = vect_recog_temp_ssa_var (itype, NULL);
2953       def_stmt = gimple_build_assign (t1, MULT_HIGHPART_EXPR, oprnd0,
2954                                       build_int_cst (itype, ml));
2955
2956       if (add)
2957         {
2958           /* t2 = t1 + oprnd0;  */
2959           append_pattern_def_seq (stmt_vinfo, def_stmt);
2960           t2 = vect_recog_temp_ssa_var (itype, NULL);
2961           def_stmt = gimple_build_assign (t2, PLUS_EXPR, t1, oprnd0);
2962         }
2963       else
2964         t2 = t1;
2965
2966       if (post_shift)
2967         {
2968           /* t3 = t2 >> post_shift;  */
2969           append_pattern_def_seq (stmt_vinfo, def_stmt);
2970           t3 = vect_recog_temp_ssa_var (itype, NULL);
2971           def_stmt = gimple_build_assign (t3, RSHIFT_EXPR, t2,
2972                                           build_int_cst (itype, post_shift));
2973         }
2974       else
2975         t3 = t2;
2976
2977       wide_int oprnd0_min, oprnd0_max;
2978       int msb = 1;
2979       if (get_range_info (oprnd0, &oprnd0_min, &oprnd0_max) == VR_RANGE)
2980         {
2981           if (!wi::neg_p (oprnd0_min, TYPE_SIGN (itype)))
2982             msb = 0;
2983           else if (wi::neg_p (oprnd0_max, TYPE_SIGN (itype)))
2984             msb = -1;
2985         }
2986
2987       if (msb == 0 && d >= 0)
2988         {
2989           /* q = t3;  */
2990           q = t3;
2991           pattern_stmt = def_stmt;
2992         }
2993       else
2994         {
2995           /* t4 = oprnd0 >> (prec - 1);
2996              or if we know from VRP that oprnd0 >= 0
2997              t4 = 0;
2998              or if we know from VRP that oprnd0 < 0
2999              t4 = -1;  */
3000           append_pattern_def_seq (stmt_vinfo, def_stmt);
3001           t4 = vect_recog_temp_ssa_var (itype, NULL);
3002           if (msb != 1)
3003             def_stmt = gimple_build_assign (t4, INTEGER_CST,
3004                                             build_int_cst (itype, msb));
3005           else
3006             def_stmt = gimple_build_assign (t4, RSHIFT_EXPR, oprnd0,
3007                                             build_int_cst (itype, prec - 1));
3008           append_pattern_def_seq (stmt_vinfo, def_stmt);
3009
3010           /* q = t3 - t4;  or q = t4 - t3;  */
3011           q = vect_recog_temp_ssa_var (itype, NULL);
3012           pattern_stmt = gimple_build_assign (q, MINUS_EXPR, d < 0 ? t4 : t3,
3013                                               d < 0 ? t3 : t4);
3014         }
3015     }
3016
3017   if (rhs_code == TRUNC_MOD_EXPR)
3018     {
3019       tree r, t1;
3020
3021       /* We divided.  Now finish by:
3022          t1 = q * oprnd1;
3023          r = oprnd0 - t1;  */
3024       append_pattern_def_seq (stmt_vinfo, pattern_stmt);
3025
3026       t1 = vect_recog_temp_ssa_var (itype, NULL);
3027       def_stmt = gimple_build_assign (t1, MULT_EXPR, q, oprnd1);
3028       append_pattern_def_seq (stmt_vinfo, def_stmt);
3029
3030       r = vect_recog_temp_ssa_var (itype, NULL);
3031       pattern_stmt = gimple_build_assign (r, MINUS_EXPR, oprnd0, t1);
3032     }
3033
3034   /* Pattern detected.  */
3035   if (dump_enabled_p ())
3036     {
3037       dump_printf_loc (MSG_NOTE, vect_location,
3038                        "vect_recog_divmod_pattern: detected: ");
3039       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
3040     }
3041
3042   stmts->safe_push (last_stmt);
3043
3044   *type_in = vectype;
3045   *type_out = vectype;
3046   return pattern_stmt;
3047 }
3048
3049 /* Function vect_recog_mixed_size_cond_pattern
3050
3051    Try to find the following pattern:
3052
3053      type x_t, y_t;
3054      TYPE a_T, b_T, c_T;
3055    loop:
3056      S1  a_T = x_t CMP y_t ? b_T : c_T;
3057
3058    where type 'TYPE' is an integral type which has different size
3059    from 'type'.  b_T and c_T are either constants (and if 'TYPE' is wider
3060    than 'type', the constants need to fit into an integer type
3061    with the same width as 'type') or results of conversion from 'type'.
3062
3063    Input:
3064
3065    * LAST_STMT: A stmt from which the pattern search begins.
3066
3067    Output:
3068
3069    * TYPE_IN: The type of the input arguments to the pattern.
3070
3071    * TYPE_OUT: The type of the output of this pattern.
3072
3073    * Return value: A new stmt that will be used to replace the pattern.
3074         Additionally a def_stmt is added.
3075
3076         a_it = x_t CMP y_t ? b_it : c_it;
3077         a_T = (TYPE) a_it;  */
3078
3079 static gimple *
3080 vect_recog_mixed_size_cond_pattern (vec<gimple *> *stmts, tree *type_in,
3081                                     tree *type_out)
3082 {
3083   gimple *last_stmt = (*stmts)[0];
3084   tree cond_expr, then_clause, else_clause;
3085   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt), def_stmt_info;
3086   tree type, vectype, comp_vectype, itype = NULL_TREE, vecitype;
3087   gimple *pattern_stmt, *def_stmt;
3088   vec_info *vinfo = stmt_vinfo->vinfo;
3089   tree orig_type0 = NULL_TREE, orig_type1 = NULL_TREE;
3090   gimple *def_stmt0 = NULL, *def_stmt1 = NULL;
3091   bool promotion;
3092   tree comp_scalar_type;
3093
3094   if (!is_gimple_assign (last_stmt)
3095       || gimple_assign_rhs_code (last_stmt) != COND_EXPR
3096       || STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_internal_def)
3097     return NULL;
3098
3099   cond_expr = gimple_assign_rhs1 (last_stmt);
3100   then_clause = gimple_assign_rhs2 (last_stmt);
3101   else_clause = gimple_assign_rhs3 (last_stmt);
3102
3103   if (!COMPARISON_CLASS_P (cond_expr))
3104     return NULL;
3105
3106   comp_scalar_type = TREE_TYPE (TREE_OPERAND (cond_expr, 0));
3107   comp_vectype = get_vectype_for_scalar_type (comp_scalar_type);
3108   if (comp_vectype == NULL_TREE)
3109     return NULL;
3110
3111   type = gimple_expr_type (last_stmt);
3112   if (types_compatible_p (type, comp_scalar_type)
3113       || ((TREE_CODE (then_clause) != INTEGER_CST
3114            || TREE_CODE (else_clause) != INTEGER_CST)
3115           && !INTEGRAL_TYPE_P (comp_scalar_type))
3116       || !INTEGRAL_TYPE_P (type))
3117     return NULL;
3118
3119   if ((TREE_CODE (then_clause) != INTEGER_CST
3120        && !type_conversion_p (then_clause, last_stmt, false, &orig_type0,
3121                               &def_stmt0, &promotion))
3122       || (TREE_CODE (else_clause) != INTEGER_CST
3123           && !type_conversion_p (else_clause, last_stmt, false, &orig_type1,
3124                                  &def_stmt1, &promotion)))
3125     return NULL;
3126
3127   if (orig_type0 && orig_type1
3128       && !types_compatible_p (orig_type0, orig_type1))
3129     return NULL;
3130
3131   if (orig_type0)
3132     {
3133       if (!types_compatible_p (orig_type0, comp_scalar_type))
3134         return NULL;
3135       then_clause = gimple_assign_rhs1 (def_stmt0);
3136       itype = orig_type0;
3137     }
3138
3139   if (orig_type1)
3140     {
3141       if (!types_compatible_p (orig_type1, comp_scalar_type))
3142         return NULL;
3143       else_clause = gimple_assign_rhs1 (def_stmt1);
3144       itype = orig_type1;
3145     }
3146
3147
3148   HOST_WIDE_INT cmp_mode_size
3149     = GET_MODE_UNIT_BITSIZE (TYPE_MODE (comp_vectype));
3150
3151   scalar_int_mode type_mode = SCALAR_INT_TYPE_MODE (type);
3152   if (GET_MODE_BITSIZE (type_mode) == cmp_mode_size)
3153     return NULL;
3154
3155   vectype = get_vectype_for_scalar_type (type);
3156   if (vectype == NULL_TREE)
3157     return NULL;
3158
3159   if (expand_vec_cond_expr_p (vectype, comp_vectype, TREE_CODE (cond_expr)))
3160     return NULL;
3161
3162   if (itype == NULL_TREE)
3163     itype = build_nonstandard_integer_type (cmp_mode_size,
3164                                             TYPE_UNSIGNED (type));
3165
3166   if (itype == NULL_TREE
3167       || GET_MODE_BITSIZE (SCALAR_TYPE_MODE (itype)) != cmp_mode_size)
3168     return NULL;
3169
3170   vecitype = get_vectype_for_scalar_type (itype);
3171   if (vecitype == NULL_TREE)
3172     return NULL;
3173
3174   if (!expand_vec_cond_expr_p (vecitype, comp_vectype, TREE_CODE (cond_expr)))
3175     return NULL;
3176
3177   if (GET_MODE_BITSIZE (type_mode) > cmp_mode_size)
3178     {
3179       if ((TREE_CODE (then_clause) == INTEGER_CST
3180            && !int_fits_type_p (then_clause, itype))
3181           || (TREE_CODE (else_clause) == INTEGER_CST
3182               && !int_fits_type_p (else_clause, itype)))
3183         return NULL;
3184     }
3185
3186   def_stmt = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
3187                                   COND_EXPR, unshare_expr (cond_expr),
3188                                   fold_convert (itype, then_clause),
3189                                   fold_convert (itype, else_clause));
3190   pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (type, NULL),
3191                                       NOP_EXPR, gimple_assign_lhs (def_stmt));
3192
3193   new_pattern_def_seq (stmt_vinfo, def_stmt);
3194   def_stmt_info = new_stmt_vec_info (def_stmt, vinfo);
3195   set_vinfo_for_stmt (def_stmt, def_stmt_info);
3196   STMT_VINFO_VECTYPE (def_stmt_info) = vecitype;
3197   *type_in = vecitype;
3198   *type_out = vectype;
3199
3200   if (dump_enabled_p ())
3201     dump_printf_loc (MSG_NOTE, vect_location,
3202                      "vect_recog_mixed_size_cond_pattern: detected:\n");
3203
3204   return pattern_stmt;
3205 }
3206
3207
3208 /* Helper function of vect_recog_bool_pattern.  Called recursively, return
3209    true if bool VAR can and should be optimized that way.  Assume it shouldn't
3210    in case it's a result of a comparison which can be directly vectorized into
3211    a vector comparison.  Fills in STMTS with all stmts visited during the
3212    walk.  */
3213
3214 static bool
3215 check_bool_pattern (tree var, vec_info *vinfo, hash_set<gimple *> &stmts)
3216 {
3217   gimple *def_stmt;
3218   enum vect_def_type dt;
3219   tree rhs1;
3220   enum tree_code rhs_code;
3221
3222   if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
3223     return false;
3224
3225   if (dt != vect_internal_def)
3226     return false;
3227
3228   if (!is_gimple_assign (def_stmt))
3229     return false;
3230
3231   if (stmts.contains (def_stmt))
3232     return true;
3233
3234   rhs1 = gimple_assign_rhs1 (def_stmt);
3235   rhs_code = gimple_assign_rhs_code (def_stmt);
3236   switch (rhs_code)
3237     {
3238     case SSA_NAME:
3239       if (! check_bool_pattern (rhs1, vinfo, stmts))
3240         return false;
3241       break;
3242
3243     CASE_CONVERT:
3244       if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
3245         return false;
3246       if (! check_bool_pattern (rhs1, vinfo, stmts))
3247         return false;
3248       break;
3249
3250     case BIT_NOT_EXPR:
3251       if (! check_bool_pattern (rhs1, vinfo, stmts))
3252         return false;
3253       break;
3254
3255     case BIT_AND_EXPR:
3256     case BIT_IOR_EXPR:
3257     case BIT_XOR_EXPR:
3258       if (! check_bool_pattern (rhs1, vinfo, stmts)
3259           || ! check_bool_pattern (gimple_assign_rhs2 (def_stmt), vinfo, stmts))
3260         return false;
3261       break;
3262
3263     default:
3264       if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
3265         {
3266           tree vecitype, comp_vectype;
3267
3268           /* If the comparison can throw, then is_gimple_condexpr will be
3269              false and we can't make a COND_EXPR/VEC_COND_EXPR out of it.  */
3270           if (stmt_could_throw_p (def_stmt))
3271             return false;
3272
3273           comp_vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1));
3274           if (comp_vectype == NULL_TREE)
3275             return false;
3276
3277           tree mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1));
3278           if (mask_type
3279               && expand_vec_cmp_expr_p (comp_vectype, mask_type, rhs_code))
3280             return false;
3281
3282           if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE)
3283             {
3284               scalar_mode mode = SCALAR_TYPE_MODE (TREE_TYPE (rhs1));
3285               tree itype
3286                 = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1);
3287               vecitype = get_vectype_for_scalar_type (itype);
3288               if (vecitype == NULL_TREE)
3289                 return false;
3290             }
3291           else
3292             vecitype = comp_vectype;
3293           if (! expand_vec_cond_expr_p (vecitype, comp_vectype, rhs_code))
3294             return false;
3295         }
3296       else
3297         return false;
3298       break;
3299     }
3300
3301   bool res = stmts.add (def_stmt);
3302   /* We can't end up recursing when just visiting SSA defs but not PHIs.  */
3303   gcc_assert (!res);
3304
3305   return true;
3306 }
3307
3308
3309 /* Helper function of adjust_bool_pattern.  Add a cast to TYPE to a previous
3310    stmt (SSA_NAME_DEF_STMT of VAR) adding a cast to STMT_INFOs
3311    pattern sequence.  */
3312
3313 static tree
3314 adjust_bool_pattern_cast (tree type, tree var, stmt_vec_info stmt_info)
3315 {
3316   gimple *cast_stmt = gimple_build_assign (vect_recog_temp_ssa_var (type, NULL),
3317                                            NOP_EXPR, var);
3318   stmt_vec_info patt_vinfo = new_stmt_vec_info (cast_stmt, stmt_info->vinfo);
3319   set_vinfo_for_stmt (cast_stmt, patt_vinfo);
3320   STMT_VINFO_VECTYPE (patt_vinfo) = get_vectype_for_scalar_type (type);
3321   append_pattern_def_seq (stmt_info, cast_stmt);
3322   return gimple_assign_lhs (cast_stmt);
3323 }
3324
3325 /* Helper function of vect_recog_bool_pattern.  Do the actual transformations.
3326    VAR is an SSA_NAME that should be transformed from bool to a wider integer
3327    type, OUT_TYPE is the desired final integer type of the whole pattern.
3328    STMT_INFO is the info of the pattern root and is where pattern stmts should
3329    be associated with.  DEFS is a map of pattern defs.  */
3330
3331 static void
3332 adjust_bool_pattern (tree var, tree out_type,
3333                      stmt_vec_info stmt_info, hash_map <tree, tree> &defs)
3334 {
3335   gimple *stmt = SSA_NAME_DEF_STMT (var);
3336   enum tree_code rhs_code, def_rhs_code;
3337   tree itype, cond_expr, rhs1, rhs2, irhs1, irhs2;
3338   location_t loc;
3339   gimple *pattern_stmt, *def_stmt;
3340   tree trueval = NULL_TREE;
3341
3342   rhs1 = gimple_assign_rhs1 (stmt);
3343   rhs2 = gimple_assign_rhs2 (stmt);
3344   rhs_code = gimple_assign_rhs_code (stmt);
3345   loc = gimple_location (stmt);
3346   switch (rhs_code)
3347     {
3348     case SSA_NAME:
3349     CASE_CONVERT:
3350       irhs1 = *defs.get (rhs1);
3351       itype = TREE_TYPE (irhs1);
3352       pattern_stmt
3353         = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
3354                                SSA_NAME, irhs1);
3355       break;
3356
3357     case BIT_NOT_EXPR:
3358       irhs1 = *defs.get (rhs1);
3359       itype = TREE_TYPE (irhs1);
3360       pattern_stmt
3361         = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
3362                                BIT_XOR_EXPR, irhs1, build_int_cst (itype, 1));
3363       break;
3364
3365     case BIT_AND_EXPR:
3366       /* Try to optimize x = y & (a < b ? 1 : 0); into
3367          x = (a < b ? y : 0);
3368
3369          E.g. for:
3370            bool a_b, b_b, c_b;
3371            TYPE d_T;
3372
3373            S1  a_b = x1 CMP1 y1;
3374            S2  b_b = x2 CMP2 y2;
3375            S3  c_b = a_b & b_b;
3376            S4  d_T = (TYPE) c_b;
3377
3378          we would normally emit:
3379
3380            S1'  a_T = x1 CMP1 y1 ? 1 : 0;
3381            S2'  b_T = x2 CMP2 y2 ? 1 : 0;
3382            S3'  c_T = a_T & b_T;
3383            S4'  d_T = c_T;
3384
3385          but we can save one stmt by using the
3386          result of one of the COND_EXPRs in the other COND_EXPR and leave
3387          BIT_AND_EXPR stmt out:
3388
3389            S1'  a_T = x1 CMP1 y1 ? 1 : 0;
3390            S3'  c_T = x2 CMP2 y2 ? a_T : 0;
3391            S4'  f_T = c_T;
3392
3393          At least when VEC_COND_EXPR is implemented using masks
3394          cond ? 1 : 0 is as expensive as cond ? var : 0, in both cases it
3395          computes the comparison masks and ands it, in one case with
3396          all ones vector, in the other case with a vector register.
3397          Don't do this for BIT_IOR_EXPR, because cond ? 1 : var; is
3398          often more expensive.  */
3399       def_stmt = SSA_NAME_DEF_STMT (rhs2);
3400       def_rhs_code = gimple_assign_rhs_code (def_stmt);
3401       if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
3402         {
3403           irhs1 = *defs.get (rhs1);
3404           tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
3405           if (TYPE_PRECISION (TREE_TYPE (irhs1))
3406               == GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (def_rhs1))))
3407             {
3408               rhs_code = def_rhs_code;
3409               rhs1 = def_rhs1;
3410               rhs2 = gimple_assign_rhs2 (def_stmt);
3411               trueval = irhs1;
3412               goto do_compare;
3413             }
3414           else
3415             irhs2 = *defs.get (rhs2);
3416           goto and_ior_xor;
3417         }
3418       def_stmt = SSA_NAME_DEF_STMT (rhs1);
3419       def_rhs_code = gimple_assign_rhs_code (def_stmt);
3420       if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
3421         {
3422           irhs2 = *defs.get (rhs2);
3423           tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
3424           if (TYPE_PRECISION (TREE_TYPE (irhs2))
3425               == GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (def_rhs1))))
3426             {
3427               rhs_code = def_rhs_code;
3428               rhs1 = def_rhs1;
3429               rhs2 = gimple_assign_rhs2 (def_stmt);
3430               trueval = irhs2;
3431               goto do_compare;
3432             }
3433           else
3434             irhs1 = *defs.get (rhs1);
3435           goto and_ior_xor;
3436         }
3437       /* FALLTHRU */
3438     case BIT_IOR_EXPR:
3439     case BIT_XOR_EXPR:
3440       irhs1 = *defs.get (rhs1);
3441       irhs2 = *defs.get (rhs2);
3442     and_ior_xor:
3443       if (TYPE_PRECISION (TREE_TYPE (irhs1))
3444           != TYPE_PRECISION (TREE_TYPE (irhs2)))
3445         {
3446           int prec1 = TYPE_PRECISION (TREE_TYPE (irhs1));
3447           int prec2 = TYPE_PRECISION (TREE_TYPE (irhs2));
3448           int out_prec = TYPE_PRECISION (out_type);
3449           if (absu_hwi (out_prec - prec1) < absu_hwi (out_prec - prec2))
3450             irhs2 = adjust_bool_pattern_cast (TREE_TYPE (irhs1), irhs2,
3451                                               stmt_info);
3452           else if (absu_hwi (out_prec - prec1) > absu_hwi (out_prec - prec2))
3453             irhs1 = adjust_bool_pattern_cast (TREE_TYPE (irhs2), irhs1,
3454                                               stmt_info);
3455           else
3456             {
3457               irhs1 = adjust_bool_pattern_cast (out_type, irhs1, stmt_info);
3458               irhs2 = adjust_bool_pattern_cast (out_type, irhs2, stmt_info);
3459             }
3460         }
3461       itype = TREE_TYPE (irhs1);
3462       pattern_stmt
3463         = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
3464                                rhs_code, irhs1, irhs2);
3465       break;
3466
3467     default:
3468     do_compare:
3469       gcc_assert (TREE_CODE_CLASS (rhs_code) == tcc_comparison);
3470       if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE
3471           || !TYPE_UNSIGNED (TREE_TYPE (rhs1))
3472           || maybe_ne (TYPE_PRECISION (TREE_TYPE (rhs1)),
3473                        GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1)))))
3474         {
3475           scalar_mode mode = SCALAR_TYPE_MODE (TREE_TYPE (rhs1));
3476           itype
3477             = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1);
3478         }
3479       else
3480         itype = TREE_TYPE (rhs1);
3481       cond_expr = build2_loc (loc, rhs_code, itype, rhs1, rhs2);
3482       if (trueval == NULL_TREE)
3483         trueval = build_int_cst (itype, 1);
3484       else
3485         gcc_checking_assert (useless_type_conversion_p (itype,
3486                                                         TREE_TYPE (trueval)));
3487       pattern_stmt
3488         = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL),
3489                                COND_EXPR, cond_expr, trueval,
3490                                build_int_cst (itype, 0));
3491       break;
3492     }
3493
3494   gimple_set_location (pattern_stmt, loc);
3495   /* ???  Why does vect_mark_pattern_stmts set the vector type on all
3496      pattern def seq stmts instead of just letting auto-detection do
3497      its work?  */
3498   stmt_vec_info patt_vinfo = new_stmt_vec_info (pattern_stmt, stmt_info->vinfo);
3499   set_vinfo_for_stmt (pattern_stmt, patt_vinfo);
3500   STMT_VINFO_VECTYPE (patt_vinfo) = get_vectype_for_scalar_type (itype);
3501   append_pattern_def_seq (stmt_info, pattern_stmt);
3502   defs.put (var, gimple_assign_lhs (pattern_stmt));
3503 }
3504
3505 /* Comparison function to qsort a vector of gimple stmts after UID.  */
3506
3507 static int
3508 sort_after_uid (const void *p1, const void *p2)
3509 {
3510   const gimple *stmt1 = *(const gimple * const *)p1;
3511   const gimple *stmt2 = *(const gimple * const *)p2;
3512   return gimple_uid (stmt1) - gimple_uid (stmt2);
3513 }
3514
3515 /* Create pattern stmts for all stmts participating in the bool pattern
3516    specified by BOOL_STMT_SET and its root STMT with the desired type
3517    OUT_TYPE.  Return the def of the pattern root.  */
3518
3519 static tree
3520 adjust_bool_stmts (hash_set <gimple *> &bool_stmt_set,
3521                    tree out_type, gimple *stmt)
3522 {
3523   /* Gather original stmts in the bool pattern in their order of appearance
3524      in the IL.  */
3525   auto_vec<gimple *> bool_stmts (bool_stmt_set.elements ());
3526   for (hash_set <gimple *>::iterator i = bool_stmt_set.begin ();
3527        i != bool_stmt_set.end (); ++i)
3528     bool_stmts.quick_push (*i);
3529   bool_stmts.qsort (sort_after_uid);
3530
3531   /* Now process them in that order, producing pattern stmts.  */
3532   hash_map <tree, tree> defs;
3533   for (unsigned i = 0; i < bool_stmts.length (); ++i)
3534     adjust_bool_pattern (gimple_assign_lhs (bool_stmts[i]),
3535                          out_type, vinfo_for_stmt (stmt), defs);
3536
3537   /* Pop the last pattern seq stmt and install it as pattern root for STMT.  */
3538   gimple *pattern_stmt
3539     = gimple_seq_last_stmt (STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (stmt)));
3540   return gimple_assign_lhs (pattern_stmt);
3541 }
3542
3543 /* Helper for search_type_for_mask.  */
3544
3545 static tree
3546 search_type_for_mask_1 (tree var, vec_info *vinfo,
3547                         hash_map<gimple *, tree> &cache)
3548 {
3549   gimple *def_stmt;
3550   enum vect_def_type dt;
3551   tree rhs1;
3552   enum tree_code rhs_code;
3553   tree res = NULL_TREE, res2;
3554
3555   if (TREE_CODE (var) != SSA_NAME)
3556     return NULL_TREE;
3557
3558   if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
3559     return NULL_TREE;
3560
3561   if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
3562     return NULL_TREE;
3563
3564   if (dt != vect_internal_def)
3565     return NULL_TREE;
3566
3567   if (!is_gimple_assign (def_stmt))
3568     return NULL_TREE;
3569
3570   tree *c = cache.get (def_stmt);
3571   if (c)
3572     return *c;
3573
3574   rhs_code = gimple_assign_rhs_code (def_stmt);
3575   rhs1 = gimple_assign_rhs1 (def_stmt);
3576
3577   switch (rhs_code)
3578     {
3579     case SSA_NAME:
3580     case BIT_NOT_EXPR:
3581     CASE_CONVERT:
3582       res = search_type_for_mask_1 (rhs1, vinfo, cache);
3583       break;
3584
3585     case BIT_AND_EXPR:
3586     case BIT_IOR_EXPR:
3587     case BIT_XOR_EXPR:
3588       res = search_type_for_mask_1 (rhs1, vinfo, cache);
3589       res2 = search_type_for_mask_1 (gimple_assign_rhs2 (def_stmt), vinfo,
3590                                      cache);
3591       if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))
3592         res = res2;
3593       break;
3594
3595     default:
3596       if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
3597         {
3598           tree comp_vectype, mask_type;
3599
3600           if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
3601             {
3602               res = search_type_for_mask_1 (rhs1, vinfo, cache);
3603               res2 = search_type_for_mask_1 (gimple_assign_rhs2 (def_stmt),
3604                                              vinfo, cache);
3605               if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))
3606                 res = res2;
3607               break;
3608             }
3609
3610           comp_vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1));
3611           if (comp_vectype == NULL_TREE)
3612             {
3613               res = NULL_TREE;
3614               break;
3615             }
3616
3617           mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1));
3618           if (!mask_type
3619               || !expand_vec_cmp_expr_p (comp_vectype, mask_type, rhs_code))
3620             {
3621               res = NULL_TREE;
3622               break;
3623             }
3624
3625           if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE
3626               || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
3627             {
3628               scalar_mode mode = SCALAR_TYPE_MODE (TREE_TYPE (rhs1));
3629               res = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1);
3630             }
3631           else
3632             res = TREE_TYPE (rhs1);
3633         }
3634     }
3635
3636   cache.put (def_stmt, res);
3637   return res;
3638 }
3639
3640 /* Return the proper type for converting bool VAR into
3641    an integer value or NULL_TREE if no such type exists.
3642    The type is chosen so that converted value has the
3643    same number of elements as VAR's vector type.  */
3644
3645 static tree
3646 search_type_for_mask (tree var, vec_info *vinfo)
3647 {
3648   hash_map<gimple *, tree> cache;
3649   return search_type_for_mask_1 (var, vinfo, cache);
3650 }
3651
3652 /* Function vect_recog_bool_pattern
3653
3654    Try to find pattern like following:
3655
3656      bool a_b, b_b, c_b, d_b, e_b;
3657      TYPE f_T;
3658    loop:
3659      S1  a_b = x1 CMP1 y1;
3660      S2  b_b = x2 CMP2 y2;
3661      S3  c_b = a_b & b_b;
3662      S4  d_b = x3 CMP3 y3;
3663      S5  e_b = c_b | d_b;
3664      S6  f_T = (TYPE) e_b;
3665
3666    where type 'TYPE' is an integral type.  Or a similar pattern
3667    ending in
3668
3669      S6  f_Y = e_b ? r_Y : s_Y;
3670
3671    as results from if-conversion of a complex condition.
3672
3673    Input:
3674
3675    * LAST_STMT: A stmt at the end from which the pattern
3676                 search begins, i.e. cast of a bool to
3677                 an integer type.
3678
3679    Output:
3680
3681    * TYPE_IN: The type of the input arguments to the pattern.
3682
3683    * TYPE_OUT: The type of the output of this pattern.
3684
3685    * Return value: A new stmt that will be used to replace the pattern.
3686
3687         Assuming size of TYPE is the same as size of all comparisons
3688         (otherwise some casts would be added where needed), the above
3689         sequence we create related pattern stmts:
3690         S1'  a_T = x1 CMP1 y1 ? 1 : 0;
3691         S3'  c_T = x2 CMP2 y2 ? a_T : 0;
3692         S4'  d_T = x3 CMP3 y3 ? 1 : 0;
3693         S5'  e_T = c_T | d_T;
3694         S6'  f_T = e_T;
3695
3696         Instead of the above S3' we could emit:
3697         S2'  b_T = x2 CMP2 y2 ? 1 : 0;
3698         S3'  c_T = a_T | b_T;
3699         but the above is more efficient.  */
3700
3701 static gimple *
3702 vect_recog_bool_pattern (vec<gimple *> *stmts, tree *type_in,
3703                          tree *type_out)
3704 {
3705   gimple *last_stmt = stmts->pop ();
3706   enum tree_code rhs_code;
3707   tree var, lhs, rhs, vectype;
3708   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
3709   stmt_vec_info new_stmt_info;
3710   vec_info *vinfo = stmt_vinfo->vinfo;
3711   gimple *pattern_stmt;
3712
3713   if (!is_gimple_assign (last_stmt))
3714     return NULL;
3715
3716   var = gimple_assign_rhs1 (last_stmt);
3717   lhs = gimple_assign_lhs (last_stmt);
3718
3719   if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
3720     return NULL;
3721
3722   hash_set<gimple *> bool_stmts;
3723
3724   rhs_code = gimple_assign_rhs_code (last_stmt);
3725   if (CONVERT_EXPR_CODE_P (rhs_code))
3726     {
3727       if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
3728           || TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
3729         return NULL;
3730       vectype = get_vectype_for_scalar_type (TREE_TYPE (lhs));
3731       if (vectype == NULL_TREE)
3732         return NULL;
3733
3734       if (check_bool_pattern (var, vinfo, bool_stmts))
3735         {
3736           rhs = adjust_bool_stmts (bool_stmts, TREE_TYPE (lhs), last_stmt);
3737           lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
3738           if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3739             pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);
3740           else
3741             pattern_stmt
3742               = gimple_build_assign (lhs, NOP_EXPR, rhs);
3743         }
3744       else
3745         {
3746           tree type = search_type_for_mask (var, vinfo);
3747           tree cst0, cst1, tmp;
3748
3749           if (!type)
3750             return NULL;
3751
3752           /* We may directly use cond with narrowed type to avoid
3753              multiple cond exprs with following result packing and
3754              perform single cond with packed mask instead.  In case
3755              of widening we better make cond first and then extract
3756              results.  */
3757           if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (lhs)))
3758             type = TREE_TYPE (lhs);
3759
3760           cst0 = build_int_cst (type, 0);
3761           cst1 = build_int_cst (type, 1);
3762           tmp = vect_recog_temp_ssa_var (type, NULL);
3763           pattern_stmt = gimple_build_assign (tmp, COND_EXPR, var, cst1, cst0);
3764
3765           if (!useless_type_conversion_p (type, TREE_TYPE (lhs)))
3766             {
3767               tree new_vectype = get_vectype_for_scalar_type (type);
3768               new_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
3769               set_vinfo_for_stmt (pattern_stmt, new_stmt_info);
3770               STMT_VINFO_VECTYPE (new_stmt_info) = new_vectype;
3771               new_pattern_def_seq (stmt_vinfo, pattern_stmt);
3772
3773               lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
3774               pattern_stmt = gimple_build_assign (lhs, CONVERT_EXPR, tmp);
3775             }
3776         }
3777
3778       *type_out = vectype;
3779       *type_in = vectype;
3780       stmts->safe_push (last_stmt);
3781       if (dump_enabled_p ())
3782         dump_printf_loc (MSG_NOTE, vect_location,
3783                          "vect_recog_bool_pattern: detected:\n");
3784
3785       return pattern_stmt;
3786     }
3787   else if (rhs_code == COND_EXPR
3788            && TREE_CODE (var) == SSA_NAME)
3789     {
3790       vectype = get_vectype_for_scalar_type (TREE_TYPE (lhs));
3791       if (vectype == NULL_TREE)
3792         return NULL;
3793
3794       /* Build a scalar type for the boolean result that when
3795          vectorized matches the vector type of the result in
3796          size and number of elements.  */
3797       unsigned prec
3798         = vector_element_size (tree_to_poly_uint64 (TYPE_SIZE (vectype)),
3799                                TYPE_VECTOR_SUBPARTS (vectype));
3800
3801       tree type
3802         = build_nonstandard_integer_type (prec,
3803                                           TYPE_UNSIGNED (TREE_TYPE (var)));
3804       if (get_vectype_for_scalar_type (type) == NULL_TREE)
3805         return NULL;
3806
3807       if (!check_bool_pattern (var, vinfo, bool_stmts))
3808         return NULL;
3809
3810       rhs = adjust_bool_stmts (bool_stmts, type, last_stmt);
3811
3812       lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
3813       pattern_stmt 
3814           = gimple_build_assign (lhs, COND_EXPR,
3815                                  build2 (NE_EXPR, boolean_type_node,
3816                                          rhs, build_int_cst (type, 0)),
3817                                  gimple_assign_rhs2 (last_stmt),
3818                                  gimple_assign_rhs3 (last_stmt));
3819       *type_out = vectype;
3820       *type_in = vectype;
3821       stmts->safe_push (last_stmt);
3822       if (dump_enabled_p ())
3823         dump_printf_loc (MSG_NOTE, vect_location,
3824                          "vect_recog_bool_pattern: detected:\n");
3825
3826       return pattern_stmt;
3827     }
3828   else if (rhs_code == SSA_NAME
3829            && STMT_VINFO_DATA_REF (stmt_vinfo))
3830     {
3831       stmt_vec_info pattern_stmt_info;
3832       vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
3833       gcc_assert (vectype != NULL_TREE);
3834       if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
3835         return NULL;
3836
3837       if (check_bool_pattern (var, vinfo, bool_stmts))
3838         rhs = adjust_bool_stmts (bool_stmts, TREE_TYPE (vectype), last_stmt);
3839       else
3840         {
3841           tree type = search_type_for_mask (var, vinfo);
3842           tree cst0, cst1, new_vectype;
3843
3844           if (!type)
3845             return NULL;
3846
3847           if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (vectype)))
3848             type = TREE_TYPE (vectype);
3849
3850           cst0 = build_int_cst (type, 0);
3851           cst1 = build_int_cst (type, 1);
3852           new_vectype = get_vectype_for_scalar_type (type);
3853
3854           rhs = vect_recog_temp_ssa_var (type, NULL);
3855           pattern_stmt = gimple_build_assign (rhs, COND_EXPR, var, cst1, cst0);
3856
3857           pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
3858           set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
3859           STMT_VINFO_VECTYPE (pattern_stmt_info) = new_vectype;
3860           append_pattern_def_seq (stmt_vinfo, pattern_stmt);
3861         }
3862
3863       lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vectype), lhs);
3864       if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3865         {
3866           tree rhs2 = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
3867           gimple *cast_stmt = gimple_build_assign (rhs2, NOP_EXPR, rhs);
3868           append_pattern_def_seq (stmt_vinfo, cast_stmt);
3869           rhs = rhs2;
3870         }
3871       pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);
3872       pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
3873       set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
3874       STMT_VINFO_DATA_REF (pattern_stmt_info)
3875         = STMT_VINFO_DATA_REF (stmt_vinfo);
3876       STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
3877         = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
3878       DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
3879       *type_out = vectype;
3880       *type_in = vectype;
3881       stmts->safe_push (last_stmt);
3882       if (dump_enabled_p ())
3883         dump_printf_loc (MSG_NOTE, vect_location,
3884                          "vect_recog_bool_pattern: detected:\n");
3885       return pattern_stmt;
3886     }
3887   else
3888     return NULL;
3889 }
3890
3891
3892 /* A helper for vect_recog_mask_conversion_pattern.  Build
3893    conversion of MASK to a type suitable for masking VECTYPE.
3894    Built statement gets required vectype and is appended to
3895    a pattern sequence of STMT_VINFO.
3896
3897    Return converted mask.  */
3898
3899 static tree
3900 build_mask_conversion (tree mask, tree vectype, stmt_vec_info stmt_vinfo,
3901                        vec_info *vinfo)
3902 {
3903   gimple *stmt;
3904   tree masktype, tmp;
3905   stmt_vec_info new_stmt_info;
3906
3907   masktype = build_same_sized_truth_vector_type (vectype);
3908   tmp = vect_recog_temp_ssa_var (TREE_TYPE (masktype), NULL);
3909   stmt = gimple_build_assign (tmp, CONVERT_EXPR, mask);
3910   new_stmt_info = new_stmt_vec_info (stmt, vinfo);
3911   set_vinfo_for_stmt (stmt, new_stmt_info);
3912   STMT_VINFO_VECTYPE (new_stmt_info) = masktype;
3913   append_pattern_def_seq (stmt_vinfo, stmt);
3914
3915   return tmp;
3916 }
3917
3918
3919 /* Function vect_recog_mask_conversion_pattern
3920
3921    Try to find statements which require boolean type
3922    converison.  Additional conversion statements are
3923    added to handle such cases.  For example:
3924
3925    bool m_1, m_2, m_3;
3926    int i_4, i_5;
3927    double d_6, d_7;
3928    char c_1, c_2, c_3;
3929
3930    S1   m_1 = i_4 > i_5;
3931    S2   m_2 = d_6 < d_7;
3932    S3   m_3 = m_1 & m_2;
3933    S4   c_1 = m_3 ? c_2 : c_3;
3934
3935    Will be transformed into:
3936
3937    S1   m_1 = i_4 > i_5;
3938    S2   m_2 = d_6 < d_7;
3939    S3'' m_2' = (_Bool[bitsize=32])m_2
3940    S3'  m_3' = m_1 & m_2';
3941    S4'' m_3'' = (_Bool[bitsize=8])m_3'
3942    S4'  c_1' = m_3'' ? c_2 : c_3;  */
3943
3944 static gimple *
3945 vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
3946                                     tree *type_out)
3947 {
3948   gimple *last_stmt = stmts->pop ();
3949   enum tree_code rhs_code;
3950   tree lhs = NULL_TREE, rhs1, rhs2, tmp, rhs1_type, rhs2_type;
3951   tree vectype1, vectype2;
3952   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
3953   stmt_vec_info pattern_stmt_info;
3954   vec_info *vinfo = stmt_vinfo->vinfo;
3955
3956   /* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion.  */
3957   if (is_gimple_call (last_stmt)
3958       && gimple_call_internal_p (last_stmt)
3959       && (gimple_call_internal_fn (last_stmt) == IFN_MASK_STORE
3960           || gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD))
3961     {
3962       gcall *pattern_stmt;
3963       bool load = (gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD);
3964
3965       if (load)
3966         {
3967           lhs = gimple_call_lhs (last_stmt);
3968           vectype1 = get_vectype_for_scalar_type (TREE_TYPE (lhs));
3969         }
3970       else
3971         {
3972           rhs2 = gimple_call_arg (last_stmt, 3);
3973           vectype1 = get_vectype_for_scalar_type (TREE_TYPE (rhs2));
3974         }
3975
3976       rhs1 = gimple_call_arg (last_stmt, 2);
3977       rhs1_type = search_type_for_mask (rhs1, vinfo);
3978       if (!rhs1_type)
3979         return NULL;
3980       vectype2 = get_mask_type_for_scalar_type (rhs1_type);
3981
3982       if (!vectype1 || !vectype2
3983           || known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
3984                        TYPE_VECTOR_SUBPARTS (vectype2)))
3985         return NULL;
3986
3987       tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
3988
3989       if (load)
3990         {
3991           lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
3992           pattern_stmt
3993             = gimple_build_call_internal (IFN_MASK_LOAD, 3,
3994                                           gimple_call_arg (last_stmt, 0),
3995                                           gimple_call_arg (last_stmt, 1),
3996                                           tmp);
3997           gimple_call_set_lhs (pattern_stmt, lhs);
3998         }
3999       else
4000           pattern_stmt
4001             = gimple_build_call_internal (IFN_MASK_STORE, 4,
4002                                           gimple_call_arg (last_stmt, 0),
4003                                           gimple_call_arg (last_stmt, 1),
4004                                           tmp,
4005                                           gimple_call_arg (last_stmt, 3));
4006
4007       gimple_call_set_nothrow (pattern_stmt, true);
4008
4009       pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
4010       set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
4011       STMT_VINFO_DATA_REF (pattern_stmt_info)
4012         = STMT_VINFO_DATA_REF (stmt_vinfo);
4013       STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
4014         = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
4015       DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
4016
4017       *type_out = vectype1;
4018       *type_in = vectype1;
4019       stmts->safe_push (last_stmt);
4020       if (dump_enabled_p ())
4021         dump_printf_loc (MSG_NOTE, vect_location,
4022                          "vect_recog_mask_conversion_pattern: detected:\n");
4023
4024       return pattern_stmt;
4025     }
4026
4027   if (!is_gimple_assign (last_stmt))
4028     return NULL;
4029
4030   gimple *pattern_stmt;
4031   lhs = gimple_assign_lhs (last_stmt);
4032   rhs1 = gimple_assign_rhs1 (last_stmt);
4033   rhs_code = gimple_assign_rhs_code (last_stmt);
4034
4035   /* Check for cond expression requiring mask conversion.  */
4036   if (rhs_code == COND_EXPR)
4037     {
4038       /* vect_recog_mixed_size_cond_pattern could apply.
4039          Do nothing then.  */
4040       if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
4041         return NULL;
4042
4043       vectype1 = get_vectype_for_scalar_type (TREE_TYPE (lhs));
4044
4045       if (TREE_CODE (rhs1) == SSA_NAME)
4046         {
4047           rhs1_type = search_type_for_mask (rhs1, vinfo);
4048           if (!rhs1_type)
4049             return NULL;
4050         }
4051       else if (COMPARISON_CLASS_P (rhs1))
4052         {
4053           /* Check whether we're comparing scalar booleans and (if so)
4054              whether a better mask type exists than the mask associated
4055              with boolean-sized elements.  This avoids unnecessary packs
4056              and unpacks if the booleans are set from comparisons of
4057              wider types.  E.g. in:
4058
4059                int x1, x2, x3, x4, y1, y1;
4060                ...
4061                bool b1 = (x1 == x2);
4062                bool b2 = (x3 == x4);
4063                ... = b1 == b2 ? y1 : y2;
4064
4065              it is better for b1 and b2 to use the mask type associated
4066              with int elements rather bool (byte) elements.  */
4067           rhs1_type = search_type_for_mask (TREE_OPERAND (rhs1, 0), vinfo);
4068           if (!rhs1_type)
4069             rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
4070         }
4071       else
4072         return NULL;
4073
4074       vectype2 = get_mask_type_for_scalar_type (rhs1_type);
4075
4076       if (!vectype1 || !vectype2)
4077         return NULL;
4078
4079       /* Continue if a conversion is needed.  Also continue if we have
4080          a comparison whose vector type would normally be different from
4081          VECTYPE2 when considered in isolation.  In that case we'll
4082          replace the comparison with an SSA name (so that we can record
4083          its vector type) and behave as though the comparison was an SSA
4084          name from the outset.  */
4085       if (known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
4086                     TYPE_VECTOR_SUBPARTS (vectype2))
4087           && (TREE_CODE (rhs1) == SSA_NAME
4088               || rhs1_type == TREE_TYPE (TREE_OPERAND (rhs1, 0))))
4089         return NULL;
4090
4091       /* If rhs1 is invariant and we can promote it leave the COND_EXPR
4092          in place, we can handle it in vectorizable_condition.  This avoids
4093          unnecessary promotion stmts and increased vectorization factor.  */
4094       if (COMPARISON_CLASS_P (rhs1)
4095           && INTEGRAL_TYPE_P (rhs1_type)
4096           && known_le (TYPE_VECTOR_SUBPARTS (vectype1),
4097                        TYPE_VECTOR_SUBPARTS (vectype2)))
4098         {
4099           gimple *dummy;
4100           enum vect_def_type dt;
4101           if (vect_is_simple_use (TREE_OPERAND (rhs1, 0), stmt_vinfo->vinfo,
4102                                   &dummy, &dt)
4103               && dt == vect_external_def
4104               && vect_is_simple_use (TREE_OPERAND (rhs1, 1), stmt_vinfo->vinfo,
4105                                      &dummy, &dt)
4106               && (dt == vect_external_def
4107                   || dt == vect_constant_def))
4108             {
4109               tree wide_scalar_type = build_nonstandard_integer_type
4110                 (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype1))),
4111                  TYPE_UNSIGNED (rhs1_type));
4112               tree vectype3 = get_vectype_for_scalar_type (wide_scalar_type);
4113               if (expand_vec_cond_expr_p (vectype1, vectype3, TREE_CODE (rhs1)))
4114                 return NULL;
4115             }
4116         }
4117
4118       /* If rhs1 is a comparison we need to move it into a
4119          separate statement.  */
4120       if (TREE_CODE (rhs1) != SSA_NAME)
4121         {
4122           tmp = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL);
4123           pattern_stmt = gimple_build_assign (tmp, rhs1);
4124           rhs1 = tmp;
4125
4126           pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
4127           set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
4128           STMT_VINFO_VECTYPE (pattern_stmt_info) = vectype2;
4129           append_pattern_def_seq (stmt_vinfo, pattern_stmt);
4130         }
4131
4132       if (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype1),
4133                     TYPE_VECTOR_SUBPARTS (vectype2)))
4134         tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
4135       else
4136         tmp = rhs1;
4137
4138       lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
4139       pattern_stmt = gimple_build_assign (lhs, COND_EXPR, tmp,
4140                                           gimple_assign_rhs2 (last_stmt),
4141                                           gimple_assign_rhs3 (last_stmt));
4142
4143       *type_out = vectype1;
4144       *type_in = vectype1;
4145       stmts->safe_push (last_stmt);
4146       if (dump_enabled_p ())
4147         dump_printf_loc (MSG_NOTE, vect_location,
4148                          "vect_recog_mask_conversion_pattern: detected:\n");
4149
4150       return pattern_stmt;
4151     }
4152
4153   /* Now check for binary boolean operations requiring conversion for
4154      one of operands.  */
4155   if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
4156     return NULL;
4157
4158   if (rhs_code != BIT_IOR_EXPR
4159       && rhs_code != BIT_XOR_EXPR
4160       && rhs_code != BIT_AND_EXPR
4161       && TREE_CODE_CLASS (rhs_code) != tcc_comparison)
4162     return NULL;
4163
4164   rhs2 = gimple_assign_rhs2 (last_stmt);
4165
4166   rhs1_type = search_type_for_mask (rhs1, vinfo);
4167   rhs2_type = search_type_for_mask (rhs2, vinfo);
4168
4169   if (!rhs1_type || !rhs2_type
4170       || TYPE_PRECISION (rhs1_type) == TYPE_PRECISION (rhs2_type))
4171     return NULL;
4172
4173   if (TYPE_PRECISION (rhs1_type) < TYPE_PRECISION (rhs2_type))
4174     {
4175       vectype1 = get_mask_type_for_scalar_type (rhs1_type);
4176       if (!vectype1)
4177         return NULL;
4178       rhs2 = build_mask_conversion (rhs2, vectype1, stmt_vinfo, vinfo);
4179     }
4180   else
4181     {
4182       vectype1 = get_mask_type_for_scalar_type (rhs2_type);
4183       if (!vectype1)
4184         return NULL;
4185       rhs1 = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
4186     }
4187
4188   lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
4189   pattern_stmt = gimple_build_assign (lhs, rhs_code, rhs1, rhs2);
4190
4191   *type_out = vectype1;
4192   *type_in = vectype1;
4193   stmts->safe_push (last_stmt);
4194   if (dump_enabled_p ())
4195     dump_printf_loc (MSG_NOTE, vect_location,
4196                      "vect_recog_mask_conversion_pattern: detected:\n");
4197
4198   return pattern_stmt;
4199 }
4200
4201 /* STMT is a load or store.  If the load or store is conditional, return
4202    the boolean condition under which it occurs, otherwise return null.  */
4203
4204 static tree
4205 vect_get_load_store_mask (gimple *stmt)
4206 {
4207   if (gassign *def_assign = dyn_cast <gassign *> (stmt))
4208     {
4209       gcc_assert (gimple_assign_single_p (def_assign));
4210       return NULL_TREE;
4211     }
4212
4213   if (gcall *def_call = dyn_cast <gcall *> (stmt))
4214     {
4215       internal_fn ifn = gimple_call_internal_fn (def_call);
4216       int mask_index = internal_fn_mask_index (ifn);
4217       return gimple_call_arg (def_call, mask_index);
4218     }
4219
4220   gcc_unreachable ();
4221 }
4222
4223 /* Return the scalar offset type that an internal gather/scatter function
4224    should use.  GS_INFO describes the gather/scatter operation.  */
4225
4226 static tree
4227 vect_get_gather_scatter_offset_type (gather_scatter_info *gs_info)
4228 {
4229   tree offset_type = TREE_TYPE (gs_info->offset);
4230   unsigned int element_bits = tree_to_uhwi (TYPE_SIZE (gs_info->element_type));
4231
4232   /* Enforced by vect_check_gather_scatter.  */
4233   unsigned int offset_bits = TYPE_PRECISION (offset_type);
4234   gcc_assert (element_bits >= offset_bits);
4235
4236   /* If the offset is narrower than the elements, extend it according
4237      to its sign.  */
4238   if (element_bits > offset_bits)
4239     return build_nonstandard_integer_type (element_bits,
4240                                            TYPE_UNSIGNED (offset_type));
4241
4242   return offset_type;
4243 }
4244
4245 /* Return MASK if MASK is suitable for masking an operation on vectors
4246    of type VECTYPE, otherwise convert it into such a form and return
4247    the result.  Associate any conversion statements with STMT_INFO's
4248    pattern.  */
4249
4250 static tree
4251 vect_convert_mask_for_vectype (tree mask, tree vectype,
4252                                stmt_vec_info stmt_info, vec_info *vinfo)
4253 {
4254   tree mask_type = search_type_for_mask (mask, vinfo);
4255   if (mask_type)
4256     {
4257       tree mask_vectype = get_mask_type_for_scalar_type (mask_type);
4258       if (mask_vectype
4259           && maybe_ne (TYPE_VECTOR_SUBPARTS (vectype),
4260                        TYPE_VECTOR_SUBPARTS (mask_vectype)))
4261         mask = build_mask_conversion (mask, vectype, stmt_info, vinfo);
4262     }
4263   return mask;
4264 }
4265
4266 /* Return the equivalent of:
4267
4268      fold_convert (TYPE, VALUE)
4269
4270    with the expectation that the operation will be vectorized.
4271    If new statements are needed, add them as pattern statements
4272    to STMT_INFO.  */
4273
4274 static tree
4275 vect_add_conversion_to_patterm (tree type, tree value,
4276                                 stmt_vec_info stmt_info,
4277                                 vec_info *vinfo)
4278 {
4279   if (useless_type_conversion_p (type, TREE_TYPE (value)))
4280     return value;
4281
4282   tree new_value = vect_recog_temp_ssa_var (type, NULL);
4283   gassign *conversion = gimple_build_assign (new_value, CONVERT_EXPR, value);
4284   stmt_vec_info new_stmt_info = new_stmt_vec_info (conversion, vinfo);
4285   set_vinfo_for_stmt (conversion, new_stmt_info);
4286   STMT_VINFO_VECTYPE (new_stmt_info) = get_vectype_for_scalar_type (type);
4287   append_pattern_def_seq (stmt_info, conversion);
4288   return new_value;
4289 }
4290
4291 /* Try to convert STMT into a call to a gather load or scatter store
4292    internal function.  Return the final statement on success and set
4293    *TYPE_IN and *TYPE_OUT to the vector type being loaded or stored.
4294
4295    This function only handles gathers and scatters that were recognized
4296    as such from the outset (indicated by STMT_VINFO_GATHER_SCATTER_P).  */
4297
4298 static gimple *
4299 vect_try_gather_scatter_pattern (gimple *stmt, stmt_vec_info last_stmt_info,
4300                                  tree *type_in, tree *type_out)
4301 {
4302   /* Currently we only support this for loop vectorization.  */
4303   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4304   loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (stmt_info->vinfo);
4305   if (!loop_vinfo)
4306     return NULL;
4307
4308   /* Make sure that we're looking at a gather load or scatter store.  */
4309   data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
4310   if (!dr || !STMT_VINFO_GATHER_SCATTER_P (stmt_info))
4311     return NULL;
4312
4313   /* Get the boolean that controls whether the load or store happens.
4314      This is null if the operation is unconditional.  */
4315   tree mask = vect_get_load_store_mask (stmt);
4316
4317   /* Make sure that the target supports an appropriate internal
4318      function for the gather/scatter operation.  */
4319   gather_scatter_info gs_info;
4320   if (!vect_check_gather_scatter (stmt, loop_vinfo, &gs_info)
4321       || gs_info.decl)
4322     return NULL;
4323
4324   /* Convert the mask to the right form.  */
4325   tree gs_vectype = get_vectype_for_scalar_type (gs_info.element_type);
4326   if (mask)
4327     mask = vect_convert_mask_for_vectype (mask, gs_vectype, last_stmt_info,
4328                                           loop_vinfo);
4329
4330   /* Get the invariant base and non-invariant offset, converting the
4331      latter to the same width as the vector elements.  */
4332   tree base = gs_info.base;
4333   tree offset_type = vect_get_gather_scatter_offset_type (&gs_info);
4334   tree offset = vect_add_conversion_to_patterm (offset_type, gs_info.offset,
4335                                                 last_stmt_info, loop_vinfo);
4336
4337   /* Build the new pattern statement.  */
4338   tree scale = size_int (gs_info.scale);
4339   gcall *pattern_stmt;
4340   if (DR_IS_READ (dr))
4341     {
4342       if (mask != NULL)
4343         pattern_stmt = gimple_build_call_internal (gs_info.ifn, 4, base,
4344                                                    offset, scale, mask);
4345       else
4346         pattern_stmt = gimple_build_call_internal (gs_info.ifn, 3, base,
4347                                                    offset, scale);
4348       tree load_lhs = vect_recog_temp_ssa_var (gs_info.element_type, NULL);
4349       gimple_call_set_lhs (pattern_stmt, load_lhs);
4350     }
4351   else
4352     {
4353       tree rhs = vect_get_store_rhs (stmt);
4354       if (mask != NULL)
4355         pattern_stmt = gimple_build_call_internal (IFN_MASK_SCATTER_STORE, 5,
4356                                                    base, offset, scale, rhs,
4357                                                    mask);
4358       else
4359         pattern_stmt = gimple_build_call_internal (IFN_SCATTER_STORE, 4,
4360                                                    base, offset, scale, rhs);
4361     }
4362   gimple_call_set_nothrow (pattern_stmt, true);
4363
4364   /* Copy across relevant vectorization info and associate DR with the
4365      new pattern statement instead of the original statement.  */
4366   stmt_vec_info pattern_stmt_info = new_stmt_vec_info (pattern_stmt,
4367                                                        loop_vinfo);
4368   set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
4369   STMT_VINFO_DATA_REF (pattern_stmt_info) = dr;
4370   STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
4371     = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info);
4372   STMT_VINFO_GATHER_SCATTER_P (pattern_stmt_info)
4373     = STMT_VINFO_GATHER_SCATTER_P (stmt_info);
4374   DR_STMT (dr) = pattern_stmt;
4375
4376   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4377   *type_out = vectype;
4378   *type_in = vectype;
4379
4380   if (dump_enabled_p ())
4381     dump_printf_loc (MSG_NOTE, vect_location,
4382                      "gather/scatter pattern detected:\n");
4383
4384   return pattern_stmt;
4385 }
4386
4387 /* Pattern wrapper around vect_try_gather_scatter_pattern.  */
4388
4389 static gimple *
4390 vect_recog_gather_scatter_pattern (vec<gimple *> *stmts, tree *type_in,
4391                                    tree *type_out)
4392 {
4393   gimple *last_stmt = stmts->pop ();
4394   stmt_vec_info last_stmt_info = vinfo_for_stmt (last_stmt);
4395   gimple *pattern_stmt = vect_try_gather_scatter_pattern (last_stmt,
4396                                                           last_stmt_info,
4397                                                           type_in, type_out);
4398   if (pattern_stmt)
4399     stmts->safe_push (last_stmt);
4400   return pattern_stmt;
4401 }
4402
4403 /* Mark statements that are involved in a pattern.  */
4404
4405 static inline void
4406 vect_mark_pattern_stmts (gimple *orig_stmt, gimple *pattern_stmt,
4407                          tree pattern_vectype)
4408 {
4409   stmt_vec_info pattern_stmt_info, def_stmt_info;
4410   stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt);
4411   vec_info *vinfo = orig_stmt_info->vinfo;
4412   gimple *def_stmt;
4413
4414   pattern_stmt_info = vinfo_for_stmt (pattern_stmt);
4415   if (pattern_stmt_info == NULL)
4416     {
4417       pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
4418       set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
4419     }
4420   gimple_set_bb (pattern_stmt, gimple_bb (orig_stmt));
4421
4422   STMT_VINFO_RELATED_STMT (pattern_stmt_info) = orig_stmt;
4423   STMT_VINFO_DEF_TYPE (pattern_stmt_info)
4424     = STMT_VINFO_DEF_TYPE (orig_stmt_info);
4425   STMT_VINFO_VECTYPE (pattern_stmt_info) = pattern_vectype;
4426   STMT_VINFO_IN_PATTERN_P (orig_stmt_info) = true;
4427   STMT_VINFO_RELATED_STMT (orig_stmt_info) = pattern_stmt;
4428   STMT_VINFO_PATTERN_DEF_SEQ (pattern_stmt_info)
4429     = STMT_VINFO_PATTERN_DEF_SEQ (orig_stmt_info);
4430   if (STMT_VINFO_PATTERN_DEF_SEQ (pattern_stmt_info))
4431     {
4432       gimple_stmt_iterator si;
4433       for (si = gsi_start (STMT_VINFO_PATTERN_DEF_SEQ (pattern_stmt_info));
4434            !gsi_end_p (si); gsi_next (&si))
4435         {
4436           def_stmt = gsi_stmt (si);
4437           def_stmt_info = vinfo_for_stmt (def_stmt);
4438           if (def_stmt_info == NULL)
4439             {
4440               def_stmt_info = new_stmt_vec_info (def_stmt, vinfo);
4441               set_vinfo_for_stmt (def_stmt, def_stmt_info);
4442             }
4443           gimple_set_bb (def_stmt, gimple_bb (orig_stmt));
4444           STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt;
4445           STMT_VINFO_DEF_TYPE (def_stmt_info) = vect_internal_def;
4446           if (STMT_VINFO_VECTYPE (def_stmt_info) == NULL_TREE)
4447             STMT_VINFO_VECTYPE (def_stmt_info) = pattern_vectype;
4448         }
4449     }
4450 }
4451
4452 /* Function vect_pattern_recog_1
4453
4454    Input:
4455    PATTERN_RECOG_FUNC: A pointer to a function that detects a certain
4456         computation pattern.
4457    STMT: A stmt from which the pattern search should start.
4458
4459    If PATTERN_RECOG_FUNC successfully detected the pattern, it creates an
4460    expression that computes the same functionality and can be used to
4461    replace the sequence of stmts that are involved in the pattern.
4462
4463    Output:
4464    This function checks if the expression returned by PATTERN_RECOG_FUNC is
4465    supported in vector form by the target.  We use 'TYPE_IN' to obtain the
4466    relevant vector type. If 'TYPE_IN' is already a vector type, then this
4467    indicates that target support had already been checked by PATTERN_RECOG_FUNC.
4468    If 'TYPE_OUT' is also returned by PATTERN_RECOG_FUNC, we check that it fits
4469    to the available target pattern.
4470
4471    This function also does some bookkeeping, as explained in the documentation
4472    for vect_recog_pattern.  */
4473
4474 static bool
4475 vect_pattern_recog_1 (vect_recog_func *recog_func,
4476                       gimple_stmt_iterator si,
4477                       vec<gimple *> *stmts_to_replace)
4478 {
4479   gimple *stmt = gsi_stmt (si), *pattern_stmt;
4480   stmt_vec_info stmt_info;
4481   loop_vec_info loop_vinfo;
4482   tree pattern_vectype;
4483   tree type_in, type_out;
4484   enum tree_code code;
4485   int i;
4486   gimple *next;
4487
4488   stmts_to_replace->truncate (0);
4489   stmts_to_replace->quick_push (stmt);
4490   pattern_stmt = recog_func->fn (stmts_to_replace, &type_in, &type_out);
4491   if (!pattern_stmt)
4492     return false;
4493
4494   stmt = stmts_to_replace->last ();
4495   stmt_info = vinfo_for_stmt (stmt);
4496   loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4497  
4498   if (VECTOR_BOOLEAN_TYPE_P (type_in)
4499       || VECTOR_TYPE_P (type_in))
4500     {
4501       /* No need to check target support (already checked by the pattern
4502          recognition function).  */
4503       pattern_vectype = type_out ? type_out : type_in;
4504     }
4505   else
4506     {
4507       /* Check target support  */
4508       type_in = get_vectype_for_scalar_type (type_in);
4509       if (!type_in)
4510         return false;
4511       if (type_out)
4512         type_out = get_vectype_for_scalar_type (type_out);
4513       else
4514         type_out = type_in;
4515       if (!type_out)
4516         return false;
4517       pattern_vectype = type_out;
4518
4519       if (is_gimple_assign (pattern_stmt))
4520         {
4521           enum insn_code icode;
4522           code = gimple_assign_rhs_code (pattern_stmt);
4523           optab optab = optab_for_tree_code (code, type_in, optab_default);
4524           machine_mode vec_mode = TYPE_MODE (type_in);
4525           if (!optab
4526               || (icode = optab_handler (optab, vec_mode)) == CODE_FOR_nothing
4527               || (insn_data[icode].operand[0].mode != TYPE_MODE (type_out)))
4528             return false;
4529         }
4530       else
4531         gcc_assert (is_gimple_call (pattern_stmt));
4532     }
4533
4534   /* Found a vectorizable pattern.  */
4535   if (dump_enabled_p ())
4536     {
4537       dump_printf_loc (MSG_NOTE, vect_location,
4538                        "%s pattern recognized: ", recog_func->name);
4539       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
4540     }
4541
4542   /* Mark the stmts that are involved in the pattern. */
4543   vect_mark_pattern_stmts (stmt, pattern_stmt, pattern_vectype);
4544
4545   /* Patterns cannot be vectorized using SLP, because they change the order of
4546      computation.  */
4547   if (loop_vinfo)
4548     FOR_EACH_VEC_ELT (LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next)
4549       if (next == stmt)
4550         LOOP_VINFO_REDUCTIONS (loop_vinfo).ordered_remove (i);
4551
4552   /* It is possible that additional pattern stmts are created and inserted in
4553      STMTS_TO_REPLACE.  We create a stmt_info for each of them, and mark the
4554      relevant statements.  */
4555   for (i = 0; stmts_to_replace->iterate (i, &stmt)
4556               && (unsigned) i < (stmts_to_replace->length () - 1);
4557        i++)
4558     {
4559       stmt_info = vinfo_for_stmt (stmt);
4560       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
4561       if (dump_enabled_p ())
4562         {
4563           dump_printf_loc (MSG_NOTE, vect_location,
4564                            "additional pattern stmt: ");
4565           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0);
4566         }
4567
4568       vect_mark_pattern_stmts (stmt, pattern_stmt, NULL_TREE);
4569     }
4570
4571   return true;
4572 }
4573
4574
4575 /* Function vect_pattern_recog
4576
4577    Input:
4578    LOOP_VINFO - a struct_loop_info of a loop in which we want to look for
4579         computation idioms.
4580
4581    Output - for each computation idiom that is detected we create a new stmt
4582         that provides the same functionality and that can be vectorized.  We
4583         also record some information in the struct_stmt_info of the relevant
4584         stmts, as explained below:
4585
4586    At the entry to this function we have the following stmts, with the
4587    following initial value in the STMT_VINFO fields:
4588
4589          stmt                     in_pattern_p  related_stmt    vec_stmt
4590          S1: a_i = ....                 -       -               -
4591          S2: a_2 = ..use(a_i)..         -       -               -
4592          S3: a_1 = ..use(a_2)..         -       -               -
4593          S4: a_0 = ..use(a_1)..         -       -               -
4594          S5: ... = ..use(a_0)..         -       -               -
4595
4596    Say the sequence {S1,S2,S3,S4} was detected as a pattern that can be
4597    represented by a single stmt.  We then:
4598    - create a new stmt S6 equivalent to the pattern (the stmt is not
4599      inserted into the code)
4600    - fill in the STMT_VINFO fields as follows:
4601
4602                                   in_pattern_p  related_stmt    vec_stmt
4603          S1: a_i = ....                 -       -               -
4604          S2: a_2 = ..use(a_i)..         -       -               -
4605          S3: a_1 = ..use(a_2)..         -       -               -
4606          S4: a_0 = ..use(a_1)..         true    S6              -
4607           '---> S6: a_new = ....        -       S4              -
4608          S5: ... = ..use(a_0)..         -       -               -
4609
4610    (the last stmt in the pattern (S4) and the new pattern stmt (S6) point
4611    to each other through the RELATED_STMT field).
4612
4613    S6 will be marked as relevant in vect_mark_stmts_to_be_vectorized instead
4614    of S4 because it will replace all its uses.  Stmts {S1,S2,S3} will
4615    remain irrelevant unless used by stmts other than S4.
4616
4617    If vectorization succeeds, vect_transform_stmt will skip over {S1,S2,S3}
4618    (because they are marked as irrelevant).  It will vectorize S6, and record
4619    a pointer to the new vector stmt VS6 from S6 (as usual).
4620    S4 will be skipped, and S5 will be vectorized as usual:
4621
4622                                   in_pattern_p  related_stmt    vec_stmt
4623          S1: a_i = ....                 -       -               -
4624          S2: a_2 = ..use(a_i)..         -       -               -
4625          S3: a_1 = ..use(a_2)..         -       -               -
4626        > VS6: va_new = ....             -       -               -
4627          S4: a_0 = ..use(a_1)..         true    S6              VS6
4628           '---> S6: a_new = ....        -       S4              VS6
4629        > VS5: ... = ..vuse(va_new)..    -       -               -
4630          S5: ... = ..use(a_0)..         -       -               -
4631
4632    DCE could then get rid of {S1,S2,S3,S4,S5} (if their defs are not used
4633    elsewhere), and we'll end up with:
4634
4635         VS6: va_new = ....
4636         VS5: ... = ..vuse(va_new)..
4637
4638    In case of more than one pattern statements, e.g., widen-mult with
4639    intermediate type:
4640
4641      S1  a_t = ;
4642      S2  a_T = (TYPE) a_t;
4643            '--> S3: a_it = (interm_type) a_t;
4644      S4  prod_T = a_T * CONST;
4645            '--> S5: prod_T' = a_it w* CONST;
4646
4647    there may be other users of a_T outside the pattern.  In that case S2 will
4648    be marked as relevant (as well as S3), and both S2 and S3 will be analyzed
4649    and vectorized.  The vector stmt VS2 will be recorded in S2, and VS3 will
4650    be recorded in S3.  */
4651
4652 void
4653 vect_pattern_recog (vec_info *vinfo)
4654 {
4655   struct loop *loop;
4656   basic_block *bbs;
4657   unsigned int nbbs;
4658   gimple_stmt_iterator si;
4659   unsigned int i, j;
4660   auto_vec<gimple *, 1> stmts_to_replace;
4661   gimple *stmt;
4662
4663   if (dump_enabled_p ())
4664     dump_printf_loc (MSG_NOTE, vect_location,
4665                      "=== vect_pattern_recog ===\n");
4666
4667   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
4668     {
4669       loop = LOOP_VINFO_LOOP (loop_vinfo);
4670       bbs = LOOP_VINFO_BBS (loop_vinfo);
4671       nbbs = loop->num_nodes;
4672
4673       /* Scan through the loop stmts, applying the pattern recognition
4674          functions starting at each stmt visited:  */
4675       for (i = 0; i < nbbs; i++)
4676         {
4677           basic_block bb = bbs[i];
4678           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
4679             {
4680               /* Scan over all generic vect_recog_xxx_pattern functions.  */
4681               for (j = 0; j < NUM_PATTERNS; j++)
4682                 if (vect_pattern_recog_1 (&vect_vect_recog_func_ptrs[j], si,
4683                                           &stmts_to_replace))
4684                   break;
4685             }
4686         }
4687     }
4688   else
4689     {
4690       bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
4691       for (si = bb_vinfo->region_begin;
4692            gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si))
4693         {
4694           if ((stmt = gsi_stmt (si))
4695               && vinfo_for_stmt (stmt)
4696               && !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)))
4697             continue;
4698
4699           /* Scan over all generic vect_recog_xxx_pattern functions.  */
4700           for (j = 0; j < NUM_PATTERNS; j++)
4701             if (vect_pattern_recog_1 (&vect_vect_recog_func_ptrs[j], si,
4702                                       &stmts_to_replace))
4703               break;
4704         }
4705     }
4706 }