Home | History | Annotate | Line # | Download | only in gcc
      1  1.1  mrg /* Lower vector operations to scalar operations.
      2  1.1  mrg    Copyright (C) 2004-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it
      7  1.1  mrg under the terms of the GNU General Public License as published by the
      8  1.1  mrg Free Software Foundation; either version 3, or (at your option) any
      9  1.1  mrg later version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT
     12  1.1  mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg #include "config.h"
     21  1.1  mrg #include "system.h"
     22  1.1  mrg #include "coretypes.h"
     23  1.1  mrg #include "backend.h"
     24  1.1  mrg #include "rtl.h"
     25  1.1  mrg #include "tree.h"
     26  1.1  mrg #include "gimple.h"
     27  1.1  mrg #include "tree-pass.h"
     28  1.1  mrg #include "ssa.h"
     29  1.1  mrg #include "expmed.h"
     30  1.1  mrg #include "optabs-tree.h"
     31  1.1  mrg #include "diagnostic.h"
     32  1.1  mrg #include "fold-const.h"
     33  1.1  mrg #include "stor-layout.h"
     34  1.1  mrg #include "langhooks.h"
     35  1.1  mrg #include "tree-eh.h"
     36  1.1  mrg #include "gimple-iterator.h"
     37  1.1  mrg #include "gimplify-me.h"
     38  1.1  mrg #include "gimplify.h"
     39  1.1  mrg #include "tree-cfg.h"
     40  1.1  mrg #include "tree-vector-builder.h"
     41  1.1  mrg #include "vec-perm-indices.h"
     42  1.1  mrg #include "insn-config.h"
     43  1.1  mrg #include "tree-ssa-dce.h"
     44  1.1  mrg #include "gimple-fold.h"
     45  1.1  mrg #include "gimple-match.h"
     46  1.1  mrg #include "recog.h"		/* FIXME: for insn_data */
     47  1.1  mrg 
     48  1.1  mrg 
     49  1.1  mrg /* Build a ternary operation and gimplify it.  Emit code before GSI.
     50  1.1  mrg    Return the gimple_val holding the result.  */
     51  1.1  mrg 
     52  1.1  mrg static tree
     53  1.1  mrg gimplify_build3 (gimple_stmt_iterator *gsi, enum tree_code code,
     54  1.1  mrg 		 tree type, tree a, tree b, tree c)
     55  1.1  mrg {
     56  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
     57  1.1  mrg   gimple_seq stmts = NULL;
     58  1.1  mrg   tree ret = gimple_build (&stmts, loc, code, type, a, b, c);
     59  1.1  mrg   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
     60  1.1  mrg   return ret;
     61  1.1  mrg }
     62  1.1  mrg 
     63  1.1  mrg /* Build a binary operation and gimplify it.  Emit code before GSI.
     64  1.1  mrg    Return the gimple_val holding the result.  */
     65  1.1  mrg 
     66  1.1  mrg static tree
     67  1.1  mrg gimplify_build2 (gimple_stmt_iterator *gsi, enum tree_code code,
     68  1.1  mrg 		 tree type, tree a, tree b)
     69  1.1  mrg {
     70  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
     71  1.1  mrg   gimple_seq stmts = NULL;
     72  1.1  mrg   tree ret = gimple_build (&stmts, loc, code, type, a, b);
     73  1.1  mrg   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
     74  1.1  mrg   return ret;
     75  1.1  mrg }
     76  1.1  mrg 
     77  1.1  mrg /* Build a unary operation and gimplify it.  Emit code before GSI.
     78  1.1  mrg    Return the gimple_val holding the result.  */
     79  1.1  mrg 
     80  1.1  mrg static tree
     81  1.1  mrg gimplify_build1 (gimple_stmt_iterator *gsi, enum tree_code code, tree type,
     82  1.1  mrg 		 tree a)
     83  1.1  mrg {
     84  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
     85  1.1  mrg   gimple_seq stmts = NULL;
     86  1.1  mrg   tree ret = gimple_build (&stmts, loc, code, type, a);
     87  1.1  mrg   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
     88  1.1  mrg   return ret;
     89  1.1  mrg }
     90  1.1  mrg 
     91  1.1  mrg 
     92  1.1  mrg static void expand_vector_operations_1 (gimple_stmt_iterator *, bitmap);
     93  1.1  mrg 
     94  1.1  mrg /* Return the number of elements in a vector type TYPE that we have
     95  1.1  mrg    already decided needs to be expanded piecewise.  We don't support
     96  1.1  mrg    this kind of expansion for variable-length vectors, since we should
     97  1.1  mrg    always check for target support before introducing uses of those.  */
     98  1.1  mrg static unsigned int
     99  1.1  mrg nunits_for_known_piecewise_op (const_tree type)
    100  1.1  mrg {
    101  1.1  mrg   return TYPE_VECTOR_SUBPARTS (type).to_constant ();
    102  1.1  mrg }
    103  1.1  mrg 
    104  1.1  mrg /* Return true if TYPE1 has more elements than TYPE2, where either
    105  1.1  mrg    type may be a vector or a scalar.  */
    106  1.1  mrg 
    107  1.1  mrg static inline bool
    108  1.1  mrg subparts_gt (tree type1, tree type2)
    109  1.1  mrg {
    110  1.1  mrg   poly_uint64 n1 = VECTOR_TYPE_P (type1) ? TYPE_VECTOR_SUBPARTS (type1) : 1;
    111  1.1  mrg   poly_uint64 n2 = VECTOR_TYPE_P (type2) ? TYPE_VECTOR_SUBPARTS (type2) : 1;
    112  1.1  mrg   return known_gt (n1, n2);
    113  1.1  mrg }
    114  1.1  mrg 
    115  1.1  mrg /* Build a constant of type TYPE, made of VALUE's bits replicated
    116  1.1  mrg    every WIDTH bits to fit TYPE's precision.  */
    117  1.1  mrg static tree
    118  1.1  mrg build_replicated_const (tree type, unsigned int width, HOST_WIDE_INT value)
    119  1.1  mrg {
    120  1.1  mrg   int n = (TYPE_PRECISION (type) + HOST_BITS_PER_WIDE_INT - 1)
    121  1.1  mrg     / HOST_BITS_PER_WIDE_INT;
    122  1.1  mrg   unsigned HOST_WIDE_INT low, mask;
    123  1.1  mrg   HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
    124  1.1  mrg   int i;
    125  1.1  mrg 
    126  1.1  mrg   gcc_assert (n && n <= WIDE_INT_MAX_ELTS);
    127  1.1  mrg 
    128  1.1  mrg   if (width == HOST_BITS_PER_WIDE_INT)
    129  1.1  mrg     low = value;
    130  1.1  mrg   else
    131  1.1  mrg     {
    132  1.1  mrg       mask = ((HOST_WIDE_INT)1 << width) - 1;
    133  1.1  mrg       low = (unsigned HOST_WIDE_INT) ~0 / mask * (value & mask);
    134  1.1  mrg     }
    135  1.1  mrg 
    136  1.1  mrg   for (i = 0; i < n; i++)
    137  1.1  mrg     a[i] = low;
    138  1.1  mrg 
    139  1.1  mrg   gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT);
    140  1.1  mrg   return wide_int_to_tree
    141  1.1  mrg     (type, wide_int::from_array (a, n, TYPE_PRECISION (type)));
    142  1.1  mrg }
    143  1.1  mrg 
    144  1.1  mrg static GTY(()) tree vector_inner_type;
    145  1.1  mrg static GTY(()) tree vector_last_type;
    146  1.1  mrg static GTY(()) int vector_last_nunits;
    147  1.1  mrg 
    148  1.1  mrg /* Return a suitable vector types made of SUBPARTS units each of mode
    149  1.1  mrg    "word_mode" (the global variable).  */
    150  1.1  mrg static tree
    151  1.1  mrg build_word_mode_vector_type (int nunits)
    152  1.1  mrg {
    153  1.1  mrg   if (!vector_inner_type)
    154  1.1  mrg     vector_inner_type = lang_hooks.types.type_for_mode (word_mode, 1);
    155  1.1  mrg   else if (vector_last_nunits == nunits)
    156  1.1  mrg     {
    157  1.1  mrg       gcc_assert (TREE_CODE (vector_last_type) == VECTOR_TYPE);
    158  1.1  mrg       return vector_last_type;
    159  1.1  mrg     }
    160  1.1  mrg 
    161  1.1  mrg   vector_last_nunits = nunits;
    162  1.1  mrg   vector_last_type = build_vector_type (vector_inner_type, nunits);
    163  1.1  mrg   return vector_last_type;
    164  1.1  mrg }
    165  1.1  mrg 
    166  1.1  mrg typedef tree (*elem_op_func) (gimple_stmt_iterator *,
    167  1.1  mrg 			      tree, tree, tree, tree, tree, enum tree_code,
    168  1.1  mrg 			      tree);
    169  1.1  mrg 
    170  1.1  mrg /* Extract the vector element of type TYPE at BITPOS with BITSIZE from T
    171  1.1  mrg    and return it.  */
    172  1.1  mrg 
    173  1.1  mrg tree
    174  1.1  mrg tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
    175  1.1  mrg 		  tree t, tree bitsize, tree bitpos)
    176  1.1  mrg {
    177  1.1  mrg   /* We're using the resimplify API and maybe_push_res_to_seq to
    178  1.1  mrg      simplify the BIT_FIELD_REF but restrict the simplification to
    179  1.1  mrg      a single stmt while at the same time following SSA edges for
    180  1.1  mrg      simplification with already emitted CTORs.  */
    181  1.1  mrg   gimple_match_op opr;
    182  1.1  mrg   opr.set_op (BIT_FIELD_REF, type, t, bitsize, bitpos);
    183  1.1  mrg   opr.resimplify (NULL, follow_all_ssa_edges);
    184  1.1  mrg   gimple_seq stmts = NULL;
    185  1.1  mrg   tree res = maybe_push_res_to_seq (&opr, &stmts);
    186  1.1  mrg   if (!res)
    187  1.1  mrg     {
    188  1.1  mrg       /* This can happen if SSA_NAME_OCCURS_IN_ABNORMAL_PHI are
    189  1.1  mrg 	 used.  Build BIT_FIELD_REF manually otherwise.  */
    190  1.1  mrg       t = build3 (BIT_FIELD_REF, type, t, bitsize, bitpos);
    191  1.1  mrg       res = make_ssa_name (type);
    192  1.1  mrg       gimple *g = gimple_build_assign (res, t);
    193  1.1  mrg       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    194  1.1  mrg       return res;
    195  1.1  mrg     }
    196  1.1  mrg   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    197  1.1  mrg   return res;
    198  1.1  mrg }
    199  1.1  mrg 
    200  1.1  mrg static tree
    201  1.1  mrg do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
    202  1.1  mrg 	 tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
    203  1.1  mrg 	 enum tree_code code, tree type ATTRIBUTE_UNUSED)
    204  1.1  mrg {
    205  1.1  mrg   tree rhs_type = inner_type;
    206  1.1  mrg 
    207  1.1  mrg   /* For ABSU_EXPR, use the signed type for the rhs if the rhs was signed. */
    208  1.1  mrg   if (code == ABSU_EXPR
    209  1.1  mrg       && ANY_INTEGRAL_TYPE_P (TREE_TYPE (a))
    210  1.1  mrg       && !TYPE_UNSIGNED (TREE_TYPE (a)))
    211  1.1  mrg     rhs_type = signed_type_for (rhs_type);
    212  1.1  mrg 
    213  1.1  mrg   a = tree_vec_extract (gsi, rhs_type, a, bitsize, bitpos);
    214  1.1  mrg   return gimplify_build1 (gsi, code, inner_type, a);
    215  1.1  mrg }
    216  1.1  mrg 
    217  1.1  mrg static tree
    218  1.1  mrg do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
    219  1.1  mrg 	  tree bitpos, tree bitsize, enum tree_code code,
    220  1.1  mrg 	  tree type ATTRIBUTE_UNUSED)
    221  1.1  mrg {
    222  1.1  mrg   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
    223  1.1  mrg     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
    224  1.1  mrg   if (TREE_CODE (TREE_TYPE (b)) == VECTOR_TYPE)
    225  1.1  mrg     b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
    226  1.1  mrg   return gimplify_build2 (gsi, code, inner_type, a, b);
    227  1.1  mrg }
    228  1.1  mrg 
    229  1.1  mrg /* Construct expression (A[BITPOS] code B[BITPOS]) ? -1 : 0
    230  1.1  mrg 
    231  1.1  mrg    INNER_TYPE is the type of A and B elements
    232  1.1  mrg 
    233  1.1  mrg    returned expression is of signed integer type with the
    234  1.1  mrg    size equal to the size of INNER_TYPE.  */
    235  1.1  mrg static tree
    236  1.1  mrg do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
    237  1.1  mrg 	    tree bitpos, tree bitsize, enum tree_code code, tree type)
    238  1.1  mrg {
    239  1.1  mrg   tree stype = TREE_TYPE (type);
    240  1.1  mrg   tree cst_false = build_zero_cst (stype);
    241  1.1  mrg   tree cst_true = build_all_ones_cst (stype);
    242  1.1  mrg   tree cmp;
    243  1.1  mrg 
    244  1.1  mrg   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
    245  1.1  mrg   b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
    246  1.1  mrg 
    247  1.1  mrg   cmp = build2 (code, boolean_type_node, a, b);
    248  1.1  mrg   return gimplify_build3 (gsi, COND_EXPR, stype, cmp, cst_true, cst_false);
    249  1.1  mrg }
    250  1.1  mrg 
    251  1.1  mrg /* Expand vector addition to scalars.  This does bit twiddling
    252  1.1  mrg    in order to increase parallelism:
    253  1.1  mrg 
    254  1.1  mrg    a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
    255  1.1  mrg            (a ^ b) & 0x80808080
    256  1.1  mrg 
    257  1.1  mrg    a - b =  (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
    258  1.1  mrg             (a ^ ~b) & 0x80808080
    259  1.1  mrg 
    260  1.1  mrg    -b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
    261  1.1  mrg 
    262  1.1  mrg    This optimization should be done only if 4 vector items or more
    263  1.1  mrg    fit into a word.  */
    264  1.1  mrg static tree
    265  1.1  mrg do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
    266  1.1  mrg 	       tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
    267  1.1  mrg 	       enum tree_code code, tree type ATTRIBUTE_UNUSED)
    268  1.1  mrg {
    269  1.1  mrg   unsigned int width = vector_element_bits (TREE_TYPE (a));
    270  1.1  mrg   tree inner_type = TREE_TYPE (TREE_TYPE (a));
    271  1.1  mrg   unsigned HOST_WIDE_INT max;
    272  1.1  mrg   tree low_bits, high_bits, a_low, b_low, result_low, signs;
    273  1.1  mrg 
    274  1.1  mrg   max = GET_MODE_MASK (TYPE_MODE (inner_type));
    275  1.1  mrg   low_bits = build_replicated_const (word_type, width, max >> 1);
    276  1.1  mrg   high_bits = build_replicated_const (word_type, width, max & ~(max >> 1));
    277  1.1  mrg 
    278  1.1  mrg   a = tree_vec_extract (gsi, word_type, a, bitsize, bitpos);
    279  1.1  mrg   b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
    280  1.1  mrg 
    281  1.1  mrg   signs = gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, a, b);
    282  1.1  mrg   b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
    283  1.1  mrg   if (code == PLUS_EXPR)
    284  1.1  mrg     a_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, a, low_bits);
    285  1.1  mrg   else
    286  1.1  mrg     {
    287  1.1  mrg       a_low = gimplify_build2 (gsi, BIT_IOR_EXPR, word_type, a, high_bits);
    288  1.1  mrg       signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, signs);
    289  1.1  mrg     }
    290  1.1  mrg 
    291  1.1  mrg   signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
    292  1.1  mrg   result_low = gimplify_build2 (gsi, code, word_type, a_low, b_low);
    293  1.1  mrg   return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
    294  1.1  mrg }
    295  1.1  mrg 
    296  1.1  mrg static tree
    297  1.1  mrg do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
    298  1.1  mrg 	   tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
    299  1.1  mrg 	   tree bitsize ATTRIBUTE_UNUSED,
    300  1.1  mrg 	   enum tree_code code ATTRIBUTE_UNUSED,
    301  1.1  mrg 	   tree type ATTRIBUTE_UNUSED)
    302  1.1  mrg {
    303  1.1  mrg   unsigned int width = vector_element_bits (TREE_TYPE (b));
    304  1.1  mrg   tree inner_type = TREE_TYPE (TREE_TYPE (b));
    305  1.1  mrg   HOST_WIDE_INT max;
    306  1.1  mrg   tree low_bits, high_bits, b_low, result_low, signs;
    307  1.1  mrg 
    308  1.1  mrg   max = GET_MODE_MASK (TYPE_MODE (inner_type));
    309  1.1  mrg   low_bits = build_replicated_const (word_type, width, max >> 1);
    310  1.1  mrg   high_bits = build_replicated_const (word_type, width, max & ~(max >> 1));
    311  1.1  mrg 
    312  1.1  mrg   b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
    313  1.1  mrg 
    314  1.1  mrg   b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
    315  1.1  mrg   signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, b);
    316  1.1  mrg   signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
    317  1.1  mrg   result_low = gimplify_build2 (gsi, MINUS_EXPR, word_type, high_bits, b_low);
    318  1.1  mrg   return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
    319  1.1  mrg }
    320  1.1  mrg 
    321  1.1  mrg /* Expand a vector operation to scalars, by using many operations
    322  1.1  mrg    whose type is the vector type's inner type.  */
    323  1.1  mrg static tree
    324  1.1  mrg expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
    325  1.1  mrg 			 tree type, tree inner_type,
    326  1.1  mrg 			 tree a, tree b, enum tree_code code,
    327  1.1  mrg 			 bool parallel_p, tree ret_type = NULL_TREE)
    328  1.1  mrg {
    329  1.1  mrg   vec<constructor_elt, va_gc> *v;
    330  1.1  mrg   tree part_width = TYPE_SIZE (inner_type);
    331  1.1  mrg   tree index = bitsize_int (0);
    332  1.1  mrg   int nunits = nunits_for_known_piecewise_op (type);
    333  1.1  mrg   int delta = tree_to_uhwi (part_width) / vector_element_bits (type);
    334  1.1  mrg   int i;
    335  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
    336  1.1  mrg 
    337  1.1  mrg   if (nunits == 1
    338  1.1  mrg       || warning_suppressed_p (gsi_stmt (*gsi),
    339  1.1  mrg 			       OPT_Wvector_operation_performance))
    340  1.1  mrg     /* Do not diagnose decomposing single element vectors or when
    341  1.1  mrg        decomposing vectorizer produced operations.  */
    342  1.1  mrg     ;
    343  1.1  mrg   else if (ret_type || !parallel_p)
    344  1.1  mrg     warning_at (loc, OPT_Wvector_operation_performance,
    345  1.1  mrg 		"vector operation will be expanded piecewise");
    346  1.1  mrg   else
    347  1.1  mrg     warning_at (loc, OPT_Wvector_operation_performance,
    348  1.1  mrg 		"vector operation will be expanded in parallel");
    349  1.1  mrg 
    350  1.1  mrg   if (!ret_type)
    351  1.1  mrg     ret_type = type;
    352  1.1  mrg   vec_alloc (v, (nunits + delta - 1) / delta);
    353  1.1  mrg   bool constant_p = true;
    354  1.1  mrg   for (i = 0; i < nunits;
    355  1.1  mrg        i += delta, index = int_const_binop (PLUS_EXPR, index, part_width))
    356  1.1  mrg     {
    357  1.1  mrg       tree result = f (gsi, inner_type, a, b, index, part_width, code,
    358  1.1  mrg 		       ret_type);
    359  1.1  mrg       if (!CONSTANT_CLASS_P (result))
    360  1.1  mrg 	constant_p = false;
    361  1.1  mrg       constructor_elt ce = {NULL_TREE, result};
    362  1.1  mrg       v->quick_push (ce);
    363  1.1  mrg     }
    364  1.1  mrg 
    365  1.1  mrg   if (constant_p)
    366  1.1  mrg     return build_vector_from_ctor (ret_type, v);
    367  1.1  mrg   else
    368  1.1  mrg     return build_constructor (ret_type, v);
    369  1.1  mrg }
    370  1.1  mrg 
    371  1.1  mrg /* Expand a vector operation to scalars with the freedom to use
    372  1.1  mrg    a scalar integer type, or to use a different size for the items
    373  1.1  mrg    in the vector type.  */
    374  1.1  mrg static tree
    375  1.1  mrg expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type,
    376  1.1  mrg 			tree a, tree b, enum tree_code code)
    377  1.1  mrg {
    378  1.1  mrg   tree result, compute_type;
    379  1.1  mrg   int n_words = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
    380  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
    381  1.1  mrg 
    382  1.1  mrg   /* We have three strategies.  If the type is already correct, just do
    383  1.1  mrg      the operation an element at a time.  Else, if the vector is wider than
    384  1.1  mrg      one word, do it a word at a time; finally, if the vector is smaller
    385  1.1  mrg      than one word, do it as a scalar.  */
    386  1.1  mrg   if (TYPE_MODE (TREE_TYPE (type)) == word_mode)
    387  1.1  mrg      return expand_vector_piecewise (gsi, f,
    388  1.1  mrg 				     type, TREE_TYPE (type),
    389  1.1  mrg 				     a, b, code, true);
    390  1.1  mrg   else if (n_words > 1)
    391  1.1  mrg     {
    392  1.1  mrg       tree word_type = build_word_mode_vector_type (n_words);
    393  1.1  mrg       result = expand_vector_piecewise (gsi, f,
    394  1.1  mrg 				        word_type, TREE_TYPE (word_type),
    395  1.1  mrg 					a, b, code, true);
    396  1.1  mrg       result = force_gimple_operand_gsi (gsi, result, true, NULL, true,
    397  1.1  mrg                                          GSI_SAME_STMT);
    398  1.1  mrg     }
    399  1.1  mrg   else
    400  1.1  mrg     {
    401  1.1  mrg       /* Use a single scalar operation with a mode no wider than word_mode.  */
    402  1.1  mrg       if (!warning_suppressed_p (gsi_stmt (*gsi),
    403  1.1  mrg 				 OPT_Wvector_operation_performance))
    404  1.1  mrg 	warning_at (loc, OPT_Wvector_operation_performance,
    405  1.1  mrg 		    "vector operation will be expanded with a "
    406  1.1  mrg 		    "single scalar operation");
    407  1.1  mrg       scalar_int_mode mode
    408  1.1  mrg 	= int_mode_for_size (tree_to_uhwi (TYPE_SIZE (type)), 0).require ();
    409  1.1  mrg       compute_type = lang_hooks.types.type_for_mode (mode, 1);
    410  1.1  mrg       result = f (gsi, compute_type, a, b, bitsize_zero_node,
    411  1.1  mrg 		  TYPE_SIZE (compute_type), code, type);
    412  1.1  mrg     }
    413  1.1  mrg 
    414  1.1  mrg   return result;
    415  1.1  mrg }
    416  1.1  mrg 
    417  1.1  mrg /* Expand a vector operation to scalars; for integer types we can use
    418  1.1  mrg    special bit twiddling tricks to do the sums a word at a time, using
    419  1.1  mrg    function F_PARALLEL instead of F.  These tricks are done only if
    420  1.1  mrg    they can process at least four items, that is, only if the vector
    421  1.1  mrg    holds at least four items and if a word can hold four items.  */
    422  1.1  mrg static tree
    423  1.1  mrg expand_vector_addition (gimple_stmt_iterator *gsi,
    424  1.1  mrg 			elem_op_func f, elem_op_func f_parallel,
    425  1.1  mrg 			tree type, tree a, tree b, enum tree_code code)
    426  1.1  mrg {
    427  1.1  mrg   int parts_per_word = BITS_PER_WORD / vector_element_bits (type);
    428  1.1  mrg 
    429  1.1  mrg   if (INTEGRAL_TYPE_P (TREE_TYPE (type))
    430  1.1  mrg       && parts_per_word >= 4
    431  1.1  mrg       && nunits_for_known_piecewise_op (type) >= 4)
    432  1.1  mrg     return expand_vector_parallel (gsi, f_parallel,
    433  1.1  mrg 				   type, a, b, code);
    434  1.1  mrg   else
    435  1.1  mrg     return expand_vector_piecewise (gsi, f,
    436  1.1  mrg 				    type, TREE_TYPE (type),
    437  1.1  mrg 				    a, b, code, false);
    438  1.1  mrg }
    439  1.1  mrg 
    440  1.1  mrg static bool
    441  1.1  mrg expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names);
    442  1.1  mrg 
    443  1.1  mrg /* Try to expand vector comparison expression OP0 CODE OP1 by
    444  1.1  mrg    querying optab if the following expression:
    445  1.1  mrg 	VEC_COND_EXPR< OP0 CODE OP1, {-1,...}, {0,...}>
    446  1.1  mrg    can be expanded.  */
    447  1.1  mrg static tree
    448  1.1  mrg expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
    449  1.1  mrg 			  tree op1, enum tree_code code,
    450  1.1  mrg 			  bitmap dce_ssa_names)
    451  1.1  mrg {
    452  1.1  mrg   tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
    453  1.1  mrg   use_operand_p use_p;
    454  1.1  mrg   imm_use_iterator iterator;
    455  1.1  mrg   bool vec_cond_expr_only = true;
    456  1.1  mrg 
    457  1.1  mrg   /* As seen in PR95830, we should not expand comparisons that are only
    458  1.1  mrg      feeding a VEC_COND_EXPR statement.  */
    459  1.1  mrg   auto_vec<gimple *> uses;
    460  1.1  mrg   FOR_EACH_IMM_USE_FAST (use_p, iterator, lhs)
    461  1.1  mrg     {
    462  1.1  mrg       gimple *use = USE_STMT (use_p);
    463  1.1  mrg       if (is_gimple_debug (use))
    464  1.1  mrg 	continue;
    465  1.1  mrg       if (is_gimple_assign (use)
    466  1.1  mrg 	  && gimple_assign_rhs_code (use) == VEC_COND_EXPR
    467  1.1  mrg 	  && gimple_assign_rhs1 (use) == lhs
    468  1.1  mrg 	  && gimple_assign_rhs2 (use) != lhs
    469  1.1  mrg 	  && gimple_assign_rhs3 (use) != lhs)
    470  1.1  mrg 	uses.safe_push (use);
    471  1.1  mrg       else
    472  1.1  mrg 	vec_cond_expr_only = false;
    473  1.1  mrg     }
    474  1.1  mrg 
    475  1.1  mrg   if (vec_cond_expr_only)
    476  1.1  mrg     for (gimple *use : uses)
    477  1.1  mrg       {
    478  1.1  mrg 	gimple_stmt_iterator it = gsi_for_stmt (use);
    479  1.1  mrg 	if (!expand_vector_condition (&it, dce_ssa_names))
    480  1.1  mrg 	  {
    481  1.1  mrg 	    vec_cond_expr_only = false;
    482  1.1  mrg 	    break;
    483  1.1  mrg 	  }
    484  1.1  mrg       }
    485  1.1  mrg 
    486  1.1  mrg   if (!uses.is_empty () && vec_cond_expr_only)
    487  1.1  mrg     return NULL_TREE;
    488  1.1  mrg 
    489  1.1  mrg   tree t;
    490  1.1  mrg   if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code))
    491  1.1  mrg     {
    492  1.1  mrg       if (VECTOR_BOOLEAN_TYPE_P (type)
    493  1.1  mrg 	  && SCALAR_INT_MODE_P (TYPE_MODE (type))
    494  1.1  mrg 	  && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),
    495  1.1  mrg 		       TYPE_VECTOR_SUBPARTS (type)
    496  1.1  mrg 		       * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
    497  1.1  mrg 						(TREE_TYPE (type)))))
    498  1.1  mrg 	{
    499  1.1  mrg 	  tree inner_type = TREE_TYPE (TREE_TYPE (op0));
    500  1.1  mrg 	  tree part_width = vector_element_bits_tree (TREE_TYPE (op0));
    501  1.1  mrg 	  tree index = bitsize_int (0);
    502  1.1  mrg 	  int nunits = nunits_for_known_piecewise_op (TREE_TYPE (op0));
    503  1.1  mrg 	  int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (type));
    504  1.1  mrg 	  tree ret_type = build_nonstandard_integer_type (prec, 1);
    505  1.1  mrg 	  tree ret_inner_type = boolean_type_node;
    506  1.1  mrg 	  int i;
    507  1.1  mrg 	  location_t loc = gimple_location (gsi_stmt (*gsi));
    508  1.1  mrg 	  t = build_zero_cst (ret_type);
    509  1.1  mrg 
    510  1.1  mrg 	  if (TYPE_PRECISION (ret_inner_type) != 1)
    511  1.1  mrg 	    ret_inner_type = build_nonstandard_integer_type (1, 1);
    512  1.1  mrg 	  if (!warning_suppressed_p (gsi_stmt (*gsi),
    513  1.1  mrg 				     OPT_Wvector_operation_performance))
    514  1.1  mrg 	    warning_at (loc, OPT_Wvector_operation_performance,
    515  1.1  mrg 			"vector operation will be expanded piecewise");
    516  1.1  mrg 	  for (i = 0; i < nunits;
    517  1.1  mrg 	       i++, index = int_const_binop (PLUS_EXPR, index, part_width))
    518  1.1  mrg 	    {
    519  1.1  mrg 	      tree a = tree_vec_extract (gsi, inner_type, op0, part_width,
    520  1.1  mrg 					 index);
    521  1.1  mrg 	      tree b = tree_vec_extract (gsi, inner_type, op1, part_width,
    522  1.1  mrg 					 index);
    523  1.1  mrg 	      tree result = gimplify_build2 (gsi, code, ret_inner_type, a, b);
    524  1.1  mrg 	      t = gimplify_build3 (gsi, BIT_INSERT_EXPR, ret_type, t, result,
    525  1.1  mrg 				   bitsize_int (i));
    526  1.1  mrg 	    }
    527  1.1  mrg 	  t = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
    528  1.1  mrg 	}
    529  1.1  mrg       else
    530  1.1  mrg 	t = expand_vector_piecewise (gsi, do_compare, type,
    531  1.1  mrg 				     TREE_TYPE (TREE_TYPE (op0)), op0, op1,
    532  1.1  mrg 				     code, false);
    533  1.1  mrg     }
    534  1.1  mrg   else
    535  1.1  mrg     t = NULL_TREE;
    536  1.1  mrg 
    537  1.1  mrg   return t;
    538  1.1  mrg }
    539  1.1  mrg 
    540  1.1  mrg /* Helper function of expand_vector_divmod.  Gimplify a RSHIFT_EXPR in type
    541  1.1  mrg    of OP0 with shift counts in SHIFTCNTS array and return the temporary holding
    542  1.1  mrg    the result if successful, otherwise return NULL_TREE.  */
    543  1.1  mrg static tree
    544  1.1  mrg add_rshift (gimple_stmt_iterator *gsi, tree type, tree op0, int *shiftcnts)
    545  1.1  mrg {
    546  1.1  mrg   optab op;
    547  1.1  mrg   unsigned int i, nunits = nunits_for_known_piecewise_op (type);
    548  1.1  mrg   bool scalar_shift = true;
    549  1.1  mrg 
    550  1.1  mrg   for (i = 1; i < nunits; i++)
    551  1.1  mrg     {
    552  1.1  mrg       if (shiftcnts[i] != shiftcnts[0])
    553  1.1  mrg 	scalar_shift = false;
    554  1.1  mrg     }
    555  1.1  mrg 
    556  1.1  mrg   if (scalar_shift && shiftcnts[0] == 0)
    557  1.1  mrg     return op0;
    558  1.1  mrg 
    559  1.1  mrg   if (scalar_shift)
    560  1.1  mrg     {
    561  1.1  mrg       op = optab_for_tree_code (RSHIFT_EXPR, type, optab_scalar);
    562  1.1  mrg       if (op != unknown_optab
    563  1.1  mrg 	  && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
    564  1.1  mrg 	return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0,
    565  1.1  mrg 				build_int_cst (NULL_TREE, shiftcnts[0]));
    566  1.1  mrg     }
    567  1.1  mrg 
    568  1.1  mrg   op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
    569  1.1  mrg   if (op != unknown_optab
    570  1.1  mrg       && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
    571  1.1  mrg     {
    572  1.1  mrg       tree_vector_builder vec (type, nunits, 1);
    573  1.1  mrg       for (i = 0; i < nunits; i++)
    574  1.1  mrg 	vec.quick_push (build_int_cst (TREE_TYPE (type), shiftcnts[i]));
    575  1.1  mrg       return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0, vec.build ());
    576  1.1  mrg     }
    577  1.1  mrg 
    578  1.1  mrg   return NULL_TREE;
    579  1.1  mrg }
    580  1.1  mrg 
    581  1.1  mrg /* Try to expand integer vector division by constant using
    582  1.1  mrg    widening multiply, shifts and additions.  */
    583  1.1  mrg static tree
    584  1.1  mrg expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
    585  1.1  mrg 		      tree op1, enum tree_code code)
    586  1.1  mrg {
    587  1.1  mrg   bool use_pow2 = true;
    588  1.1  mrg   bool has_vector_shift = true;
    589  1.1  mrg   bool use_abs_op1 = false;
    590  1.1  mrg   int mode = -1, this_mode;
    591  1.1  mrg   int pre_shift = -1, post_shift;
    592  1.1  mrg   unsigned int nunits = nunits_for_known_piecewise_op (type);
    593  1.1  mrg   int *shifts = XALLOCAVEC (int, nunits * 4);
    594  1.1  mrg   int *pre_shifts = shifts + nunits;
    595  1.1  mrg   int *post_shifts = pre_shifts + nunits;
    596  1.1  mrg   int *shift_temps = post_shifts + nunits;
    597  1.1  mrg   unsigned HOST_WIDE_INT *mulc = XALLOCAVEC (unsigned HOST_WIDE_INT, nunits);
    598  1.1  mrg   int prec = TYPE_PRECISION (TREE_TYPE (type));
    599  1.1  mrg   int dummy_int;
    600  1.1  mrg   unsigned int i;
    601  1.1  mrg   signop sign_p = TYPE_SIGN (TREE_TYPE (type));
    602  1.1  mrg   unsigned HOST_WIDE_INT mask = GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type)));
    603  1.1  mrg   tree cur_op, mulcst, tem;
    604  1.1  mrg   optab op;
    605  1.1  mrg 
    606  1.1  mrg   if (prec > HOST_BITS_PER_WIDE_INT)
    607  1.1  mrg     return NULL_TREE;
    608  1.1  mrg 
    609  1.1  mrg   op = optab_for_tree_code (RSHIFT_EXPR, type, optab_vector);
    610  1.1  mrg   if (op == unknown_optab
    611  1.1  mrg       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
    612  1.1  mrg     has_vector_shift = false;
    613  1.1  mrg 
    614  1.1  mrg   /* Analysis phase.  Determine if all op1 elements are either power
    615  1.1  mrg      of two and it is possible to expand it using shifts (or for remainder
    616  1.1  mrg      using masking).  Additionally compute the multiplicative constants
    617  1.1  mrg      and pre and post shifts if the division is to be expanded using
    618  1.1  mrg      widening or high part multiplication plus shifts.  */
    619  1.1  mrg   for (i = 0; i < nunits; i++)
    620  1.1  mrg     {
    621  1.1  mrg       tree cst = VECTOR_CST_ELT (op1, i);
    622  1.1  mrg       unsigned HOST_WIDE_INT ml;
    623  1.1  mrg 
    624  1.1  mrg       if (TREE_CODE (cst) != INTEGER_CST || integer_zerop (cst))
    625  1.1  mrg 	return NULL_TREE;
    626  1.1  mrg       pre_shifts[i] = 0;
    627  1.1  mrg       post_shifts[i] = 0;
    628  1.1  mrg       mulc[i] = 0;
    629  1.1  mrg       if (use_pow2
    630  1.1  mrg 	  && (!integer_pow2p (cst) || tree_int_cst_sgn (cst) != 1))
    631  1.1  mrg 	use_pow2 = false;
    632  1.1  mrg       if (use_pow2)
    633  1.1  mrg 	{
    634  1.1  mrg 	  shifts[i] = tree_log2 (cst);
    635  1.1  mrg 	  if (shifts[i] != shifts[0]
    636  1.1  mrg 	      && code == TRUNC_DIV_EXPR
    637  1.1  mrg 	      && !has_vector_shift)
    638  1.1  mrg 	    use_pow2 = false;
    639  1.1  mrg 	}
    640  1.1  mrg       if (mode == -2)
    641  1.1  mrg 	continue;
    642  1.1  mrg       if (sign_p == UNSIGNED)
    643  1.1  mrg 	{
    644  1.1  mrg 	  unsigned HOST_WIDE_INT mh;
    645  1.1  mrg 	  unsigned HOST_WIDE_INT d = TREE_INT_CST_LOW (cst) & mask;
    646  1.1  mrg 
    647  1.1  mrg 	  if (d >= (HOST_WIDE_INT_1U << (prec - 1)))
    648  1.1  mrg 	    /* FIXME: Can transform this into op0 >= op1 ? 1 : 0.  */
    649  1.1  mrg 	    return NULL_TREE;
    650  1.1  mrg 
    651  1.1  mrg 	  if (d <= 1)
    652  1.1  mrg 	    {
    653  1.1  mrg 	      mode = -2;
    654  1.1  mrg 	      continue;
    655  1.1  mrg 	    }
    656  1.1  mrg 
    657  1.1  mrg 	  /* Find a suitable multiplier and right shift count
    658  1.1  mrg 	     instead of multiplying with D.  */
    659  1.1  mrg 	  mh = choose_multiplier (d, prec, prec, &ml, &post_shift, &dummy_int);
    660  1.1  mrg 
    661  1.1  mrg 	  /* If the suggested multiplier is more than SIZE bits, we can
    662  1.1  mrg 	     do better for even divisors, using an initial right shift.  */
    663  1.1  mrg 	  if ((mh != 0 && (d & 1) == 0)
    664  1.1  mrg 	      || (!has_vector_shift && pre_shift != -1))
    665  1.1  mrg 	    {
    666  1.1  mrg 	      if (has_vector_shift)
    667  1.1  mrg 		pre_shift = ctz_or_zero (d);
    668  1.1  mrg 	      else if (pre_shift == -1)
    669  1.1  mrg 		{
    670  1.1  mrg 		  unsigned int j;
    671  1.1  mrg 		  for (j = 0; j < nunits; j++)
    672  1.1  mrg 		    {
    673  1.1  mrg 		      tree cst2 = VECTOR_CST_ELT (op1, j);
    674  1.1  mrg 		      unsigned HOST_WIDE_INT d2;
    675  1.1  mrg 		      int this_pre_shift;
    676  1.1  mrg 
    677  1.1  mrg 		      if (!tree_fits_uhwi_p (cst2))
    678  1.1  mrg 			return NULL_TREE;
    679  1.1  mrg 		      d2 = tree_to_uhwi (cst2) & mask;
    680  1.1  mrg 		      if (d2 == 0)
    681  1.1  mrg 			return NULL_TREE;
    682  1.1  mrg 		      this_pre_shift = floor_log2 (d2 & -d2);
    683  1.1  mrg 		      if (pre_shift == -1 || this_pre_shift < pre_shift)
    684  1.1  mrg 			pre_shift = this_pre_shift;
    685  1.1  mrg 		    }
    686  1.1  mrg 		  if (i != 0 && pre_shift != 0)
    687  1.1  mrg 		    {
    688  1.1  mrg 		      /* Restart.  */
    689  1.1  mrg 		      i = -1U;
    690  1.1  mrg 		      mode = -1;
    691  1.1  mrg 		      continue;
    692  1.1  mrg 		    }
    693  1.1  mrg 		}
    694  1.1  mrg 	      if (pre_shift != 0)
    695  1.1  mrg 		{
    696  1.1  mrg 		  if ((d >> pre_shift) <= 1)
    697  1.1  mrg 		    {
    698  1.1  mrg 		      mode = -2;
    699  1.1  mrg 		      continue;
    700  1.1  mrg 		    }
    701  1.1  mrg 		  mh = choose_multiplier (d >> pre_shift, prec,
    702  1.1  mrg 					  prec - pre_shift,
    703  1.1  mrg 					  &ml, &post_shift, &dummy_int);
    704  1.1  mrg 		  gcc_assert (!mh);
    705  1.1  mrg 		  pre_shifts[i] = pre_shift;
    706  1.1  mrg 		}
    707  1.1  mrg 	    }
    708  1.1  mrg 	  if (!mh)
    709  1.1  mrg 	    this_mode = 0;
    710  1.1  mrg 	  else
    711  1.1  mrg 	    this_mode = 1;
    712  1.1  mrg 	}
    713  1.1  mrg       else
    714  1.1  mrg 	{
    715  1.1  mrg 	  HOST_WIDE_INT d = TREE_INT_CST_LOW (cst);
    716  1.1  mrg 	  unsigned HOST_WIDE_INT abs_d;
    717  1.1  mrg 
    718  1.1  mrg 	  if (d == -1)
    719  1.1  mrg 	    return NULL_TREE;
    720  1.1  mrg 
    721  1.1  mrg 	  /* Since d might be INT_MIN, we have to cast to
    722  1.1  mrg 	     unsigned HOST_WIDE_INT before negating to avoid
    723  1.1  mrg 	     undefined signed overflow.  */
    724  1.1  mrg 	  abs_d = (d >= 0
    725  1.1  mrg 		  ? (unsigned HOST_WIDE_INT) d
    726  1.1  mrg 		  : - (unsigned HOST_WIDE_INT) d);
    727  1.1  mrg 
    728  1.1  mrg 	  /* n rem d = n rem -d */
    729  1.1  mrg 	  if (code == TRUNC_MOD_EXPR && d < 0)
    730  1.1  mrg 	    {
    731  1.1  mrg 	      d = abs_d;
    732  1.1  mrg 	      use_abs_op1 = true;
    733  1.1  mrg 	    }
    734  1.1  mrg 	  if (abs_d == HOST_WIDE_INT_1U << (prec - 1))
    735  1.1  mrg 	    {
    736  1.1  mrg 	      /* This case is not handled correctly below.  */
    737  1.1  mrg 	      mode = -2;
    738  1.1  mrg 	      continue;
    739  1.1  mrg 	    }
    740  1.1  mrg 	  if (abs_d <= 1)
    741  1.1  mrg 	    {
    742  1.1  mrg 	      mode = -2;
    743  1.1  mrg 	      continue;
    744  1.1  mrg 	    }
    745  1.1  mrg 
    746  1.1  mrg 	  choose_multiplier (abs_d, prec, prec - 1, &ml,
    747  1.1  mrg 			     &post_shift, &dummy_int);
    748  1.1  mrg 	  if (ml >= HOST_WIDE_INT_1U << (prec - 1))
    749  1.1  mrg 	    {
    750  1.1  mrg 	      this_mode = 4 + (d < 0);
    751  1.1  mrg 	      ml |= HOST_WIDE_INT_M1U << (prec - 1);
    752  1.1  mrg 	    }
    753  1.1  mrg 	  else
    754  1.1  mrg 	    this_mode = 2 + (d < 0);
    755  1.1  mrg 	}
    756  1.1  mrg       mulc[i] = ml;
    757  1.1  mrg       post_shifts[i] = post_shift;
    758  1.1  mrg       if ((i && !has_vector_shift && post_shifts[0] != post_shift)
    759  1.1  mrg 	  || post_shift >= prec
    760  1.1  mrg 	  || pre_shifts[i] >= prec)
    761  1.1  mrg 	this_mode = -2;
    762  1.1  mrg 
    763  1.1  mrg       if (i == 0)
    764  1.1  mrg 	mode = this_mode;
    765  1.1  mrg       else if (mode != this_mode)
    766  1.1  mrg 	mode = -2;
    767  1.1  mrg     }
    768  1.1  mrg 
    769  1.1  mrg   if (use_pow2)
    770  1.1  mrg     {
    771  1.1  mrg       tree addend = NULL_TREE;
    772  1.1  mrg       if (sign_p == SIGNED)
    773  1.1  mrg 	{
    774  1.1  mrg 	  tree uns_type;
    775  1.1  mrg 
    776  1.1  mrg 	  /* Both division and remainder sequences need
    777  1.1  mrg 	     op0 < 0 ? mask : 0 computed.  It can be either computed as
    778  1.1  mrg 	     (type) (((uns_type) (op0 >> (prec - 1))) >> (prec - shifts[i]))
    779  1.1  mrg 	     if none of the shifts is 0, or as the conditional.  */
    780  1.1  mrg 	  for (i = 0; i < nunits; i++)
    781  1.1  mrg 	    if (shifts[i] == 0)
    782  1.1  mrg 	      break;
    783  1.1  mrg 	  uns_type
    784  1.1  mrg 	    = build_vector_type (build_nonstandard_integer_type (prec, 1),
    785  1.1  mrg 				 nunits);
    786  1.1  mrg 	  if (i == nunits && TYPE_MODE (uns_type) == TYPE_MODE (type))
    787  1.1  mrg 	    {
    788  1.1  mrg 	      for (i = 0; i < nunits; i++)
    789  1.1  mrg 		shift_temps[i] = prec - 1;
    790  1.1  mrg 	      cur_op = add_rshift (gsi, type, op0, shift_temps);
    791  1.1  mrg 	      if (cur_op != NULL_TREE)
    792  1.1  mrg 		{
    793  1.1  mrg 		  cur_op = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
    794  1.1  mrg 					    uns_type, cur_op);
    795  1.1  mrg 		  for (i = 0; i < nunits; i++)
    796  1.1  mrg 		    shift_temps[i] = prec - shifts[i];
    797  1.1  mrg 		  cur_op = add_rshift (gsi, uns_type, cur_op, shift_temps);
    798  1.1  mrg 		  if (cur_op != NULL_TREE)
    799  1.1  mrg 		    addend = gimplify_build1 (gsi, VIEW_CONVERT_EXPR,
    800  1.1  mrg 					      type, cur_op);
    801  1.1  mrg 		}
    802  1.1  mrg 	    }
    803  1.1  mrg 	  if (addend == NULL_TREE
    804  1.1  mrg 	      && expand_vec_cond_expr_p (type, type, LT_EXPR))
    805  1.1  mrg 	    {
    806  1.1  mrg 	      tree zero, cst, mask_type, mask;
    807  1.1  mrg 	      gimple *stmt, *cond;
    808  1.1  mrg 
    809  1.1  mrg 	      mask_type = truth_type_for (type);
    810  1.1  mrg 	      zero = build_zero_cst (type);
    811  1.1  mrg 	      mask = make_ssa_name (mask_type);
    812  1.1  mrg 	      cond = gimple_build_assign (mask, LT_EXPR, op0, zero);
    813  1.1  mrg 	      gsi_insert_before (gsi, cond, GSI_SAME_STMT);
    814  1.1  mrg 	      tree_vector_builder vec (type, nunits, 1);
    815  1.1  mrg 	      for (i = 0; i < nunits; i++)
    816  1.1  mrg 		vec.quick_push (build_int_cst (TREE_TYPE (type),
    817  1.1  mrg 					       (HOST_WIDE_INT_1U
    818  1.1  mrg 						<< shifts[i]) - 1));
    819  1.1  mrg 	      cst = vec.build ();
    820  1.1  mrg 	      addend = make_ssa_name (type);
    821  1.1  mrg 	      stmt
    822  1.1  mrg 		= gimple_build_assign (addend, VEC_COND_EXPR, mask, cst, zero);
    823  1.1  mrg 	      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    824  1.1  mrg 	    }
    825  1.1  mrg 	}
    826  1.1  mrg       if (code == TRUNC_DIV_EXPR)
    827  1.1  mrg 	{
    828  1.1  mrg 	  if (sign_p == UNSIGNED)
    829  1.1  mrg 	    {
    830  1.1  mrg 	      /* q = op0 >> shift;  */
    831  1.1  mrg 	      cur_op = add_rshift (gsi, type, op0, shifts);
    832  1.1  mrg 	      if (cur_op != NULL_TREE)
    833  1.1  mrg 		return cur_op;
    834  1.1  mrg 	    }
    835  1.1  mrg 	  else if (addend != NULL_TREE)
    836  1.1  mrg 	    {
    837  1.1  mrg 	      /* t1 = op0 + addend;
    838  1.1  mrg 		 q = t1 >> shift;  */
    839  1.1  mrg 	      op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
    840  1.1  mrg 	      if (op != unknown_optab
    841  1.1  mrg 		  && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
    842  1.1  mrg 		{
    843  1.1  mrg 		  cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0, addend);
    844  1.1  mrg 		  cur_op = add_rshift (gsi, type, cur_op, shifts);
    845  1.1  mrg 		  if (cur_op != NULL_TREE)
    846  1.1  mrg 		    return cur_op;
    847  1.1  mrg 		}
    848  1.1  mrg 	    }
    849  1.1  mrg 	}
    850  1.1  mrg       else
    851  1.1  mrg 	{
    852  1.1  mrg 	  tree mask;
    853  1.1  mrg 	  tree_vector_builder vec (type, nunits, 1);
    854  1.1  mrg 	  for (i = 0; i < nunits; i++)
    855  1.1  mrg 	    vec.quick_push (build_int_cst (TREE_TYPE (type),
    856  1.1  mrg 					   (HOST_WIDE_INT_1U
    857  1.1  mrg 					    << shifts[i]) - 1));
    858  1.1  mrg 	  mask = vec.build ();
    859  1.1  mrg 	  op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default);
    860  1.1  mrg 	  if (op != unknown_optab
    861  1.1  mrg 	      && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
    862  1.1  mrg 	    {
    863  1.1  mrg 	      if (sign_p == UNSIGNED)
    864  1.1  mrg 		/* r = op0 & mask;  */
    865  1.1  mrg 		return gimplify_build2 (gsi, BIT_AND_EXPR, type, op0, mask);
    866  1.1  mrg 	      else if (addend != NULL_TREE)
    867  1.1  mrg 		{
    868  1.1  mrg 		  /* t1 = op0 + addend;
    869  1.1  mrg 		     t2 = t1 & mask;
    870  1.1  mrg 		     r = t2 - addend;  */
    871  1.1  mrg 		  op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
    872  1.1  mrg 		  if (op != unknown_optab
    873  1.1  mrg 		      && optab_handler (op, TYPE_MODE (type))
    874  1.1  mrg 			 != CODE_FOR_nothing)
    875  1.1  mrg 		    {
    876  1.1  mrg 		      cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, op0,
    877  1.1  mrg 						addend);
    878  1.1  mrg 		      cur_op = gimplify_build2 (gsi, BIT_AND_EXPR, type,
    879  1.1  mrg 						cur_op, mask);
    880  1.1  mrg 		      op = optab_for_tree_code (MINUS_EXPR, type,
    881  1.1  mrg 						optab_default);
    882  1.1  mrg 		      if (op != unknown_optab
    883  1.1  mrg 			  && optab_handler (op, TYPE_MODE (type))
    884  1.1  mrg 			     != CODE_FOR_nothing)
    885  1.1  mrg 			return gimplify_build2 (gsi, MINUS_EXPR, type,
    886  1.1  mrg 						cur_op, addend);
    887  1.1  mrg 		    }
    888  1.1  mrg 		}
    889  1.1  mrg 	    }
    890  1.1  mrg 	}
    891  1.1  mrg     }
    892  1.1  mrg 
    893  1.1  mrg   if (mode == -2 || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
    894  1.1  mrg     return NULL_TREE;
    895  1.1  mrg 
    896  1.1  mrg   if (!can_mult_highpart_p (TYPE_MODE (type), TYPE_UNSIGNED (type)))
    897  1.1  mrg     return NULL_TREE;
    898  1.1  mrg 
    899  1.1  mrg   cur_op = op0;
    900  1.1  mrg 
    901  1.1  mrg   switch (mode)
    902  1.1  mrg     {
    903  1.1  mrg     case 0:
    904  1.1  mrg       gcc_assert (sign_p == UNSIGNED);
    905  1.1  mrg       /* t1 = oprnd0 >> pre_shift;
    906  1.1  mrg 	 t2 = t1 h* ml;
    907  1.1  mrg 	 q = t2 >> post_shift;  */
    908  1.1  mrg       cur_op = add_rshift (gsi, type, cur_op, pre_shifts);
    909  1.1  mrg       if (cur_op == NULL_TREE)
    910  1.1  mrg 	return NULL_TREE;
    911  1.1  mrg       break;
    912  1.1  mrg     case 1:
    913  1.1  mrg       gcc_assert (sign_p == UNSIGNED);
    914  1.1  mrg       for (i = 0; i < nunits; i++)
    915  1.1  mrg 	{
    916  1.1  mrg 	  shift_temps[i] = 1;
    917  1.1  mrg 	  post_shifts[i]--;
    918  1.1  mrg 	}
    919  1.1  mrg       break;
    920  1.1  mrg     case 2:
    921  1.1  mrg     case 3:
    922  1.1  mrg     case 4:
    923  1.1  mrg     case 5:
    924  1.1  mrg       gcc_assert (sign_p == SIGNED);
    925  1.1  mrg       for (i = 0; i < nunits; i++)
    926  1.1  mrg 	shift_temps[i] = prec - 1;
    927  1.1  mrg       break;
    928  1.1  mrg     default:
    929  1.1  mrg       return NULL_TREE;
    930  1.1  mrg     }
    931  1.1  mrg 
    932  1.1  mrg   tree_vector_builder vec (type, nunits, 1);
    933  1.1  mrg   for (i = 0; i < nunits; i++)
    934  1.1  mrg     vec.quick_push (build_int_cst (TREE_TYPE (type), mulc[i]));
    935  1.1  mrg   mulcst = vec.build ();
    936  1.1  mrg 
    937  1.1  mrg   cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst);
    938  1.1  mrg 
    939  1.1  mrg   switch (mode)
    940  1.1  mrg     {
    941  1.1  mrg     case 0:
    942  1.1  mrg       /* t1 = oprnd0 >> pre_shift;
    943  1.1  mrg 	 t2 = t1 h* ml;
    944  1.1  mrg 	 q = t2 >> post_shift;  */
    945  1.1  mrg       cur_op = add_rshift (gsi, type, cur_op, post_shifts);
    946  1.1  mrg       break;
    947  1.1  mrg     case 1:
    948  1.1  mrg       /* t1 = oprnd0 h* ml;
    949  1.1  mrg 	 t2 = oprnd0 - t1;
    950  1.1  mrg 	 t3 = t2 >> 1;
    951  1.1  mrg 	 t4 = t1 + t3;
    952  1.1  mrg 	 q = t4 >> (post_shift - 1);  */
    953  1.1  mrg       op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
    954  1.1  mrg       if (op == unknown_optab
    955  1.1  mrg 	  || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
    956  1.1  mrg 	return NULL_TREE;
    957  1.1  mrg       tem = gimplify_build2 (gsi, MINUS_EXPR, type, op0, cur_op);
    958  1.1  mrg       tem = add_rshift (gsi, type, tem, shift_temps);
    959  1.1  mrg       op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
    960  1.1  mrg       if (op == unknown_optab
    961  1.1  mrg 	  || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
    962  1.1  mrg 	return NULL_TREE;
    963  1.1  mrg       tem = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, tem);
    964  1.1  mrg       cur_op = add_rshift (gsi, type, tem, post_shifts);
    965  1.1  mrg       if (cur_op == NULL_TREE)
    966  1.1  mrg 	return NULL_TREE;
    967  1.1  mrg       break;
    968  1.1  mrg     case 2:
    969  1.1  mrg     case 3:
    970  1.1  mrg     case 4:
    971  1.1  mrg     case 5:
    972  1.1  mrg       /* t1 = oprnd0 h* ml;
    973  1.1  mrg 	 t2 = t1; [ iff (mode & 2) != 0 ]
    974  1.1  mrg 	 t2 = t1 + oprnd0; [ iff (mode & 2) == 0 ]
    975  1.1  mrg 	 t3 = t2 >> post_shift;
    976  1.1  mrg 	 t4 = oprnd0 >> (prec - 1);
    977  1.1  mrg 	 q = t3 - t4; [ iff (mode & 1) == 0 ]
    978  1.1  mrg 	 q = t4 - t3; [ iff (mode & 1) != 0 ]  */
    979  1.1  mrg       if ((mode & 2) == 0)
    980  1.1  mrg 	{
    981  1.1  mrg 	  op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
    982  1.1  mrg 	  if (op == unknown_optab
    983  1.1  mrg 	      || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
    984  1.1  mrg 	    return NULL_TREE;
    985  1.1  mrg 	  cur_op = gimplify_build2 (gsi, PLUS_EXPR, type, cur_op, op0);
    986  1.1  mrg 	}
    987  1.1  mrg       cur_op = add_rshift (gsi, type, cur_op, post_shifts);
    988  1.1  mrg       if (cur_op == NULL_TREE)
    989  1.1  mrg 	return NULL_TREE;
    990  1.1  mrg       tem = add_rshift (gsi, type, op0, shift_temps);
    991  1.1  mrg       if (tem == NULL_TREE)
    992  1.1  mrg 	return NULL_TREE;
    993  1.1  mrg       op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
    994  1.1  mrg       if (op == unknown_optab
    995  1.1  mrg 	  || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
    996  1.1  mrg 	return NULL_TREE;
    997  1.1  mrg       if ((mode & 1) == 0)
    998  1.1  mrg 	cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, cur_op, tem);
    999  1.1  mrg       else
   1000  1.1  mrg 	cur_op = gimplify_build2 (gsi, MINUS_EXPR, type, tem, cur_op);
   1001  1.1  mrg       break;
   1002  1.1  mrg     default:
   1003  1.1  mrg       gcc_unreachable ();
   1004  1.1  mrg     }
   1005  1.1  mrg 
   1006  1.1  mrg   if (code == TRUNC_DIV_EXPR)
   1007  1.1  mrg     return cur_op;
   1008  1.1  mrg 
   1009  1.1  mrg   /* We divided.  Now finish by:
   1010  1.1  mrg      t1 = q * oprnd1;
   1011  1.1  mrg      r = oprnd0 - t1;  */
   1012  1.1  mrg   op = optab_for_tree_code (MULT_EXPR, type, optab_default);
   1013  1.1  mrg   if (op == unknown_optab
   1014  1.1  mrg       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
   1015  1.1  mrg     return NULL_TREE;
   1016  1.1  mrg   if (use_abs_op1)
   1017  1.1  mrg     {
   1018  1.1  mrg       tree_vector_builder elts;
   1019  1.1  mrg       if (!elts.new_unary_operation (type, op1, false))
   1020  1.1  mrg 	return NULL_TREE;
   1021  1.1  mrg       unsigned int count = elts.encoded_nelts ();
   1022  1.1  mrg       for (unsigned int i = 0; i < count; ++i)
   1023  1.1  mrg 	{
   1024  1.1  mrg 	  tree elem1 = VECTOR_CST_ELT (op1, i);
   1025  1.1  mrg 
   1026  1.1  mrg 	  tree elt = const_unop (ABS_EXPR, TREE_TYPE (elem1), elem1);
   1027  1.1  mrg 	  if (elt == NULL_TREE)
   1028  1.1  mrg 	    return NULL_TREE;
   1029  1.1  mrg 	  elts.quick_push (elt);
   1030  1.1  mrg 	}
   1031  1.1  mrg       op1 = elts.build ();
   1032  1.1  mrg     }
   1033  1.1  mrg   tem = gimplify_build2 (gsi, MULT_EXPR, type, cur_op, op1);
   1034  1.1  mrg   op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
   1035  1.1  mrg   if (op == unknown_optab
   1036  1.1  mrg       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
   1037  1.1  mrg     return NULL_TREE;
   1038  1.1  mrg   return gimplify_build2 (gsi, MINUS_EXPR, type, op0, tem);
   1039  1.1  mrg }
   1040  1.1  mrg 
   1041  1.1  mrg /* Expand a vector condition to scalars, by using many conditions
   1042  1.1  mrg    on the vector's elements.  */
   1043  1.1  mrg 
   1044  1.1  mrg static bool
   1045  1.1  mrg expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names)
   1046  1.1  mrg {
   1047  1.1  mrg   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   1048  1.1  mrg   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
   1049  1.1  mrg   tree a = gimple_assign_rhs1 (stmt);
   1050  1.1  mrg   tree a1 = a;
   1051  1.1  mrg   tree a2 = NULL_TREE;
   1052  1.1  mrg   bool a_is_comparison = false;
   1053  1.1  mrg   bool a_is_scalar_bitmask = false;
   1054  1.1  mrg   tree b = gimple_assign_rhs2 (stmt);
   1055  1.1  mrg   tree c = gimple_assign_rhs3 (stmt);
   1056  1.1  mrg   vec<constructor_elt, va_gc> *v;
   1057  1.1  mrg   tree constr;
   1058  1.1  mrg   tree inner_type = TREE_TYPE (type);
   1059  1.1  mrg   tree width = vector_element_bits_tree (type);
   1060  1.1  mrg   tree cond_type = TREE_TYPE (TREE_TYPE (a));
   1061  1.1  mrg   tree comp_inner_type = cond_type;
   1062  1.1  mrg   tree index = bitsize_int (0);
   1063  1.1  mrg   tree comp_width = width;
   1064  1.1  mrg   tree comp_index = index;
   1065  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
   1066  1.1  mrg   tree_code code = TREE_CODE (a);
   1067  1.1  mrg   gassign *assign = NULL;
   1068  1.1  mrg 
   1069  1.1  mrg   if (code == SSA_NAME)
   1070  1.1  mrg     {
   1071  1.1  mrg       assign = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (a));
   1072  1.1  mrg       if (assign != NULL
   1073  1.1  mrg 	  && TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison)
   1074  1.1  mrg 	{
   1075  1.1  mrg 	  a_is_comparison = true;
   1076  1.1  mrg 	  a1 = gimple_assign_rhs1 (assign);
   1077  1.1  mrg 	  a2 = gimple_assign_rhs2 (assign);
   1078  1.1  mrg 	  code = gimple_assign_rhs_code (assign);
   1079  1.1  mrg 	  comp_inner_type = TREE_TYPE (TREE_TYPE (a1));
   1080  1.1  mrg 	  comp_width = vector_element_bits_tree (TREE_TYPE (a1));
   1081  1.1  mrg 	}
   1082  1.1  mrg     }
   1083  1.1  mrg 
   1084  1.1  mrg   if (expand_vec_cond_expr_p (type, TREE_TYPE (a1), code)
   1085  1.1  mrg       || (integer_all_onesp (b) && integer_zerop (c)
   1086  1.1  mrg 	  && expand_vec_cmp_expr_p (type, TREE_TYPE (a1), code)))
   1087  1.1  mrg     {
   1088  1.1  mrg       gcc_assert (TREE_CODE (a) == SSA_NAME || TREE_CODE (a) == VECTOR_CST);
   1089  1.1  mrg       return true;
   1090  1.1  mrg     }
   1091  1.1  mrg 
   1092  1.1  mrg   /* If a has vector boolean type and is a comparison, above
   1093  1.1  mrg      expand_vec_cond_expr_p might fail, even if both the comparison and
   1094  1.1  mrg      VEC_COND_EXPR could be supported individually.  See PR109176.  */
   1095  1.1  mrg   if (a_is_comparison
   1096  1.1  mrg       && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))
   1097  1.1  mrg       && expand_vec_cond_expr_p (type, TREE_TYPE (a), SSA_NAME)
   1098  1.1  mrg       && expand_vec_cmp_expr_p (TREE_TYPE (a1), TREE_TYPE (a), code))
   1099  1.1  mrg     return true;
   1100  1.1  mrg 
   1101  1.1  mrg   /* Handle vector boolean types with bitmasks.  If there is a comparison
   1102  1.1  mrg      and we can expand the comparison into the vector boolean bitmask,
   1103  1.1  mrg      or otherwise if it is compatible with type, we can transform
   1104  1.1  mrg       vbfld_1 = x_2 < y_3 ? vbfld_4 : vbfld_5;
   1105  1.1  mrg      into
   1106  1.1  mrg       tmp_6 = x_2 < y_3;
   1107  1.1  mrg       tmp_7 = tmp_6 & vbfld_4;
   1108  1.1  mrg       tmp_8 = ~tmp_6;
   1109  1.1  mrg       tmp_9 = tmp_8 & vbfld_5;
   1110  1.1  mrg       vbfld_1 = tmp_7 | tmp_9;
   1111  1.1  mrg      Similarly for vbfld_10 instead of x_2 < y_3.  */
   1112  1.1  mrg   if (VECTOR_BOOLEAN_TYPE_P (type)
   1113  1.1  mrg       && SCALAR_INT_MODE_P (TYPE_MODE (type))
   1114  1.1  mrg       && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),
   1115  1.1  mrg 		   TYPE_VECTOR_SUBPARTS (type)
   1116  1.1  mrg 		   * GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type))))
   1117  1.1  mrg       && (a_is_comparison
   1118  1.1  mrg 	  ? useless_type_conversion_p (type, TREE_TYPE (a))
   1119  1.1  mrg 	  : expand_vec_cmp_expr_p (TREE_TYPE (a1), type, TREE_CODE (a))))
   1120  1.1  mrg     {
   1121  1.1  mrg       if (a_is_comparison)
   1122  1.1  mrg 	a = gimplify_build2 (gsi, code, type, a1, a2);
   1123  1.1  mrg       a1 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a, b);
   1124  1.1  mrg       a2 = gimplify_build1 (gsi, BIT_NOT_EXPR, type, a);
   1125  1.1  mrg       a2 = gimplify_build2 (gsi, BIT_AND_EXPR, type, a2, c);
   1126  1.1  mrg       a = gimplify_build2 (gsi, BIT_IOR_EXPR, type, a1, a2);
   1127  1.1  mrg       gimple_assign_set_rhs_from_tree (gsi, a);
   1128  1.1  mrg       update_stmt (gsi_stmt (*gsi));
   1129  1.1  mrg       return true;
   1130  1.1  mrg     }
   1131  1.1  mrg 
   1132  1.1  mrg   /* TODO: try and find a smaller vector type.  */
   1133  1.1  mrg 
   1134  1.1  mrg   if (!warning_suppressed_p (stmt, OPT_Wvector_operation_performance))
   1135  1.1  mrg     warning_at (loc, OPT_Wvector_operation_performance,
   1136  1.1  mrg 		"vector condition will be expanded piecewise");
   1137  1.1  mrg 
   1138  1.1  mrg   if (!a_is_comparison
   1139  1.1  mrg       && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))
   1140  1.1  mrg       && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a)))
   1141  1.1  mrg       && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a))),
   1142  1.1  mrg 		   TYPE_VECTOR_SUBPARTS (TREE_TYPE (a))
   1143  1.1  mrg 		   * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
   1144  1.1  mrg 						(TREE_TYPE (TREE_TYPE (a))))))
   1145  1.1  mrg     {
   1146  1.1  mrg       a_is_scalar_bitmask = true;
   1147  1.1  mrg       int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a)));
   1148  1.1  mrg       tree atype = build_nonstandard_integer_type (prec, 1);
   1149  1.1  mrg       a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a);
   1150  1.1  mrg     }
   1151  1.1  mrg   else if (!a_is_comparison
   1152  1.1  mrg 	   && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a)))
   1153  1.1  mrg     comp_width = vector_element_bits_tree (TREE_TYPE (a));
   1154  1.1  mrg 
   1155  1.1  mrg   int nunits = nunits_for_known_piecewise_op (type);
   1156  1.1  mrg   vec_alloc (v, nunits);
   1157  1.1  mrg   bool constant_p = true;
   1158  1.1  mrg   for (int i = 0; i < nunits; i++)
   1159  1.1  mrg     {
   1160  1.1  mrg       tree aa, result;
   1161  1.1  mrg       tree bb = tree_vec_extract (gsi, inner_type, b, width, index);
   1162  1.1  mrg       tree cc = tree_vec_extract (gsi, inner_type, c, width, index);
   1163  1.1  mrg       if (a_is_comparison)
   1164  1.1  mrg 	{
   1165  1.1  mrg 	  tree aa1 = tree_vec_extract (gsi, comp_inner_type, a1,
   1166  1.1  mrg 				       comp_width, comp_index);
   1167  1.1  mrg 	  tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2,
   1168  1.1  mrg 				       comp_width, comp_index);
   1169  1.1  mrg 	  aa = build2 (code, cond_type, aa1, aa2);
   1170  1.1  mrg 	}
   1171  1.1  mrg       else if (a_is_scalar_bitmask)
   1172  1.1  mrg 	{
   1173  1.1  mrg 	  wide_int w = wi::set_bit_in_zero (i, TYPE_PRECISION (TREE_TYPE (a)));
   1174  1.1  mrg 	  result = gimplify_build2 (gsi, BIT_AND_EXPR, TREE_TYPE (a),
   1175  1.1  mrg 				    a, wide_int_to_tree (TREE_TYPE (a), w));
   1176  1.1  mrg 	  aa = build2 (NE_EXPR, boolean_type_node, result,
   1177  1.1  mrg 		       build_zero_cst (TREE_TYPE (a)));
   1178  1.1  mrg 	}
   1179  1.1  mrg       else
   1180  1.1  mrg 	aa = tree_vec_extract (gsi, cond_type, a, comp_width, comp_index);
   1181  1.1  mrg       result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
   1182  1.1  mrg       if (!CONSTANT_CLASS_P (result))
   1183  1.1  mrg 	constant_p = false;
   1184  1.1  mrg       constructor_elt ce = {NULL_TREE, result};
   1185  1.1  mrg       v->quick_push (ce);
   1186  1.1  mrg       index = int_const_binop (PLUS_EXPR, index, width);
   1187  1.1  mrg       if (width == comp_width)
   1188  1.1  mrg 	comp_index = index;
   1189  1.1  mrg       else
   1190  1.1  mrg 	comp_index = int_const_binop (PLUS_EXPR, comp_index, comp_width);
   1191  1.1  mrg     }
   1192  1.1  mrg 
   1193  1.1  mrg   if (constant_p)
   1194  1.1  mrg     constr = build_vector_from_ctor (type, v);
   1195  1.1  mrg   else
   1196  1.1  mrg     constr = build_constructor (type, v);
   1197  1.1  mrg   gimple_assign_set_rhs_from_tree (gsi, constr);
   1198  1.1  mrg   update_stmt (gsi_stmt (*gsi));
   1199  1.1  mrg 
   1200  1.1  mrg   if (a_is_comparison)
   1201  1.1  mrg     bitmap_set_bit (dce_ssa_names,
   1202  1.1  mrg 		    SSA_NAME_VERSION (gimple_assign_lhs (assign)));
   1203  1.1  mrg 
   1204  1.1  mrg   return false;
   1205  1.1  mrg }
   1206  1.1  mrg 
   1207  1.1  mrg static tree
   1208  1.1  mrg expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
   1209  1.1  mrg 			 gassign *assign, enum tree_code code,
   1210  1.1  mrg 			 bitmap dce_ssa_names)
   1211  1.1  mrg {
   1212  1.1  mrg   machine_mode compute_mode = TYPE_MODE (compute_type);
   1213  1.1  mrg 
   1214  1.1  mrg   /* If the compute mode is not a vector mode (hence we are not decomposing
   1215  1.1  mrg      a BLKmode vector to smaller, hardware-supported vectors), we may want
   1216  1.1  mrg      to expand the operations in parallel.  */
   1217  1.1  mrg   if (!VECTOR_MODE_P (compute_mode))
   1218  1.1  mrg     switch (code)
   1219  1.1  mrg       {
   1220  1.1  mrg       case PLUS_EXPR:
   1221  1.1  mrg       case MINUS_EXPR:
   1222  1.1  mrg         if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
   1223  1.1  mrg 	  return expand_vector_addition (gsi, do_binop, do_plus_minus, type,
   1224  1.1  mrg 					 gimple_assign_rhs1 (assign),
   1225  1.1  mrg 					 gimple_assign_rhs2 (assign), code);
   1226  1.1  mrg 	break;
   1227  1.1  mrg 
   1228  1.1  mrg       case NEGATE_EXPR:
   1229  1.1  mrg         if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
   1230  1.1  mrg           return expand_vector_addition (gsi, do_unop, do_negate, type,
   1231  1.1  mrg 		      		         gimple_assign_rhs1 (assign),
   1232  1.1  mrg 					 NULL_TREE, code);
   1233  1.1  mrg 	break;
   1234  1.1  mrg 
   1235  1.1  mrg       case BIT_AND_EXPR:
   1236  1.1  mrg       case BIT_IOR_EXPR:
   1237  1.1  mrg       case BIT_XOR_EXPR:
   1238  1.1  mrg         return expand_vector_parallel (gsi, do_binop, type,
   1239  1.1  mrg 		      		       gimple_assign_rhs1 (assign),
   1240  1.1  mrg 				       gimple_assign_rhs2 (assign), code);
   1241  1.1  mrg 
   1242  1.1  mrg       case BIT_NOT_EXPR:
   1243  1.1  mrg         return expand_vector_parallel (gsi, do_unop, type,
   1244  1.1  mrg 		      		       gimple_assign_rhs1 (assign),
   1245  1.1  mrg         			       NULL_TREE, code);
   1246  1.1  mrg       case EQ_EXPR:
   1247  1.1  mrg       case NE_EXPR:
   1248  1.1  mrg       case GT_EXPR:
   1249  1.1  mrg       case LT_EXPR:
   1250  1.1  mrg       case GE_EXPR:
   1251  1.1  mrg       case LE_EXPR:
   1252  1.1  mrg       case UNEQ_EXPR:
   1253  1.1  mrg       case UNGT_EXPR:
   1254  1.1  mrg       case UNLT_EXPR:
   1255  1.1  mrg       case UNGE_EXPR:
   1256  1.1  mrg       case UNLE_EXPR:
   1257  1.1  mrg       case LTGT_EXPR:
   1258  1.1  mrg       case ORDERED_EXPR:
   1259  1.1  mrg       case UNORDERED_EXPR:
   1260  1.1  mrg 	{
   1261  1.1  mrg 	  tree rhs1 = gimple_assign_rhs1 (assign);
   1262  1.1  mrg 	  tree rhs2 = gimple_assign_rhs2 (assign);
   1263  1.1  mrg 
   1264  1.1  mrg 	  return expand_vector_comparison (gsi, type, rhs1, rhs2, code,
   1265  1.1  mrg 					   dce_ssa_names);
   1266  1.1  mrg 	}
   1267  1.1  mrg 
   1268  1.1  mrg       case TRUNC_DIV_EXPR:
   1269  1.1  mrg       case TRUNC_MOD_EXPR:
   1270  1.1  mrg 	{
   1271  1.1  mrg 	  tree rhs1 = gimple_assign_rhs1 (assign);
   1272  1.1  mrg 	  tree rhs2 = gimple_assign_rhs2 (assign);
   1273  1.1  mrg 	  tree ret;
   1274  1.1  mrg 
   1275  1.1  mrg 	  if (!optimize
   1276  1.1  mrg 	      || !VECTOR_INTEGER_TYPE_P (type)
   1277  1.1  mrg 	      || TREE_CODE (rhs2) != VECTOR_CST
   1278  1.1  mrg 	      || !VECTOR_MODE_P (TYPE_MODE (type)))
   1279  1.1  mrg 	    break;
   1280  1.1  mrg 
   1281  1.1  mrg 	  ret = expand_vector_divmod (gsi, type, rhs1, rhs2, code);
   1282  1.1  mrg 	  if (ret != NULL_TREE)
   1283  1.1  mrg 	    return ret;
   1284  1.1  mrg 	  break;
   1285  1.1  mrg 	}
   1286  1.1  mrg 
   1287  1.1  mrg       default:
   1288  1.1  mrg 	break;
   1289  1.1  mrg       }
   1290  1.1  mrg 
   1291  1.1  mrg   if (TREE_CODE_CLASS (code) == tcc_unary)
   1292  1.1  mrg     return expand_vector_piecewise (gsi, do_unop, type, compute_type,
   1293  1.1  mrg 				    gimple_assign_rhs1 (assign),
   1294  1.1  mrg 				    NULL_TREE, code, false);
   1295  1.1  mrg   else
   1296  1.1  mrg     return expand_vector_piecewise (gsi, do_binop, type, compute_type,
   1297  1.1  mrg 				    gimple_assign_rhs1 (assign),
   1298  1.1  mrg 				    gimple_assign_rhs2 (assign), code, false);
   1299  1.1  mrg }
   1300  1.1  mrg 
   1301  1.1  mrg /* Try to optimize
   1302  1.1  mrg    a_5 = { b_7, b_7 + 3, b_7 + 6, b_7 + 9 };
   1303  1.1  mrg    style stmts into:
   1304  1.1  mrg    _9 = { b_7, b_7, b_7, b_7 };
   1305  1.1  mrg    a_5 = _9 + { 0, 3, 6, 9 };
   1306  1.1  mrg    because vector splat operation is usually more efficient
   1307  1.1  mrg    than piecewise initialization of the vector.  */
   1308  1.1  mrg 
   1309  1.1  mrg static void
   1310  1.1  mrg optimize_vector_constructor (gimple_stmt_iterator *gsi)
   1311  1.1  mrg {
   1312  1.1  mrg   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   1313  1.1  mrg   tree lhs = gimple_assign_lhs (stmt);
   1314  1.1  mrg   tree rhs = gimple_assign_rhs1 (stmt);
   1315  1.1  mrg   tree type = TREE_TYPE (rhs);
   1316  1.1  mrg   unsigned int i, j;
   1317  1.1  mrg   unsigned HOST_WIDE_INT nelts;
   1318  1.1  mrg   bool all_same = true;
   1319  1.1  mrg   constructor_elt *elt;
   1320  1.1  mrg   gimple *g;
   1321  1.1  mrg   tree base = NULL_TREE;
   1322  1.1  mrg   optab op;
   1323  1.1  mrg 
   1324  1.1  mrg   if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)
   1325  1.1  mrg       || nelts <= 2
   1326  1.1  mrg       || CONSTRUCTOR_NELTS (rhs) != nelts)
   1327  1.1  mrg     return;
   1328  1.1  mrg   op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
   1329  1.1  mrg   if (op == unknown_optab
   1330  1.1  mrg       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
   1331  1.1  mrg     return;
   1332  1.1  mrg   FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs), i, elt)
   1333  1.1  mrg     if (TREE_CODE (elt->value) != SSA_NAME
   1334  1.1  mrg 	|| TREE_CODE (TREE_TYPE (elt->value)) == VECTOR_TYPE)
   1335  1.1  mrg       return;
   1336  1.1  mrg     else
   1337  1.1  mrg       {
   1338  1.1  mrg 	tree this_base = elt->value;
   1339  1.1  mrg 	if (this_base != CONSTRUCTOR_ELT (rhs, 0)->value)
   1340  1.1  mrg 	  all_same = false;
   1341  1.1  mrg 	for (j = 0; j < nelts + 1; j++)
   1342  1.1  mrg 	  {
   1343  1.1  mrg 	    g = SSA_NAME_DEF_STMT (this_base);
   1344  1.1  mrg 	    if (is_gimple_assign (g)
   1345  1.1  mrg 		&& gimple_assign_rhs_code (g) == PLUS_EXPR
   1346  1.1  mrg 		&& TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST
   1347  1.1  mrg 		&& TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
   1348  1.1  mrg 		&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
   1349  1.1  mrg 	      this_base = gimple_assign_rhs1 (g);
   1350  1.1  mrg 	    else
   1351  1.1  mrg 	      break;
   1352  1.1  mrg 	  }
   1353  1.1  mrg 	if (i == 0)
   1354  1.1  mrg 	  base = this_base;
   1355  1.1  mrg 	else if (this_base != base)
   1356  1.1  mrg 	  return;
   1357  1.1  mrg       }
   1358  1.1  mrg   if (all_same)
   1359  1.1  mrg     return;
   1360  1.1  mrg   tree_vector_builder cst (type, nelts, 1);
   1361  1.1  mrg   for (i = 0; i < nelts; i++)
   1362  1.1  mrg     {
   1363  1.1  mrg       tree this_base = CONSTRUCTOR_ELT (rhs, i)->value;
   1364  1.1  mrg       tree elt = build_zero_cst (TREE_TYPE (base));
   1365  1.1  mrg       while (this_base != base)
   1366  1.1  mrg 	{
   1367  1.1  mrg 	  g = SSA_NAME_DEF_STMT (this_base);
   1368  1.1  mrg 	  elt = fold_binary (PLUS_EXPR, TREE_TYPE (base),
   1369  1.1  mrg 			     elt, gimple_assign_rhs2 (g));
   1370  1.1  mrg 	  if (elt == NULL_TREE
   1371  1.1  mrg 	      || TREE_CODE (elt) != INTEGER_CST
   1372  1.1  mrg 	      || TREE_OVERFLOW (elt))
   1373  1.1  mrg 	    return;
   1374  1.1  mrg 	  this_base = gimple_assign_rhs1 (g);
   1375  1.1  mrg 	}
   1376  1.1  mrg       cst.quick_push (elt);
   1377  1.1  mrg     }
   1378  1.1  mrg   for (i = 0; i < nelts; i++)
   1379  1.1  mrg     CONSTRUCTOR_ELT (rhs, i)->value = base;
   1380  1.1  mrg   g = gimple_build_assign (make_ssa_name (type), rhs);
   1381  1.1  mrg   gsi_insert_before (gsi, g, GSI_SAME_STMT);
   1382  1.1  mrg   g = gimple_build_assign (lhs, PLUS_EXPR, gimple_assign_lhs (g),
   1383  1.1  mrg 			   cst.build ());
   1384  1.1  mrg   gsi_replace (gsi, g, false);
   1385  1.1  mrg }
   1386  1.1  mrg 
   1387  1.1  mrg /* Return a type for the widest vector mode with the same element type as
   1389  1.1  mrg    type ORIGINAL_VECTOR_TYPE, with at most the same number of elements as type
   1390  1.1  mrg    ORIGINAL_VECTOR_TYPE and that is supported by the target for an operation
   1391  1.1  mrg    with optab OP, or return NULL_TREE if none is found.  */
   1392  1.1  mrg 
   1393  1.1  mrg static tree
   1394  1.1  mrg type_for_widest_vector_mode (tree original_vector_type, optab op)
   1395  1.1  mrg {
   1396  1.1  mrg   gcc_assert (VECTOR_TYPE_P (original_vector_type));
   1397  1.1  mrg   tree type = TREE_TYPE (original_vector_type);
   1398  1.1  mrg   machine_mode inner_mode = TYPE_MODE (type);
   1399  1.1  mrg   machine_mode best_mode = VOIDmode, mode;
   1400  1.1  mrg   poly_int64 best_nunits = 0;
   1401  1.1  mrg 
   1402  1.1  mrg   if (SCALAR_FLOAT_MODE_P (inner_mode))
   1403  1.1  mrg     mode = MIN_MODE_VECTOR_FLOAT;
   1404  1.1  mrg   else if (SCALAR_FRACT_MODE_P (inner_mode))
   1405  1.1  mrg     mode = MIN_MODE_VECTOR_FRACT;
   1406  1.1  mrg   else if (SCALAR_UFRACT_MODE_P (inner_mode))
   1407  1.1  mrg     mode = MIN_MODE_VECTOR_UFRACT;
   1408  1.1  mrg   else if (SCALAR_ACCUM_MODE_P (inner_mode))
   1409  1.1  mrg     mode = MIN_MODE_VECTOR_ACCUM;
   1410  1.1  mrg   else if (SCALAR_UACCUM_MODE_P (inner_mode))
   1411  1.1  mrg     mode = MIN_MODE_VECTOR_UACCUM;
   1412  1.1  mrg   else if (inner_mode == BImode)
   1413  1.1  mrg     mode = MIN_MODE_VECTOR_BOOL;
   1414  1.1  mrg   else
   1415  1.1  mrg     mode = MIN_MODE_VECTOR_INT;
   1416  1.1  mrg 
   1417  1.1  mrg   FOR_EACH_MODE_FROM (mode, mode)
   1418  1.1  mrg     if (GET_MODE_INNER (mode) == inner_mode
   1419  1.1  mrg 	&& maybe_gt (GET_MODE_NUNITS (mode), best_nunits)
   1420  1.1  mrg 	&& optab_handler (op, mode) != CODE_FOR_nothing
   1421  1.1  mrg 	&& known_le (GET_MODE_NUNITS (mode),
   1422  1.1  mrg 		     TYPE_VECTOR_SUBPARTS (original_vector_type)))
   1423  1.1  mrg       best_mode = mode, best_nunits = GET_MODE_NUNITS (mode);
   1424  1.1  mrg 
   1425  1.1  mrg   if (best_mode == VOIDmode)
   1426  1.1  mrg     return NULL_TREE;
   1427  1.1  mrg   else
   1428  1.1  mrg     return build_vector_type_for_mode (type, best_mode);
   1429  1.1  mrg }
   1430  1.1  mrg 
   1431  1.1  mrg 
   1432  1.1  mrg /* Build a reference to the element of the vector VECT.  Function
   1433  1.1  mrg    returns either the element itself, either BIT_FIELD_REF, or an
   1434  1.1  mrg    ARRAY_REF expression.
   1435  1.1  mrg 
   1436  1.1  mrg    GSI is required to insert temporary variables while building a
   1437  1.1  mrg    refernece to the element of the vector VECT.
   1438  1.1  mrg 
   1439  1.1  mrg    PTMPVEC is a pointer to the temporary variable for caching
   1440  1.1  mrg    purposes.  In case when PTMPVEC is NULL new temporary variable
   1441  1.1  mrg    will be created.  */
   1442  1.1  mrg static tree
   1443  1.1  mrg vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec)
   1444  1.1  mrg {
   1445  1.1  mrg   tree vect_type, vect_elt_type;
   1446  1.1  mrg   gimple *asgn;
   1447  1.1  mrg   tree tmpvec;
   1448  1.1  mrg   tree arraytype;
   1449  1.1  mrg   bool need_asgn = true;
   1450  1.1  mrg   unsigned int elements;
   1451  1.1  mrg 
   1452  1.1  mrg   vect_type = TREE_TYPE (vect);
   1453  1.1  mrg   vect_elt_type = TREE_TYPE (vect_type);
   1454  1.1  mrg   elements = nunits_for_known_piecewise_op (vect_type);
   1455  1.1  mrg 
   1456  1.1  mrg   if (TREE_CODE (idx) == INTEGER_CST)
   1457  1.1  mrg     {
   1458  1.1  mrg       unsigned HOST_WIDE_INT index;
   1459  1.1  mrg 
   1460  1.1  mrg       /* Given that we're about to compute a binary modulus,
   1461  1.1  mrg 	 we don't care about the high bits of the value.  */
   1462  1.1  mrg       index = TREE_INT_CST_LOW (idx);
   1463  1.1  mrg       if (!tree_fits_uhwi_p (idx) || index >= elements)
   1464  1.1  mrg 	{
   1465  1.1  mrg 	  index &= elements - 1;
   1466  1.1  mrg 	  idx = build_int_cst (TREE_TYPE (idx), index);
   1467  1.1  mrg 	}
   1468  1.1  mrg 
   1469  1.1  mrg       /* When lowering a vector statement sequence do some easy
   1470  1.1  mrg          simplification by looking through intermediate vector results.  */
   1471  1.1  mrg       if (TREE_CODE (vect) == SSA_NAME)
   1472  1.1  mrg 	{
   1473  1.1  mrg 	  gimple *def_stmt = SSA_NAME_DEF_STMT (vect);
   1474  1.1  mrg 	  if (is_gimple_assign (def_stmt)
   1475  1.1  mrg 	      && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST
   1476  1.1  mrg 		  || gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR))
   1477  1.1  mrg 	    vect = gimple_assign_rhs1 (def_stmt);
   1478  1.1  mrg 	}
   1479  1.1  mrg 
   1480  1.1  mrg       if (TREE_CODE (vect) == VECTOR_CST)
   1481  1.1  mrg 	return VECTOR_CST_ELT (vect, index);
   1482  1.1  mrg       else if (TREE_CODE (vect) == CONSTRUCTOR
   1483  1.1  mrg 	       && (CONSTRUCTOR_NELTS (vect) == 0
   1484  1.1  mrg 		   || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect, 0)->value))
   1485  1.1  mrg 		      != VECTOR_TYPE))
   1486  1.1  mrg         {
   1487  1.1  mrg 	  if (index < CONSTRUCTOR_NELTS (vect))
   1488  1.1  mrg 	    return CONSTRUCTOR_ELT (vect, index)->value;
   1489  1.1  mrg           return build_zero_cst (vect_elt_type);
   1490  1.1  mrg         }
   1491  1.1  mrg       else
   1492  1.1  mrg         {
   1493  1.1  mrg 	  tree size = vector_element_bits_tree (vect_type);
   1494  1.1  mrg 	  tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (index),
   1495  1.1  mrg 				  size);
   1496  1.1  mrg 	  return fold_build3 (BIT_FIELD_REF, vect_elt_type, vect, size, pos);
   1497  1.1  mrg         }
   1498  1.1  mrg     }
   1499  1.1  mrg 
   1500  1.1  mrg   if (!ptmpvec)
   1501  1.1  mrg     tmpvec = create_tmp_var (vect_type, "vectmp");
   1502  1.1  mrg   else if (!*ptmpvec)
   1503  1.1  mrg     tmpvec = *ptmpvec = create_tmp_var (vect_type, "vectmp");
   1504  1.1  mrg   else
   1505  1.1  mrg     {
   1506  1.1  mrg       tmpvec = *ptmpvec;
   1507  1.1  mrg       need_asgn = false;
   1508  1.1  mrg     }
   1509  1.1  mrg 
   1510  1.1  mrg   if (need_asgn)
   1511  1.1  mrg     {
   1512  1.1  mrg       TREE_ADDRESSABLE (tmpvec) = 1;
   1513  1.1  mrg       asgn = gimple_build_assign (tmpvec, vect);
   1514  1.1  mrg       gsi_insert_before (gsi, asgn, GSI_SAME_STMT);
   1515  1.1  mrg     }
   1516  1.1  mrg 
   1517  1.1  mrg   arraytype = build_array_type_nelts (vect_elt_type, elements);
   1518  1.1  mrg   return build4 (ARRAY_REF, vect_elt_type,
   1519  1.1  mrg                  build1 (VIEW_CONVERT_EXPR, arraytype, tmpvec),
   1520  1.1  mrg                  idx, NULL_TREE, NULL_TREE);
   1521  1.1  mrg }
   1522  1.1  mrg 
   1523  1.1  mrg /* Check if VEC_PERM_EXPR within the given setting is supported
   1524  1.1  mrg    by hardware, or lower it piecewise.
   1525  1.1  mrg 
   1526  1.1  mrg    When VEC_PERM_EXPR has the same first and second operands:
   1527  1.1  mrg    VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
   1528  1.1  mrg    {v0[mask[0]], v0[mask[1]], ...}
   1529  1.1  mrg    MASK and V0 must have the same number of elements.
   1530  1.1  mrg 
   1531  1.1  mrg    Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
   1532  1.1  mrg    {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
   1533  1.1  mrg    V0 and V1 must have the same type.  MASK, V0, V1 must have the
   1534  1.1  mrg    same number of arguments.  */
   1535  1.1  mrg 
   1536  1.1  mrg static void
   1537  1.1  mrg lower_vec_perm (gimple_stmt_iterator *gsi)
   1538  1.1  mrg {
   1539  1.1  mrg   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   1540  1.1  mrg   tree mask = gimple_assign_rhs3 (stmt);
   1541  1.1  mrg   tree vec0 = gimple_assign_rhs1 (stmt);
   1542  1.1  mrg   tree vec1 = gimple_assign_rhs2 (stmt);
   1543  1.1  mrg   tree vect_type = TREE_TYPE (vec0);
   1544  1.1  mrg   tree mask_type = TREE_TYPE (mask);
   1545  1.1  mrg   tree vect_elt_type = TREE_TYPE (vect_type);
   1546  1.1  mrg   tree mask_elt_type = TREE_TYPE (mask_type);
   1547  1.1  mrg   unsigned HOST_WIDE_INT elements;
   1548  1.1  mrg   vec<constructor_elt, va_gc> *v;
   1549  1.1  mrg   tree constr, t, si, i_val;
   1550  1.1  mrg   tree vec0tmp = NULL_TREE, vec1tmp = NULL_TREE, masktmp = NULL_TREE;
   1551  1.1  mrg   bool two_operand_p = !operand_equal_p (vec0, vec1, 0);
   1552  1.1  mrg   location_t loc = gimple_location (gsi_stmt (*gsi));
   1553  1.1  mrg   unsigned i;
   1554  1.1  mrg 
   1555  1.1  mrg   if (!TYPE_VECTOR_SUBPARTS (vect_type).is_constant (&elements))
   1556  1.1  mrg     return;
   1557  1.1  mrg 
   1558  1.1  mrg   if (TREE_CODE (mask) == SSA_NAME)
   1559  1.1  mrg     {
   1560  1.1  mrg       gimple *def_stmt = SSA_NAME_DEF_STMT (mask);
   1561  1.1  mrg       if (is_gimple_assign (def_stmt)
   1562  1.1  mrg 	  && gimple_assign_rhs_code (def_stmt) == VECTOR_CST)
   1563  1.1  mrg 	mask = gimple_assign_rhs1 (def_stmt);
   1564  1.1  mrg     }
   1565  1.1  mrg 
   1566  1.1  mrg   vec_perm_builder sel_int;
   1567  1.1  mrg 
   1568  1.1  mrg   if (TREE_CODE (mask) == VECTOR_CST
   1569  1.1  mrg       && tree_to_vec_perm_builder (&sel_int, mask))
   1570  1.1  mrg     {
   1571  1.1  mrg       vec_perm_indices indices (sel_int, 2, elements);
   1572  1.1  mrg       if (can_vec_perm_const_p (TYPE_MODE (vect_type), indices))
   1573  1.1  mrg 	{
   1574  1.1  mrg 	  gimple_assign_set_rhs3 (stmt, mask);
   1575  1.1  mrg 	  update_stmt (stmt);
   1576  1.1  mrg 	  return;
   1577  1.1  mrg 	}
   1578  1.1  mrg       /* Also detect vec_shr pattern - VEC_PERM_EXPR with zero
   1579  1.1  mrg 	 vector as VEC1 and a right element shift MASK.  */
   1580  1.1  mrg       if (optab_handler (vec_shr_optab, TYPE_MODE (vect_type))
   1581  1.1  mrg 	  != CODE_FOR_nothing
   1582  1.1  mrg 	  && TREE_CODE (vec1) == VECTOR_CST
   1583  1.1  mrg 	  && initializer_zerop (vec1)
   1584  1.1  mrg 	  && maybe_ne (indices[0], 0)
   1585  1.1  mrg 	  && known_lt (poly_uint64 (indices[0]), elements))
   1586  1.1  mrg 	{
   1587  1.1  mrg 	  bool ok_p = indices.series_p (0, 1, indices[0], 1);
   1588  1.1  mrg 	  if (!ok_p)
   1589  1.1  mrg 	    {
   1590  1.1  mrg 	      for (i = 1; i < elements; ++i)
   1591  1.1  mrg 		{
   1592  1.1  mrg 		  poly_uint64 actual = indices[i];
   1593  1.1  mrg 		  poly_uint64 expected = i + indices[0];
   1594  1.1  mrg 		  /* Indices into the second vector are all equivalent.  */
   1595  1.1  mrg 		  if (maybe_lt (actual, elements)
   1596  1.1  mrg 		      ? maybe_ne (actual, expected)
   1597  1.1  mrg 		      : maybe_lt (expected, elements))
   1598  1.1  mrg 		    break;
   1599  1.1  mrg 		}
   1600  1.1  mrg 	      ok_p = i == elements;
   1601  1.1  mrg 	    }
   1602  1.1  mrg 	  if (ok_p)
   1603  1.1  mrg 	    {
   1604  1.1  mrg 	      gimple_assign_set_rhs3 (stmt, mask);
   1605  1.1  mrg 	      update_stmt (stmt);
   1606  1.1  mrg 	      return;
   1607  1.1  mrg 	    }
   1608  1.1  mrg 	}
   1609  1.1  mrg       /* And similarly vec_shl pattern.  */
   1610  1.1  mrg       if (optab_handler (vec_shl_optab, TYPE_MODE (vect_type))
   1611  1.1  mrg 	  != CODE_FOR_nothing
   1612  1.1  mrg 	  && TREE_CODE (vec0) == VECTOR_CST
   1613  1.1  mrg 	  && initializer_zerop (vec0))
   1614  1.1  mrg 	{
   1615  1.1  mrg 	  unsigned int first = 0;
   1616  1.1  mrg 	  for (i = 0; i < elements; ++i)
   1617  1.1  mrg 	    if (known_eq (poly_uint64 (indices[i]), elements))
   1618  1.1  mrg 	      {
   1619  1.1  mrg 		if (i == 0 || first)
   1620  1.1  mrg 		  break;
   1621  1.1  mrg 		first = i;
   1622  1.1  mrg 	      }
   1623  1.1  mrg 	    else if (first
   1624  1.1  mrg 		     ? maybe_ne (poly_uint64 (indices[i]),
   1625  1.1  mrg 					      elements + i - first)
   1626  1.1  mrg 		     : maybe_ge (poly_uint64 (indices[i]), elements))
   1627  1.1  mrg 	      break;
   1628  1.1  mrg 	  if (first && i == elements)
   1629  1.1  mrg 	    {
   1630  1.1  mrg 	      gimple_assign_set_rhs3 (stmt, mask);
   1631  1.1  mrg 	      update_stmt (stmt);
   1632  1.1  mrg 	      return;
   1633  1.1  mrg 	    }
   1634  1.1  mrg 	}
   1635  1.1  mrg     }
   1636  1.1  mrg   else if (can_vec_perm_var_p (TYPE_MODE (vect_type)))
   1637  1.1  mrg     return;
   1638  1.1  mrg 
   1639  1.1  mrg   if (!warning_suppressed_p (stmt, OPT_Wvector_operation_performance))
   1640  1.1  mrg     warning_at (loc, OPT_Wvector_operation_performance,
   1641  1.1  mrg 		"vector shuffling operation will be expanded piecewise");
   1642  1.1  mrg 
   1643  1.1  mrg   vec_alloc (v, elements);
   1644  1.1  mrg   bool constant_p = true;
   1645  1.1  mrg   for (i = 0; i < elements; i++)
   1646  1.1  mrg     {
   1647  1.1  mrg       si = size_int (i);
   1648  1.1  mrg       i_val = vector_element (gsi, mask, si, &masktmp);
   1649  1.1  mrg 
   1650  1.1  mrg       if (TREE_CODE (i_val) == INTEGER_CST)
   1651  1.1  mrg         {
   1652  1.1  mrg 	  unsigned HOST_WIDE_INT index;
   1653  1.1  mrg 
   1654  1.1  mrg 	  index = TREE_INT_CST_LOW (i_val);
   1655  1.1  mrg 	  if (!tree_fits_uhwi_p (i_val) || index >= elements)
   1656  1.1  mrg 	    i_val = build_int_cst (mask_elt_type, index & (elements - 1));
   1657  1.1  mrg 
   1658  1.1  mrg           if (two_operand_p && (index & elements) != 0)
   1659  1.1  mrg 	    t = vector_element (gsi, vec1, i_val, &vec1tmp);
   1660  1.1  mrg 	  else
   1661  1.1  mrg 	    t = vector_element (gsi, vec0, i_val, &vec0tmp);
   1662  1.1  mrg 
   1663  1.1  mrg           t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE,
   1664  1.1  mrg 					true, GSI_SAME_STMT);
   1665  1.1  mrg         }
   1666  1.1  mrg       else
   1667  1.1  mrg         {
   1668  1.1  mrg 	  tree cond = NULL_TREE, v0_val;
   1669  1.1  mrg 
   1670  1.1  mrg 	  if (two_operand_p)
   1671  1.1  mrg 	    {
   1672  1.1  mrg 	      cond = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,
   1673  1.1  mrg 			          build_int_cst (mask_elt_type, elements));
   1674  1.1  mrg 	      cond = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE,
   1675  1.1  mrg 					       true, GSI_SAME_STMT);
   1676  1.1  mrg 	    }
   1677  1.1  mrg 
   1678  1.1  mrg 	  i_val = fold_build2 (BIT_AND_EXPR, mask_elt_type, i_val,
   1679  1.1  mrg 			       build_int_cst (mask_elt_type, elements - 1));
   1680  1.1  mrg 	  i_val = force_gimple_operand_gsi (gsi, i_val, true, NULL_TREE,
   1681  1.1  mrg 					    true, GSI_SAME_STMT);
   1682  1.1  mrg 
   1683  1.1  mrg 	  v0_val = vector_element (gsi, vec0, i_val, &vec0tmp);
   1684  1.1  mrg 	  v0_val = force_gimple_operand_gsi (gsi, v0_val, true, NULL_TREE,
   1685  1.1  mrg 					     true, GSI_SAME_STMT);
   1686  1.1  mrg 
   1687  1.1  mrg 	  if (two_operand_p)
   1688  1.1  mrg 	    {
   1689  1.1  mrg 	      tree v1_val;
   1690  1.1  mrg 
   1691  1.1  mrg 	      v1_val = vector_element (gsi, vec1, i_val, &vec1tmp);
   1692  1.1  mrg 	      v1_val = force_gimple_operand_gsi (gsi, v1_val, true, NULL_TREE,
   1693  1.1  mrg 						 true, GSI_SAME_STMT);
   1694  1.1  mrg 
   1695  1.1  mrg 	      cond = fold_build2 (EQ_EXPR, boolean_type_node,
   1696  1.1  mrg 				  cond, build_zero_cst (mask_elt_type));
   1697  1.1  mrg 	      cond = fold_build3 (COND_EXPR, vect_elt_type,
   1698  1.1  mrg 				  cond, v0_val, v1_val);
   1699  1.1  mrg               t = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE,
   1700  1.1  mrg 					    true, GSI_SAME_STMT);
   1701  1.1  mrg             }
   1702  1.1  mrg 	  else
   1703  1.1  mrg 	    t = v0_val;
   1704  1.1  mrg         }
   1705  1.1  mrg 
   1706  1.1  mrg       if (!CONSTANT_CLASS_P (t))
   1707  1.1  mrg 	constant_p = false;
   1708  1.1  mrg       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
   1709  1.1  mrg     }
   1710  1.1  mrg 
   1711  1.1  mrg   if (constant_p)
   1712  1.1  mrg     constr = build_vector_from_ctor (vect_type, v);
   1713  1.1  mrg   else
   1714  1.1  mrg     constr = build_constructor (vect_type, v);
   1715  1.1  mrg   gimple_assign_set_rhs_from_tree (gsi, constr);
   1716  1.1  mrg   update_stmt (gsi_stmt (*gsi));
   1717  1.1  mrg }
   1718  1.1  mrg 
   1719  1.1  mrg /* If OP is a uniform vector return the element it is a splat from.  */
   1720  1.1  mrg 
   1721  1.1  mrg static tree
   1722  1.1  mrg ssa_uniform_vector_p (tree op)
   1723  1.1  mrg {
   1724  1.1  mrg   if (TREE_CODE (op) == VECTOR_CST
   1725  1.1  mrg       || TREE_CODE (op) == VEC_DUPLICATE_EXPR
   1726  1.1  mrg       || TREE_CODE (op) == CONSTRUCTOR)
   1727  1.1  mrg     return uniform_vector_p (op);
   1728  1.1  mrg   if (TREE_CODE (op) == SSA_NAME)
   1729  1.1  mrg     {
   1730  1.1  mrg       gimple *def_stmt = SSA_NAME_DEF_STMT (op);
   1731  1.1  mrg       if (gimple_assign_single_p (def_stmt))
   1732  1.1  mrg 	return uniform_vector_p (gimple_assign_rhs1 (def_stmt));
   1733  1.1  mrg     }
   1734  1.1  mrg   return NULL_TREE;
   1735  1.1  mrg }
   1736  1.1  mrg 
   1737  1.1  mrg /* Return type in which CODE operation with optab OP can be
   1738  1.1  mrg    computed.  */
   1739  1.1  mrg 
   1740  1.1  mrg static tree
   1741  1.1  mrg get_compute_type (enum tree_code code, optab op, tree type)
   1742  1.1  mrg {
   1743  1.1  mrg   /* For very wide vectors, try using a smaller vector mode.  */
   1744  1.1  mrg   tree compute_type = type;
   1745  1.1  mrg   if (op
   1746  1.1  mrg       && (!VECTOR_MODE_P (TYPE_MODE (type))
   1747  1.1  mrg 	  || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing))
   1748  1.1  mrg     {
   1749  1.1  mrg       tree vector_compute_type
   1750  1.1  mrg 	= type_for_widest_vector_mode (type, op);
   1751  1.1  mrg       if (vector_compute_type != NULL_TREE
   1752  1.1  mrg 	  && maybe_ne (TYPE_VECTOR_SUBPARTS (vector_compute_type), 1U)
   1753  1.1  mrg 	  && (optab_handler (op, TYPE_MODE (vector_compute_type))
   1754  1.1  mrg 	      != CODE_FOR_nothing))
   1755  1.1  mrg 	compute_type = vector_compute_type;
   1756  1.1  mrg     }
   1757  1.1  mrg 
   1758  1.1  mrg   /* If we are breaking a BLKmode vector into smaller pieces,
   1759  1.1  mrg      type_for_widest_vector_mode has already looked into the optab,
   1760  1.1  mrg      so skip these checks.  */
   1761  1.1  mrg   if (compute_type == type)
   1762  1.1  mrg     {
   1763  1.1  mrg       machine_mode compute_mode = TYPE_MODE (compute_type);
   1764  1.1  mrg       if (VECTOR_MODE_P (compute_mode))
   1765  1.1  mrg 	{
   1766  1.1  mrg 	  if (op && optab_handler (op, compute_mode) != CODE_FOR_nothing)
   1767  1.1  mrg 	    return compute_type;
   1768  1.1  mrg 	  if (code == MULT_HIGHPART_EXPR
   1769  1.1  mrg 	      && can_mult_highpart_p (compute_mode,
   1770  1.1  mrg 				      TYPE_UNSIGNED (compute_type)))
   1771  1.1  mrg 	    return compute_type;
   1772  1.1  mrg 	}
   1773  1.1  mrg       /* There is no operation in hardware, so fall back to scalars.  */
   1774  1.1  mrg       compute_type = TREE_TYPE (type);
   1775  1.1  mrg     }
   1776  1.1  mrg 
   1777  1.1  mrg   return compute_type;
   1778  1.1  mrg }
   1779  1.1  mrg 
   1780  1.1  mrg static tree
   1781  1.1  mrg do_cond (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
   1782  1.1  mrg 	 tree bitpos, tree bitsize, enum tree_code code,
   1783  1.1  mrg 	 tree type ATTRIBUTE_UNUSED)
   1784  1.1  mrg {
   1785  1.1  mrg   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
   1786  1.1  mrg     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   1787  1.1  mrg   if (TREE_CODE (TREE_TYPE (b)) == VECTOR_TYPE)
   1788  1.1  mrg     b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
   1789  1.1  mrg   tree cond = gimple_assign_rhs1 (gsi_stmt (*gsi));
   1790  1.1  mrg   return gimplify_build3 (gsi, code, inner_type, unshare_expr (cond), a, b);
   1791  1.1  mrg }
   1792  1.1  mrg 
   1793  1.1  mrg /* Expand a vector COND_EXPR to scalars, piecewise.  */
   1794  1.1  mrg static void
   1795  1.1  mrg expand_vector_scalar_condition (gimple_stmt_iterator *gsi)
   1796  1.1  mrg {
   1797  1.1  mrg   gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   1798  1.1  mrg   tree lhs = gimple_assign_lhs (stmt);
   1799  1.1  mrg   tree type = TREE_TYPE (lhs);
   1800  1.1  mrg   tree compute_type = get_compute_type (COND_EXPR, mov_optab, type);
   1801  1.1  mrg   machine_mode compute_mode = TYPE_MODE (compute_type);
   1802  1.1  mrg   gcc_assert (compute_mode != BLKmode);
   1803  1.1  mrg   tree rhs2 = gimple_assign_rhs2 (stmt);
   1804  1.1  mrg   tree rhs3 = gimple_assign_rhs3 (stmt);
   1805  1.1  mrg   tree new_rhs;
   1806  1.1  mrg 
   1807  1.1  mrg   /* If the compute mode is not a vector mode (hence we are not decomposing
   1808  1.1  mrg      a BLKmode vector to smaller, hardware-supported vectors), we may want
   1809  1.1  mrg      to expand the operations in parallel.  */
   1810  1.1  mrg   if (!VECTOR_MODE_P (compute_mode))
   1811  1.1  mrg     new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3,
   1812  1.1  mrg 				      COND_EXPR);
   1813  1.1  mrg   else
   1814  1.1  mrg     new_rhs = expand_vector_piecewise (gsi, do_cond, type, compute_type,
   1815  1.1  mrg 				       rhs2, rhs3, COND_EXPR, false);
   1816  1.1  mrg   if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
   1817  1.1  mrg     new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
   1818  1.1  mrg 			       new_rhs);
   1819  1.1  mrg 
   1820  1.1  mrg   /* NOTE:  We should avoid using gimple_assign_set_rhs_from_tree. One
   1821  1.1  mrg      way to do it is change expand_vector_operation and its callees to
   1822  1.1  mrg      return a tree_code, RHS1 and RHS2 instead of a tree. */
   1823  1.1  mrg   gimple_assign_set_rhs_from_tree (gsi, new_rhs);
   1824  1.1  mrg   update_stmt (gsi_stmt (*gsi));
   1825  1.1  mrg }
   1826  1.1  mrg 
   1827  1.1  mrg /* Callback for expand_vector_piecewise to do VEC_CONVERT ifn call
   1828  1.1  mrg    lowering.  If INNER_TYPE is not a vector type, this is a scalar
   1829  1.1  mrg    fallback.  */
   1830  1.1  mrg 
   1831  1.1  mrg static tree
   1832  1.1  mrg do_vec_conversion (gimple_stmt_iterator *gsi, tree inner_type, tree a,
   1833  1.1  mrg 		   tree decl, tree bitpos, tree bitsize,
   1834  1.1  mrg 		   enum tree_code code, tree type)
   1835  1.1  mrg {
   1836  1.1  mrg   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   1837  1.1  mrg   if (!VECTOR_TYPE_P (inner_type))
   1838  1.1  mrg     return gimplify_build1 (gsi, code, TREE_TYPE (type), a);
   1839  1.1  mrg   if (code == CALL_EXPR)
   1840  1.1  mrg     {
   1841  1.1  mrg       gimple *g = gimple_build_call (decl, 1, a);
   1842  1.1  mrg       tree lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (decl)));
   1843  1.1  mrg       gimple_call_set_lhs (g, lhs);
   1844  1.1  mrg       gsi_insert_before (gsi, g, GSI_SAME_STMT);
   1845  1.1  mrg       return lhs;
   1846  1.1  mrg     }
   1847  1.1  mrg   else
   1848  1.1  mrg     {
   1849  1.1  mrg       tree outer_type = build_vector_type (TREE_TYPE (type),
   1850  1.1  mrg 					   TYPE_VECTOR_SUBPARTS (inner_type));
   1851  1.1  mrg       return gimplify_build1 (gsi, code, outer_type, a);
   1852  1.1  mrg     }
   1853  1.1  mrg }
   1854  1.1  mrg 
   1855  1.1  mrg /* Similarly, but for narrowing conversion.  */
   1856  1.1  mrg 
   1857  1.1  mrg static tree
   1858  1.1  mrg do_vec_narrow_conversion (gimple_stmt_iterator *gsi, tree inner_type, tree a,
   1859  1.1  mrg 			  tree, tree bitpos, tree, enum tree_code code,
   1860  1.1  mrg 			  tree type)
   1861  1.1  mrg {
   1862  1.1  mrg   tree itype = build_vector_type (TREE_TYPE (inner_type),
   1863  1.1  mrg 				  exact_div (TYPE_VECTOR_SUBPARTS (inner_type),
   1864  1.1  mrg 					     2));
   1865  1.1  mrg   tree b = tree_vec_extract (gsi, itype, a, TYPE_SIZE (itype), bitpos);
   1866  1.1  mrg   tree c = tree_vec_extract (gsi, itype, a, TYPE_SIZE (itype),
   1867  1.1  mrg 			     int_const_binop (PLUS_EXPR, bitpos,
   1868  1.1  mrg 					      TYPE_SIZE (itype)));
   1869  1.1  mrg   tree outer_type = build_vector_type (TREE_TYPE (type),
   1870  1.1  mrg 				       TYPE_VECTOR_SUBPARTS (inner_type));
   1871  1.1  mrg   return gimplify_build2 (gsi, code, outer_type, b, c);
   1872  1.1  mrg }
   1873  1.1  mrg 
   1874  1.1  mrg /* Expand VEC_CONVERT ifn call.  */
   1875  1.1  mrg 
   1876  1.1  mrg static void
   1877  1.1  mrg expand_vector_conversion (gimple_stmt_iterator *gsi)
   1878  1.1  mrg {
   1879  1.1  mrg   gimple *stmt = gsi_stmt (*gsi);
   1880  1.1  mrg   gimple *g;
   1881  1.1  mrg   tree lhs = gimple_call_lhs (stmt);
   1882  1.1  mrg   if (lhs == NULL_TREE)
   1883  1.1  mrg     {
   1884  1.1  mrg       g = gimple_build_nop ();
   1885  1.1  mrg       gsi_replace (gsi, g, false);
   1886  1.1  mrg       return;
   1887  1.1  mrg     }
   1888  1.1  mrg   tree arg = gimple_call_arg (stmt, 0);
   1889  1.1  mrg   tree ret_type = TREE_TYPE (lhs);
   1890  1.1  mrg   tree arg_type = TREE_TYPE (arg);
   1891  1.1  mrg   tree new_rhs, compute_type = TREE_TYPE (arg_type);
   1892  1.1  mrg   enum tree_code code = NOP_EXPR;
   1893  1.1  mrg   enum tree_code code1 = ERROR_MARK;
   1894  1.1  mrg   enum { NARROW, NONE, WIDEN } modifier = NONE;
   1895  1.1  mrg   optab optab1 = unknown_optab;
   1896  1.1  mrg 
   1897  1.1  mrg   gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type));
   1898  1.1  mrg   if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
   1899  1.1  mrg       && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type)))
   1900  1.1  mrg     code = FIX_TRUNC_EXPR;
   1901  1.1  mrg   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
   1902  1.1  mrg 	   && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type)))
   1903  1.1  mrg     code = FLOAT_EXPR;
   1904  1.1  mrg   unsigned int ret_elt_bits = vector_element_bits (ret_type);
   1905  1.1  mrg   unsigned int arg_elt_bits = vector_element_bits (arg_type);
   1906  1.1  mrg   if (ret_elt_bits < arg_elt_bits)
   1907  1.1  mrg     modifier = NARROW;
   1908  1.1  mrg   else if (ret_elt_bits > arg_elt_bits)
   1909  1.1  mrg     modifier = WIDEN;
   1910  1.1  mrg 
   1911  1.1  mrg   if (modifier == NONE && (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR))
   1912  1.1  mrg     {
   1913  1.1  mrg       if (supportable_convert_operation (code, ret_type, arg_type, &code1))
   1914  1.1  mrg 	{
   1915  1.1  mrg 	  g = gimple_build_assign (lhs, code1, arg);
   1916  1.1  mrg 	  gsi_replace (gsi, g, false);
   1917  1.1  mrg 	  return;
   1918  1.1  mrg 	}
   1919  1.1  mrg       /* Can't use get_compute_type here, as supportable_convert_operation
   1920  1.1  mrg 	 doesn't necessarily use an optab and needs two arguments.  */
   1921  1.1  mrg       tree vec_compute_type
   1922  1.1  mrg 	= type_for_widest_vector_mode (arg_type, mov_optab);
   1923  1.1  mrg       if (vec_compute_type
   1924  1.1  mrg 	  && VECTOR_MODE_P (TYPE_MODE (vec_compute_type)))
   1925  1.1  mrg 	{
   1926  1.1  mrg 	  unsigned HOST_WIDE_INT nelts
   1927  1.1  mrg 	    = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vec_compute_type));
   1928  1.1  mrg 	  while (nelts > 1)
   1929  1.1  mrg 	    {
   1930  1.1  mrg 	      tree ret1_type = build_vector_type (TREE_TYPE (ret_type), nelts);
   1931  1.1  mrg 	      tree arg1_type = build_vector_type (TREE_TYPE (arg_type), nelts);
   1932  1.1  mrg 	      if (supportable_convert_operation (code, ret1_type, arg1_type,
   1933  1.1  mrg 						 &code1))
   1934  1.1  mrg 		{
   1935  1.1  mrg 		  new_rhs = expand_vector_piecewise (gsi, do_vec_conversion,
   1936  1.1  mrg 						     ret_type, arg1_type, arg,
   1937  1.1  mrg 						     NULL_TREE, code1, false);
   1938  1.1  mrg 		  g = gimple_build_assign (lhs, new_rhs);
   1939  1.1  mrg 		  gsi_replace (gsi, g, false);
   1940  1.1  mrg 		  return;
   1941  1.1  mrg 		}
   1942  1.1  mrg 	      nelts = nelts / 2;
   1943  1.1  mrg 	    }
   1944  1.1  mrg 	}
   1945  1.1  mrg     }
   1946  1.1  mrg   else if (modifier == NARROW)
   1947  1.1  mrg     {
   1948  1.1  mrg       switch (code)
   1949  1.1  mrg 	{
   1950  1.1  mrg 	CASE_CONVERT:
   1951  1.1  mrg 	  code1 = VEC_PACK_TRUNC_EXPR;
   1952  1.1  mrg 	  optab1 = optab_for_tree_code (code1, arg_type, optab_default);
   1953  1.1  mrg 	  break;
   1954  1.1  mrg 	case FIX_TRUNC_EXPR:
   1955  1.1  mrg 	  code1 = VEC_PACK_FIX_TRUNC_EXPR;
   1956  1.1  mrg 	  /* The signedness is determined from output operand.  */
   1957  1.1  mrg 	  optab1 = optab_for_tree_code (code1, ret_type, optab_default);
   1958  1.1  mrg 	  break;
   1959  1.1  mrg 	case FLOAT_EXPR:
   1960  1.1  mrg 	  code1 = VEC_PACK_FLOAT_EXPR;
   1961  1.1  mrg 	  optab1 = optab_for_tree_code (code1, arg_type, optab_default);
   1962  1.1  mrg 	  break;
   1963  1.1  mrg 	default:
   1964  1.1  mrg 	  gcc_unreachable ();
   1965  1.1  mrg 	}
   1966  1.1  mrg 
   1967  1.1  mrg       if (optab1)
   1968  1.1  mrg 	compute_type = get_compute_type (code1, optab1, arg_type);
   1969  1.1  mrg       enum insn_code icode1;
   1970  1.1  mrg       if (VECTOR_TYPE_P (compute_type)
   1971  1.1  mrg 	  && ((icode1 = optab_handler (optab1, TYPE_MODE (compute_type)))
   1972  1.1  mrg 	      != CODE_FOR_nothing)
   1973  1.1  mrg 	  && VECTOR_MODE_P (insn_data[icode1].operand[0].mode))
   1974  1.1  mrg 	{
   1975  1.1  mrg 	  tree cretd_type
   1976  1.1  mrg 	    = build_vector_type (TREE_TYPE (ret_type),
   1977  1.1  mrg 				 TYPE_VECTOR_SUBPARTS (compute_type) * 2);
   1978  1.1  mrg 	  if (insn_data[icode1].operand[0].mode == TYPE_MODE (cretd_type))
   1979  1.1  mrg 	    {
   1980  1.1  mrg 	      if (compute_type == arg_type)
   1981  1.1  mrg 		{
   1982  1.1  mrg 		  new_rhs = gimplify_build2 (gsi, code1, cretd_type,
   1983  1.1  mrg 					     arg, build_zero_cst (arg_type));
   1984  1.1  mrg 		  new_rhs = tree_vec_extract (gsi, ret_type, new_rhs,
   1985  1.1  mrg 					      TYPE_SIZE (ret_type),
   1986  1.1  mrg 					      bitsize_int (0));
   1987  1.1  mrg 		  g = gimple_build_assign (lhs, new_rhs);
   1988  1.1  mrg 		  gsi_replace (gsi, g, false);
   1989  1.1  mrg 		  return;
   1990  1.1  mrg 		}
   1991  1.1  mrg 	      tree dcompute_type
   1992  1.1  mrg 		= build_vector_type (TREE_TYPE (compute_type),
   1993  1.1  mrg 				     TYPE_VECTOR_SUBPARTS (compute_type) * 2);
   1994  1.1  mrg 	      if (TYPE_MAIN_VARIANT (dcompute_type)
   1995  1.1  mrg 		  == TYPE_MAIN_VARIANT (arg_type))
   1996  1.1  mrg 		new_rhs = do_vec_narrow_conversion (gsi, dcompute_type, arg,
   1997  1.1  mrg 						    NULL_TREE, bitsize_int (0),
   1998  1.1  mrg 						    NULL_TREE, code1,
   1999  1.1  mrg 						    ret_type);
   2000  1.1  mrg 	      else
   2001  1.1  mrg 		new_rhs = expand_vector_piecewise (gsi,
   2002  1.1  mrg 						   do_vec_narrow_conversion,
   2003  1.1  mrg 						   arg_type, dcompute_type,
   2004  1.1  mrg 						   arg, NULL_TREE, code1,
   2005  1.1  mrg 						   false, ret_type);
   2006  1.1  mrg 	      g = gimple_build_assign (lhs, new_rhs);
   2007  1.1  mrg 	      gsi_replace (gsi, g, false);
   2008  1.1  mrg 	      return;
   2009  1.1  mrg 	    }
   2010  1.1  mrg 	}
   2011  1.1  mrg     }
   2012  1.1  mrg   else if (modifier == WIDEN)
   2013  1.1  mrg     {
   2014  1.1  mrg       enum tree_code code2 = ERROR_MARK;
   2015  1.1  mrg       optab optab2 = unknown_optab;
   2016  1.1  mrg       switch (code)
   2017  1.1  mrg 	{
   2018  1.1  mrg 	CASE_CONVERT:
   2019  1.1  mrg 	  code1 = VEC_UNPACK_LO_EXPR;
   2020  1.1  mrg           code2 = VEC_UNPACK_HI_EXPR;
   2021  1.1  mrg 	  break;
   2022  1.1  mrg 	case FIX_TRUNC_EXPR:
   2023  1.1  mrg 	  code1 = VEC_UNPACK_FIX_TRUNC_LO_EXPR;
   2024  1.1  mrg 	  code2 = VEC_UNPACK_FIX_TRUNC_HI_EXPR;
   2025  1.1  mrg 	  break;
   2026  1.1  mrg 	case FLOAT_EXPR:
   2027  1.1  mrg 	  code1 = VEC_UNPACK_FLOAT_LO_EXPR;
   2028  1.1  mrg 	  code2 = VEC_UNPACK_FLOAT_HI_EXPR;
   2029  1.1  mrg 	  break;
   2030  1.1  mrg 	default:
   2031  1.1  mrg 	  gcc_unreachable ();
   2032  1.1  mrg 	}
   2033  1.1  mrg       if (BYTES_BIG_ENDIAN)
   2034  1.1  mrg 	std::swap (code1, code2);
   2035  1.1  mrg 
   2036  1.1  mrg       if (code == FIX_TRUNC_EXPR)
   2037  1.1  mrg 	{
   2038  1.1  mrg 	  /* The signedness is determined from output operand.  */
   2039  1.1  mrg 	  optab1 = optab_for_tree_code (code1, ret_type, optab_default);
   2040  1.1  mrg 	  optab2 = optab_for_tree_code (code2, ret_type, optab_default);
   2041  1.1  mrg 	}
   2042  1.1  mrg       else
   2043  1.1  mrg 	{
   2044  1.1  mrg 	  optab1 = optab_for_tree_code (code1, arg_type, optab_default);
   2045  1.1  mrg 	  optab2 = optab_for_tree_code (code2, arg_type, optab_default);
   2046  1.1  mrg 	}
   2047  1.1  mrg 
   2048  1.1  mrg       if (optab1 && optab2)
   2049  1.1  mrg 	compute_type = get_compute_type (code1, optab1, arg_type);
   2050  1.1  mrg 
   2051  1.1  mrg       enum insn_code icode1, icode2;
   2052  1.1  mrg       if (VECTOR_TYPE_P (compute_type)
   2053  1.1  mrg 	  && ((icode1 = optab_handler (optab1, TYPE_MODE (compute_type)))
   2054  1.1  mrg 	      != CODE_FOR_nothing)
   2055  1.1  mrg 	  && ((icode2 = optab_handler (optab2, TYPE_MODE (compute_type)))
   2056  1.1  mrg 	      != CODE_FOR_nothing)
   2057  1.1  mrg 	  && VECTOR_MODE_P (insn_data[icode1].operand[0].mode)
   2058  1.1  mrg 	  && (insn_data[icode1].operand[0].mode
   2059  1.1  mrg 	      == insn_data[icode2].operand[0].mode))
   2060  1.1  mrg 	{
   2061  1.1  mrg 	  poly_uint64 nunits
   2062  1.1  mrg 	    = exact_div (TYPE_VECTOR_SUBPARTS (compute_type), 2);
   2063  1.1  mrg 	  tree cretd_type = build_vector_type (TREE_TYPE (ret_type), nunits);
   2064  1.1  mrg 	  if (insn_data[icode1].operand[0].mode == TYPE_MODE (cretd_type))
   2065  1.1  mrg 	    {
   2066  1.1  mrg 	      vec<constructor_elt, va_gc> *v;
   2067  1.1  mrg 	      tree part_width = TYPE_SIZE (compute_type);
   2068  1.1  mrg 	      tree index = bitsize_int (0);
   2069  1.1  mrg 	      int nunits = nunits_for_known_piecewise_op (arg_type);
   2070  1.1  mrg 	      int delta = tree_to_uhwi (part_width) / arg_elt_bits;
   2071  1.1  mrg 	      int i;
   2072  1.1  mrg 	      location_t loc = gimple_location (gsi_stmt (*gsi));
   2073  1.1  mrg 
   2074  1.1  mrg 	      if (compute_type != arg_type)
   2075  1.1  mrg 		{
   2076  1.1  mrg 		  if (!warning_suppressed_p (gsi_stmt (*gsi),
   2077  1.1  mrg 					     OPT_Wvector_operation_performance))
   2078  1.1  mrg 		    warning_at (loc, OPT_Wvector_operation_performance,
   2079  1.1  mrg 				"vector operation will be expanded piecewise");
   2080  1.1  mrg 		}
   2081  1.1  mrg 	      else
   2082  1.1  mrg 		{
   2083  1.1  mrg 		  nunits = 1;
   2084  1.1  mrg 		  delta = 1;
   2085  1.1  mrg 		}
   2086  1.1  mrg 
   2087  1.1  mrg 	      vec_alloc (v, (nunits + delta - 1) / delta * 2);
   2088  1.1  mrg 	      bool constant_p = true;
   2089  1.1  mrg 	      for (i = 0; i < nunits;
   2090  1.1  mrg 		   i += delta, index = int_const_binop (PLUS_EXPR, index,
   2091  1.1  mrg 							part_width))
   2092  1.1  mrg 		{
   2093  1.1  mrg 		  tree a = arg;
   2094  1.1  mrg 		  if (compute_type != arg_type)
   2095  1.1  mrg 		    a = tree_vec_extract (gsi, compute_type, a, part_width,
   2096  1.1  mrg 					  index);
   2097  1.1  mrg 		  tree result = gimplify_build1 (gsi, code1, cretd_type, a);
   2098  1.1  mrg 		  constructor_elt ce = { NULL_TREE, result };
   2099  1.1  mrg 		  if (!CONSTANT_CLASS_P (ce.value))
   2100  1.1  mrg 		    constant_p = false;
   2101  1.1  mrg 		  v->quick_push (ce);
   2102  1.1  mrg 		  ce.value = gimplify_build1 (gsi, code2, cretd_type, a);
   2103  1.1  mrg 		  if (!CONSTANT_CLASS_P (ce.value))
   2104  1.1  mrg 		    constant_p = false;
   2105  1.1  mrg 		  v->quick_push (ce);
   2106  1.1  mrg 		}
   2107  1.1  mrg 
   2108  1.1  mrg 	      if (constant_p)
   2109  1.1  mrg 		new_rhs = build_vector_from_ctor (ret_type, v);
   2110  1.1  mrg 	      else
   2111  1.1  mrg 		new_rhs = build_constructor (ret_type, v);
   2112  1.1  mrg 	      g = gimple_build_assign (lhs, new_rhs);
   2113  1.1  mrg 	      gsi_replace (gsi, g, false);
   2114  1.1  mrg 	      return;
   2115  1.1  mrg 	    }
   2116  1.1  mrg 	}
   2117  1.1  mrg     }
   2118  1.1  mrg 
   2119  1.1  mrg   new_rhs = expand_vector_piecewise (gsi, do_vec_conversion, arg_type,
   2120  1.1  mrg 				     TREE_TYPE (arg_type), arg,
   2121  1.1  mrg 				     NULL_TREE, code, false, ret_type);
   2122  1.1  mrg   g = gimple_build_assign (lhs, new_rhs);
   2123  1.1  mrg   gsi_replace (gsi, g, false);
   2124  1.1  mrg }
   2125  1.1  mrg 
   2126  1.1  mrg /* Process one statement.  If we identify a vector operation, expand it.  */
   2127  1.1  mrg 
   2128  1.1  mrg static void
   2129  1.1  mrg expand_vector_operations_1 (gimple_stmt_iterator *gsi,
   2130  1.1  mrg 			    bitmap dce_ssa_names)
   2131  1.1  mrg {
   2132  1.1  mrg   tree lhs, rhs1, rhs2 = NULL, type, compute_type = NULL_TREE;
   2133  1.1  mrg   enum tree_code code;
   2134  1.1  mrg   optab op = unknown_optab;
   2135  1.1  mrg   enum gimple_rhs_class rhs_class;
   2136  1.1  mrg   tree new_rhs;
   2137  1.1  mrg 
   2138  1.1  mrg   /* Only consider code == GIMPLE_ASSIGN. */
   2139  1.1  mrg   gassign *stmt = dyn_cast <gassign *> (gsi_stmt (*gsi));
   2140  1.1  mrg   if (!stmt)
   2141  1.1  mrg     {
   2142  1.1  mrg       if (gimple_call_internal_p (gsi_stmt (*gsi), IFN_VEC_CONVERT))
   2143  1.1  mrg 	expand_vector_conversion (gsi);
   2144  1.1  mrg       return;
   2145  1.1  mrg     }
   2146  1.1  mrg 
   2147  1.1  mrg   code = gimple_assign_rhs_code (stmt);
   2148  1.1  mrg   rhs_class = get_gimple_rhs_class (code);
   2149  1.1  mrg   lhs = gimple_assign_lhs (stmt);
   2150  1.1  mrg 
   2151  1.1  mrg   if (code == VEC_PERM_EXPR)
   2152  1.1  mrg     {
   2153  1.1  mrg       lower_vec_perm (gsi);
   2154  1.1  mrg       return;
   2155  1.1  mrg     }
   2156  1.1  mrg 
   2157  1.1  mrg   if (code == VEC_COND_EXPR)
   2158  1.1  mrg     {
   2159  1.1  mrg       expand_vector_condition (gsi, dce_ssa_names);
   2160  1.1  mrg       return;
   2161  1.1  mrg     }
   2162  1.1  mrg 
   2163  1.1  mrg   if (code == COND_EXPR
   2164  1.1  mrg       && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt))) == VECTOR_TYPE
   2165  1.1  mrg       && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode)
   2166  1.1  mrg     {
   2167  1.1  mrg       expand_vector_scalar_condition (gsi);
   2168  1.1  mrg       return;
   2169  1.1  mrg     }
   2170  1.1  mrg 
   2171  1.1  mrg   if (code == CONSTRUCTOR
   2172  1.1  mrg       && TREE_CODE (lhs) == SSA_NAME
   2173  1.1  mrg       && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))
   2174  1.1  mrg       && !gimple_clobber_p (stmt)
   2175  1.1  mrg       && optimize)
   2176  1.1  mrg     {
   2177  1.1  mrg       optimize_vector_constructor (gsi);
   2178  1.1  mrg       return;
   2179  1.1  mrg     }
   2180  1.1  mrg 
   2181  1.1  mrg   if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
   2182  1.1  mrg     return;
   2183  1.1  mrg 
   2184  1.1  mrg   rhs1 = gimple_assign_rhs1 (stmt);
   2185  1.1  mrg   if (rhs_class == GIMPLE_BINARY_RHS)
   2186  1.1  mrg     rhs2 = gimple_assign_rhs2 (stmt);
   2187  1.1  mrg 
   2188  1.1  mrg   type = TREE_TYPE (lhs);
   2189  1.1  mrg   if (!VECTOR_TYPE_P (type)
   2190  1.1  mrg       || !VECTOR_TYPE_P (TREE_TYPE (rhs1)))
   2191  1.1  mrg     return;
   2192  1.1  mrg 
   2193  1.1  mrg   /* A scalar operation pretending to be a vector one.  */
   2194  1.1  mrg   if (VECTOR_BOOLEAN_TYPE_P (type)
   2195  1.1  mrg       && !VECTOR_MODE_P (TYPE_MODE (type))
   2196  1.1  mrg       && TYPE_MODE (type) != BLKmode
   2197  1.1  mrg       && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) != tcc_comparison
   2198  1.1  mrg 	  || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1))
   2199  1.1  mrg 	      && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1)))
   2200  1.1  mrg 	      && TYPE_MODE (TREE_TYPE (rhs1)) != BLKmode)))
   2201  1.1  mrg     return;
   2202  1.1  mrg 
   2203  1.1  mrg   /* If the vector operation is operating on all same vector elements
   2204  1.1  mrg      implement it with a scalar operation and a splat if the target
   2205  1.1  mrg      supports the scalar operation.  */
   2206  1.1  mrg   tree srhs1, srhs2 = NULL_TREE;
   2207  1.1  mrg   if ((srhs1 = ssa_uniform_vector_p (rhs1)) != NULL_TREE
   2208  1.1  mrg       && (rhs2 == NULL_TREE
   2209  1.1  mrg 	  || (! VECTOR_TYPE_P (TREE_TYPE (rhs2))
   2210  1.1  mrg 	      && (srhs2 = rhs2))
   2211  1.1  mrg 	  || (srhs2 = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
   2212  1.1  mrg       /* As we query direct optabs restrict to non-convert operations.  */
   2213  1.1  mrg       && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (TREE_TYPE (srhs1)))
   2214  1.1  mrg     {
   2215  1.1  mrg       op = optab_for_tree_code (code, TREE_TYPE (type), optab_scalar);
   2216  1.1  mrg       if (op >= FIRST_NORM_OPTAB && op <= LAST_NORM_OPTAB
   2217  1.1  mrg 	  && optab_handler (op, TYPE_MODE (TREE_TYPE (type))) != CODE_FOR_nothing)
   2218  1.1  mrg 	{
   2219  1.1  mrg 	  tree stype = TREE_TYPE (TREE_TYPE (lhs));
   2220  1.1  mrg 	  tree slhs = (rhs2 != NULL_TREE)
   2221  1.1  mrg 		      ? gimplify_build2 (gsi, code, stype, srhs1, srhs2)
   2222  1.1  mrg 		      : gimplify_build1 (gsi, code, stype, srhs1);
   2223  1.1  mrg 	  gimple_assign_set_rhs_from_tree (gsi,
   2224  1.1  mrg 					   build_vector_from_val (type, slhs));
   2225  1.1  mrg 	  update_stmt (stmt);
   2226  1.1  mrg 	  return;
   2227  1.1  mrg 	}
   2228  1.1  mrg     }
   2229  1.1  mrg 
   2230  1.1  mrg   if (CONVERT_EXPR_CODE_P (code)
   2231  1.1  mrg       || code == FLOAT_EXPR
   2232  1.1  mrg       || code == FIX_TRUNC_EXPR
   2233  1.1  mrg       || code == VIEW_CONVERT_EXPR)
   2234  1.1  mrg     return;
   2235  1.1  mrg 
   2236  1.1  mrg   /* The signedness is determined from input argument.  */
   2237  1.1  mrg   if (code == VEC_UNPACK_FLOAT_HI_EXPR
   2238  1.1  mrg       || code == VEC_UNPACK_FLOAT_LO_EXPR
   2239  1.1  mrg       || code == VEC_PACK_FLOAT_EXPR)
   2240  1.1  mrg     {
   2241  1.1  mrg       /* We do not know how to scalarize those.  */
   2242  1.1  mrg       return;
   2243  1.1  mrg     }
   2244  1.1  mrg 
   2245  1.1  mrg   /* For widening/narrowing vector operations, the relevant type is of the
   2246  1.1  mrg      arguments, not the widened result.  VEC_UNPACK_FLOAT_*_EXPR is
   2247  1.1  mrg      calculated in the same way above.  */
   2248  1.1  mrg   if (code == WIDEN_SUM_EXPR
   2249  1.1  mrg       || code == VEC_WIDEN_PLUS_HI_EXPR
   2250  1.1  mrg       || code == VEC_WIDEN_PLUS_LO_EXPR
   2251  1.1  mrg       || code == VEC_WIDEN_MINUS_HI_EXPR
   2252  1.1  mrg       || code == VEC_WIDEN_MINUS_LO_EXPR
   2253  1.1  mrg       || code == VEC_WIDEN_MULT_HI_EXPR
   2254  1.1  mrg       || code == VEC_WIDEN_MULT_LO_EXPR
   2255  1.1  mrg       || code == VEC_WIDEN_MULT_EVEN_EXPR
   2256  1.1  mrg       || code == VEC_WIDEN_MULT_ODD_EXPR
   2257  1.1  mrg       || code == VEC_UNPACK_HI_EXPR
   2258  1.1  mrg       || code == VEC_UNPACK_LO_EXPR
   2259  1.1  mrg       || code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
   2260  1.1  mrg       || code == VEC_UNPACK_FIX_TRUNC_LO_EXPR
   2261  1.1  mrg       || code == VEC_PACK_TRUNC_EXPR
   2262  1.1  mrg       || code == VEC_PACK_SAT_EXPR
   2263  1.1  mrg       || code == VEC_PACK_FIX_TRUNC_EXPR
   2264  1.1  mrg       || code == VEC_WIDEN_LSHIFT_HI_EXPR
   2265  1.1  mrg       || code == VEC_WIDEN_LSHIFT_LO_EXPR)
   2266  1.1  mrg     {
   2267  1.1  mrg       /* We do not know how to scalarize those.  */
   2268  1.1  mrg       return;
   2269  1.1  mrg     }
   2270  1.1  mrg 
   2271  1.1  mrg   /* Choose between vector shift/rotate by vector and vector shift/rotate by
   2272  1.1  mrg      scalar */
   2273  1.1  mrg   if (code == LSHIFT_EXPR
   2274  1.1  mrg       || code == RSHIFT_EXPR
   2275  1.1  mrg       || code == LROTATE_EXPR
   2276  1.1  mrg       || code == RROTATE_EXPR)
   2277  1.1  mrg     {
   2278  1.1  mrg       optab opv;
   2279  1.1  mrg 
   2280  1.1  mrg       /* Check whether we have vector <op> {x,x,x,x} where x
   2281  1.1  mrg          could be a scalar variable or a constant.  Transform
   2282  1.1  mrg          vector <op> {x,x,x,x} ==> vector <op> scalar.  */
   2283  1.1  mrg       if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
   2284  1.1  mrg         {
   2285  1.1  mrg           tree first;
   2286  1.1  mrg 
   2287  1.1  mrg           if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
   2288  1.1  mrg             {
   2289  1.1  mrg               gimple_assign_set_rhs2 (stmt, first);
   2290  1.1  mrg               update_stmt (stmt);
   2291  1.1  mrg               rhs2 = first;
   2292  1.1  mrg             }
   2293  1.1  mrg         }
   2294  1.1  mrg 
   2295  1.1  mrg       opv = optab_for_tree_code (code, type, optab_vector);
   2296  1.1  mrg       if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
   2297  1.1  mrg 	op = opv;
   2298  1.1  mrg       else
   2299  1.1  mrg 	{
   2300  1.1  mrg           op = optab_for_tree_code (code, type, optab_scalar);
   2301  1.1  mrg 
   2302  1.1  mrg 	  compute_type = get_compute_type (code, op, type);
   2303  1.1  mrg 	  if (compute_type == type)
   2304  1.1  mrg 	    return;
   2305  1.1  mrg 	  /* The rtl expander will expand vector/scalar as vector/vector
   2306  1.1  mrg 	     if necessary.  Pick one with wider vector type.  */
   2307  1.1  mrg 	  tree compute_vtype = get_compute_type (code, opv, type);
   2308  1.1  mrg 	  if (subparts_gt (compute_vtype, compute_type))
   2309  1.1  mrg 	    {
   2310  1.1  mrg 	      compute_type = compute_vtype;
   2311  1.1  mrg 	      op = opv;
   2312  1.1  mrg 	    }
   2313  1.1  mrg 	}
   2314  1.1  mrg 
   2315  1.1  mrg       if (code == LROTATE_EXPR || code == RROTATE_EXPR)
   2316  1.1  mrg 	{
   2317  1.1  mrg 	  if (compute_type == NULL_TREE)
   2318  1.1  mrg 	    compute_type = get_compute_type (code, op, type);
   2319  1.1  mrg 	  if (compute_type == type)
   2320  1.1  mrg 	    return;
   2321  1.1  mrg 	  /* Before splitting vector rotates into scalar rotates,
   2322  1.1  mrg 	     see if we can't use vector shifts and BIT_IOR_EXPR
   2323  1.1  mrg 	     instead.  For vector by vector rotates we'd also
   2324  1.1  mrg 	     need to check BIT_AND_EXPR and NEGATE_EXPR, punt there
   2325  1.1  mrg 	     for now, fold doesn't seem to create such rotates anyway.  */
   2326  1.1  mrg 	  if (compute_type == TREE_TYPE (type)
   2327  1.1  mrg 	      && !VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
   2328  1.1  mrg 	    {
   2329  1.1  mrg 	      optab oplv = vashl_optab, opl = ashl_optab;
   2330  1.1  mrg 	      optab oprv = vlshr_optab, opr = lshr_optab, opo = ior_optab;
   2331  1.1  mrg 	      tree compute_lvtype = get_compute_type (LSHIFT_EXPR, oplv, type);
   2332  1.1  mrg 	      tree compute_rvtype = get_compute_type (RSHIFT_EXPR, oprv, type);
   2333  1.1  mrg 	      tree compute_otype = get_compute_type (BIT_IOR_EXPR, opo, type);
   2334  1.1  mrg 	      tree compute_ltype = get_compute_type (LSHIFT_EXPR, opl, type);
   2335  1.1  mrg 	      tree compute_rtype = get_compute_type (RSHIFT_EXPR, opr, type);
   2336  1.1  mrg 	      /* The rtl expander will expand vector/scalar as vector/vector
   2337  1.1  mrg 		 if necessary.  Pick one with wider vector type.  */
   2338  1.1  mrg 	      if (subparts_gt (compute_lvtype, compute_ltype))
   2339  1.1  mrg 		{
   2340  1.1  mrg 		  compute_ltype = compute_lvtype;
   2341  1.1  mrg 		  opl = oplv;
   2342  1.1  mrg 		}
   2343  1.1  mrg 	      if (subparts_gt (compute_rvtype, compute_rtype))
   2344  1.1  mrg 		{
   2345  1.1  mrg 		  compute_rtype = compute_rvtype;
   2346  1.1  mrg 		  opr = oprv;
   2347  1.1  mrg 		}
   2348  1.1  mrg 	      /* Pick the narrowest type from LSHIFT_EXPR, RSHIFT_EXPR and
   2349  1.1  mrg 		 BIT_IOR_EXPR.  */
   2350  1.1  mrg 	      compute_type = compute_ltype;
   2351  1.1  mrg 	      if (subparts_gt (compute_type, compute_rtype))
   2352  1.1  mrg 		compute_type = compute_rtype;
   2353  1.1  mrg 	      if (subparts_gt (compute_type, compute_otype))
   2354  1.1  mrg 		compute_type = compute_otype;
   2355  1.1  mrg 	      /* Verify all 3 operations can be performed in that type.  */
   2356  1.1  mrg 	      if (compute_type != TREE_TYPE (type))
   2357  1.1  mrg 		{
   2358  1.1  mrg 		  if (optab_handler (opl, TYPE_MODE (compute_type))
   2359  1.1  mrg 		      == CODE_FOR_nothing
   2360  1.1  mrg 		      || optab_handler (opr, TYPE_MODE (compute_type))
   2361  1.1  mrg 			 == CODE_FOR_nothing
   2362  1.1  mrg 		      || optab_handler (opo, TYPE_MODE (compute_type))
   2363  1.1  mrg 			 == CODE_FOR_nothing)
   2364  1.1  mrg 		    compute_type = TREE_TYPE (type);
   2365  1.1  mrg 		}
   2366  1.1  mrg 	    }
   2367  1.1  mrg 	}
   2368  1.1  mrg     }
   2369  1.1  mrg   else
   2370  1.1  mrg     op = optab_for_tree_code (code, type, optab_default);
   2371  1.1  mrg 
   2372  1.1  mrg   /* Optabs will try converting a negation into a subtraction, so
   2373  1.1  mrg      look for it as well.  TODO: negation of floating-point vectors
   2374  1.1  mrg      might be turned into an exclusive OR toggling the sign bit.  */
   2375  1.1  mrg   if (op == unknown_optab
   2376  1.1  mrg       && code == NEGATE_EXPR
   2377  1.1  mrg       && INTEGRAL_TYPE_P (TREE_TYPE (type)))
   2378  1.1  mrg     op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
   2379  1.1  mrg 
   2380  1.1  mrg   if (compute_type == NULL_TREE)
   2381  1.1  mrg     compute_type = get_compute_type (code, op, type);
   2382  1.1  mrg   if (compute_type == type)
   2383  1.1  mrg     return;
   2384  1.1  mrg 
   2385  1.1  mrg   new_rhs = expand_vector_operation (gsi, type, compute_type, stmt, code,
   2386  1.1  mrg 				     dce_ssa_names);
   2387  1.1  mrg 
   2388  1.1  mrg   /* Leave expression untouched for later expansion.  */
   2389  1.1  mrg   if (new_rhs == NULL_TREE)
   2390  1.1  mrg     return;
   2391  1.1  mrg 
   2392  1.1  mrg   if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
   2393  1.1  mrg     new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
   2394  1.1  mrg                                new_rhs);
   2395  1.1  mrg 
   2396  1.1  mrg   /* NOTE:  We should avoid using gimple_assign_set_rhs_from_tree. One
   2397  1.1  mrg      way to do it is change expand_vector_operation and its callees to
   2398  1.1  mrg      return a tree_code, RHS1 and RHS2 instead of a tree. */
   2399  1.1  mrg   gimple_assign_set_rhs_from_tree (gsi, new_rhs);
   2400  1.1  mrg   update_stmt (gsi_stmt (*gsi));
   2401  1.1  mrg }
   2402  1.1  mrg 
   2403  1.1  mrg /* Use this to lower vector operations introduced by the vectorizer,
   2405  1.1  mrg    if it may need the bit-twiddling tricks implemented in this file.  */
   2406  1.1  mrg 
   2407  1.1  mrg static unsigned int
   2408  1.1  mrg expand_vector_operations (void)
   2409  1.1  mrg {
   2410  1.1  mrg   gimple_stmt_iterator gsi;
   2411  1.1  mrg   basic_block bb;
   2412  1.1  mrg   bool cfg_changed = false;
   2413  1.1  mrg 
   2414  1.1  mrg   auto_bitmap dce_ssa_names;
   2415  1.1  mrg 
   2416  1.1  mrg   FOR_EACH_BB_FN (bb, cfun)
   2417  1.1  mrg     {
   2418  1.1  mrg       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
   2419  1.1  mrg 	{
   2420  1.1  mrg 	  expand_vector_operations_1 (&gsi, dce_ssa_names);
   2421  1.1  mrg 	  /* ???  If we do not cleanup EH then we will ICE in
   2422  1.1  mrg 	     verification.  But in reality we have created wrong-code
   2423  1.1  mrg 	     as we did not properly transition EH info and edges to
   2424  1.1  mrg 	     the piecewise computations.  */
   2425  1.1  mrg 	  if (maybe_clean_eh_stmt (gsi_stmt (gsi))
   2426  1.1  mrg 	      && gimple_purge_dead_eh_edges (bb))
   2427  1.1  mrg 	    cfg_changed = true;
   2428  1.1  mrg 	}
   2429  1.1  mrg     }
   2430  1.1  mrg 
   2431  1.1  mrg   simple_dce_from_worklist (dce_ssa_names);
   2432  1.1  mrg 
   2433  1.1  mrg   return cfg_changed ? TODO_cleanup_cfg : 0;
   2434  1.1  mrg }
   2435  1.1  mrg 
   2436  1.1  mrg namespace {
   2437  1.1  mrg 
   2438  1.1  mrg const pass_data pass_data_lower_vector =
   2439  1.1  mrg {
   2440  1.1  mrg   GIMPLE_PASS, /* type */
   2441  1.1  mrg   "veclower", /* name */
   2442  1.1  mrg   OPTGROUP_VEC, /* optinfo_flags */
   2443  1.1  mrg   TV_NONE, /* tv_id */
   2444  1.1  mrg   PROP_cfg, /* properties_required */
   2445  1.1  mrg   PROP_gimple_lvec, /* properties_provided */
   2446  1.1  mrg   0, /* properties_destroyed */
   2447  1.1  mrg   0, /* todo_flags_start */
   2448  1.1  mrg   TODO_update_ssa, /* todo_flags_finish */
   2449  1.1  mrg };
   2450  1.1  mrg 
   2451  1.1  mrg class pass_lower_vector : public gimple_opt_pass
   2452  1.1  mrg {
   2453  1.1  mrg public:
   2454  1.1  mrg   pass_lower_vector (gcc::context *ctxt)
   2455  1.1  mrg     : gimple_opt_pass (pass_data_lower_vector, ctxt)
   2456  1.1  mrg   {}
   2457  1.1  mrg 
   2458  1.1  mrg   /* opt_pass methods: */
   2459  1.1  mrg   virtual bool gate (function *fun)
   2460  1.1  mrg     {
   2461  1.1  mrg       return !(fun->curr_properties & PROP_gimple_lvec);
   2462  1.1  mrg     }
   2463  1.1  mrg 
   2464  1.1  mrg   virtual unsigned int execute (function *)
   2465  1.1  mrg     {
   2466  1.1  mrg       return expand_vector_operations ();
   2467  1.1  mrg     }
   2468  1.1  mrg 
   2469  1.1  mrg }; // class pass_lower_vector
   2470  1.1  mrg 
   2471  1.1  mrg } // anon namespace
   2472  1.1  mrg 
   2473  1.1  mrg gimple_opt_pass *
   2474  1.1  mrg make_pass_lower_vector (gcc::context *ctxt)
   2475  1.1  mrg {
   2476  1.1  mrg   return new pass_lower_vector (ctxt);
   2477  1.1  mrg }
   2478  1.1  mrg 
   2479  1.1  mrg namespace {
   2480  1.1  mrg 
   2481  1.1  mrg const pass_data pass_data_lower_vector_ssa =
   2482  1.1  mrg {
   2483  1.1  mrg   GIMPLE_PASS, /* type */
   2484  1.1  mrg   "veclower2", /* name */
   2485  1.1  mrg   OPTGROUP_VEC, /* optinfo_flags */
   2486  1.1  mrg   TV_NONE, /* tv_id */
   2487  1.1  mrg   PROP_cfg, /* properties_required */
   2488  1.1  mrg   PROP_gimple_lvec, /* properties_provided */
   2489  1.1  mrg   0, /* properties_destroyed */
   2490  1.1  mrg   0, /* todo_flags_start */
   2491  1.1  mrg   ( TODO_update_ssa
   2492  1.1  mrg     | TODO_cleanup_cfg ), /* todo_flags_finish */
   2493  1.1  mrg };
   2494  1.1  mrg 
   2495  1.1  mrg class pass_lower_vector_ssa : public gimple_opt_pass
   2496  1.1  mrg {
   2497  1.1  mrg public:
   2498  1.1  mrg   pass_lower_vector_ssa (gcc::context *ctxt)
   2499  1.1  mrg     : gimple_opt_pass (pass_data_lower_vector_ssa, ctxt)
   2500  1.1  mrg   {}
   2501  1.1  mrg 
   2502  1.1  mrg   /* opt_pass methods: */
   2503  1.1  mrg   opt_pass * clone () { return new pass_lower_vector_ssa (m_ctxt); }
   2504  1.1  mrg   virtual unsigned int execute (function *)
   2505  1.1  mrg     {
   2506  1.1  mrg       return expand_vector_operations ();
   2507  1.1  mrg     }
   2508  1.1  mrg 
   2509  1.1  mrg }; // class pass_lower_vector_ssa
   2510  1.1  mrg 
   2511  1.1  mrg } // anon namespace
   2512  1.1  mrg 
   2513  1.1  mrg gimple_opt_pass *
   2514  1.1  mrg make_pass_lower_vector_ssa (gcc::context *ctxt)
   2515  1.1  mrg {
   2516  1.1  mrg   return new pass_lower_vector_ssa (ctxt);
   2517  1.1  mrg }
   2518           
   2519           #include "gt-tree-vect-generic.h"
   2520