LCOV - code coverage report
Current view: top level - gcc - tree-vect-generic.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1011 1188 85.1 %
Date: 2020-03-28 11:57:23 Functions: 35 37 94.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.