Delete VEC_EXTRACT_EVEN/ODD_EXPR.
authorRichard Henderson <rth@redhat.com>
Fri, 23 Dec 2011 22:07:16 +0000 (14:07 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 23 Dec 2011 22:07:16 +0000 (14:07 -0800)
* tree.def (VEC_EXTRACT_EVEN_EXPR, VEC_EXTRACT_ODD_EXPR): Remove.
* cfgexpand.c (expand_debug_expr): Don't handle them.
* expr.c (expand_expr_real_2): Likewise.
* fold-const.c (fold_binary_loc): Likewise.
* gimple-pretty-print.c (dump_binary_rhs): Likewise.
* tree-cfg.c (verify_gimple_assign_binary): Likewise.
* tree-inline.c (estimate_operator_cost): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-vect-generic.c (expand_vector_operations_1): Likewise.
* optabs.c (optab_for_tree_code): Likewise.
(can_vec_perm_for_code_p): Remove.
(expand_binop): Don't try it.
(init_optabs): Don't init vec_extract_even/odd_optab.
* genopinit.c (optabs): Likewise.
* optabs.h (OTI_vec_extract_even, OTI_vec_extract_odd): Remove.
(vec_extract_even_optab, vec_extract_odd_optab): Remove.
* tree-vect-data-refs.c (vect_strided_store_supported): Tidy code.
(vect_permute_store_chain): Use TYPE_VECTOR_SUBPARTS instead of
GET_MODE_NUNITS; check vect_gen_perm_mask return value instead of
asserting vect_strided_store_supported.
(vect_strided_load_supported): Use can_vec_perm_p.
(vect_permute_load_chain): Use VEC_PERM_EXPR.

* doc/generic.texi (VEC_EXTRACT_EVEN_EXPR): Remove.
(VEC_EXTRACT_ODD_EXPR): Remove.
* doc/md.texi (vec_extract_even, vec_extract_odd): Remove.

From-SVN: r182669

17 files changed:
gcc/ChangeLog
gcc/cfgexpand.c
gcc/doc/generic.texi
gcc/doc/md.texi
gcc/expr.c
gcc/fold-const.c
gcc/genopinit.c
gcc/gimple-pretty-print.c
gcc/optabs.c
gcc/optabs.h
gcc/tree-cfg.c
gcc/tree-inline.c
gcc/tree-pretty-print.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-generic.c
gcc/tree-vect-stmts.c
gcc/tree.def

index 278464097e91c8e4d2182a6e4ec201b57398acb3..a5e914a3735dcc172f12ef91ecbf13bde59f235d 100644 (file)
@@ -1,3 +1,32 @@
+2011-12-23  Richard Henderson  <rth@redhat.com>
+
+       * tree.def (VEC_EXTRACT_EVEN_EXPR, VEC_EXTRACT_ODD_EXPR): Remove.
+       * cfgexpand.c (expand_debug_expr): Don't handle them.
+       * expr.c (expand_expr_real_2): Likewise.
+       * fold-const.c (fold_binary_loc): Likewise.
+       * gimple-pretty-print.c (dump_binary_rhs): Likewise.
+       * tree-cfg.c (verify_gimple_assign_binary): Likewise.
+       * tree-inline.c (estimate_operator_cost): Likewise.
+       * tree-pretty-print.c (dump_generic_node): Likewise.
+       * tree-vect-generic.c (expand_vector_operations_1): Likewise.
+       * optabs.c (optab_for_tree_code): Likewise.
+       (can_vec_perm_for_code_p): Remove.
+       (expand_binop): Don't try it.
+       (init_optabs): Don't init vec_extract_even/odd_optab.
+       * genopinit.c (optabs): Likewise.
+       * optabs.h (OTI_vec_extract_even, OTI_vec_extract_odd): Remove.
+       (vec_extract_even_optab, vec_extract_odd_optab): Remove.
+       * tree-vect-data-refs.c (vect_strided_store_supported): Tidy code.
+       (vect_permute_store_chain): Use TYPE_VECTOR_SUBPARTS instead of
+       GET_MODE_NUNITS; check vect_gen_perm_mask return value instead of
+       asserting vect_strided_store_supported.
+       (vect_strided_load_supported): Use can_vec_perm_p.
+       (vect_permute_load_chain): Use VEC_PERM_EXPR.
+
+       * doc/generic.texi (VEC_EXTRACT_EVEN_EXPR): Remove.
+       (VEC_EXTRACT_ODD_EXPR): Remove.
+       * doc/md.texi (vec_extract_even, vec_extract_odd): Remove.
+
 2011-12-23  Anatoly Sokolov  <aesok@post.ru>
 
        * config/score/score.h (REGISTER_MOVE_COST, MEMORY_MOVE_COST): Remove.
index dfe5442880ce40e7333573020c115dd79d0579e2..2b2e464791cf2abf1afd71f1867e5209ed659858 100644 (file)
@@ -3449,8 +3449,6 @@ expand_debug_expr (tree exp)
     case REDUC_MIN_EXPR:
     case REDUC_PLUS_EXPR:
     case VEC_COND_EXPR:
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
     case VEC_LSHIFT_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
     case VEC_PACK_SAT_EXPR:
index 4f26238322cd118d11837ab491bc55d89178782a..31e8855bf846cc10297db1c326172e4072db2950 100644 (file)
@@ -1695,8 +1695,6 @@ its sole argument yields the representation for @code{ap}.
 @tindex VEC_PACK_TRUNC_EXPR
 @tindex VEC_PACK_SAT_EXPR
 @tindex VEC_PACK_FIX_TRUNC_EXPR
-@tindex VEC_EXTRACT_EVEN_EXPR
-@tindex VEC_EXTRACT_ODD_EXPR
 
 @table @code
 @item VEC_LSHIFT_EXPR
@@ -1765,13 +1763,6 @@ of elements of a floating point type.  The result is a vector that contains
 twice as many elements of an integral type whose size is half as wide.  The
 elements of the two vectors are merged (concatenated) to form the output
 vector.
-
-@item VEC_EXTRACT_EVEN_EXPR
-@itemx VEC_EXTRACT_ODD_EXPR
-These nodes represent extracting of the even/odd elements of the two input
-vectors, respectively. Their operands and result are vectors that contain the
-same number of elements of the same type.
-
 @end table
 
 
index 6dd6a5835a379e7f35b82c4a8041048577ee0dec..93183e6f8957e615e70948fa96270697ce725570 100644 (file)
@@ -4145,20 +4145,6 @@ operand 1 is new value of field and operand 2 specify the field index.
 Extract given field from the vector value.  Operand 1 is the vector, operand 2
 specify field index and operand 0 place to store value into.
 
-@cindex @code{vec_extract_even@var{m}} instruction pattern
-@item @samp{vec_extract_even@var{m}}
-Extract even elements from the input vectors (operand 1 and operand 2).
-The even elements of operand 2 are concatenated to the even elements of operand
-1 in their original order. The result is stored in operand 0.
-The output and input vectors should have the same modes.
-
-@cindex @code{vec_extract_odd@var{m}} instruction pattern
-@item @samp{vec_extract_odd@var{m}}
-Extract odd elements from the input vectors (operand 1 and operand 2).
-The odd elements of operand 2 are concatenated to the odd elements of operand
-1 in their original order. The result is stored in operand 0.
-The output and input vectors should have the same modes.
-
 @cindex @code{vec_init@var{m}} instruction pattern
 @item @samp{vec_init@var{m}}
 Initialize the vector to given values.  Operand 0 is the vector to initialize
index cb28f480dd598463d87b5ebf799263ce6e4f9f14..c10f91576878144a70860fee0a20958349d3ef8d 100644 (file)
@@ -8647,10 +8647,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
         return temp;
       }
 
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
-      goto binop;
-
     case VEC_LSHIFT_EXPR:
     case VEC_RSHIFT_EXPR:
       {
index 89c68cf582b0027121b959d0726e9dd6c8250bdb..5d3196b73775f102b4229cdaf18e1aedf0b3c408 100644 (file)
@@ -13501,33 +13501,6 @@ fold_binary_loc (location_t loc,
       /* An ASSERT_EXPR should never be passed to fold_binary.  */
       gcc_unreachable ();
 
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
-      if ((TREE_CODE (arg0) == VECTOR_CST
-          || TREE_CODE (arg0) == CONSTRUCTOR)
-         && (TREE_CODE (arg1) == VECTOR_CST
-             || TREE_CODE (arg1) == CONSTRUCTOR))
-       {
-         unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
-         unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
-
-         for (i = 0; i < nelts; i++)
-           switch (code)
-             {
-             case VEC_EXTRACT_EVEN_EXPR:
-               sel[i] = i * 2;
-               break;
-             case VEC_EXTRACT_ODD_EXPR:
-               sel[i] = i * 2 + 1;
-               break;
-             default:
-               gcc_unreachable ();
-             }
-
-         return fold_vec_perm (type, arg0, arg1, sel);
-       }
-      return NULL_TREE;
-
     case VEC_PACK_TRUNC_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
       {
index 9cd77fac367e47f4b24f5dfd3db8e3460340ff1d..baccd452b63884ff1b388212bf3bd647ef52a5f2 100644 (file)
@@ -267,8 +267,6 @@ static const char * const optabs[] =
   "set_direct_optab_handler (atomic_or_optab, $A, CODE_FOR_$(atomic_or$I$a$))",
   "set_optab_handler (vec_set_optab, $A, CODE_FOR_$(vec_set$a$))",
   "set_optab_handler (vec_extract_optab, $A, CODE_FOR_$(vec_extract$a$))",
-  "set_optab_handler (vec_extract_even_optab, $A, CODE_FOR_$(vec_extract_even$a$))",
-  "set_optab_handler (vec_extract_odd_optab, $A, CODE_FOR_$(vec_extract_odd$a$))",
   "set_optab_handler (vec_init_optab, $A, CODE_FOR_$(vec_init$a$))",
   "set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))",
   "set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
index b93d66d8e3fb8366d926af04fd7c9a89caf01a83..3ba7183a553fb12f16433fed9ad8558b4d41b7c7 100644 (file)
@@ -345,8 +345,6 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
     case VEC_PACK_TRUNC_EXPR:
     case VEC_PACK_SAT_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
     case VEC_WIDEN_LSHIFT_HI_EXPR:
     case VEC_WIDEN_LSHIFT_LO_EXPR:
       for (p = tree_code_name [(int) code]; *p; p++)
index 1c13b5a660fd9ca56d378b756c4f27f6d0b4e0d2..b586eb91626da0e0ec8dbcfd5e60df7147b93f48 100644 (file)
@@ -547,12 +547,6 @@ optab_for_tree_code (enum tree_code code, const_tree type,
     case ABS_EXPR:
       return trapv ? absv_optab : abs_optab;
 
-    case VEC_EXTRACT_EVEN_EXPR:
-      return vec_extract_even_optab;
-
-    case VEC_EXTRACT_ODD_EXPR:
-      return vec_extract_odd_optab;
-
     default:
       return NULL;
     }
@@ -1600,26 +1594,6 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
        }
     }
 
-  /* Certain vector operations can be implemented with vector permutation.  */
-  if (VECTOR_MODE_P (mode))
-    {
-      enum tree_code tcode = ERROR_MARK;
-      rtx sel;
-
-      if (binoptab == vec_extract_even_optab)
-       tcode = VEC_EXTRACT_EVEN_EXPR;
-      else if (binoptab == vec_extract_odd_optab)
-       tcode = VEC_EXTRACT_ODD_EXPR;
-
-      if (tcode != ERROR_MARK
-         && can_vec_perm_for_code_p (tcode, mode, &sel))
-       {
-         temp = expand_vec_perm (mode, op0, op1, sel, target);
-         gcc_assert (temp != NULL);
-         return temp;
-       }
-    }
-
   /* Look for a wider mode of the same class for which we think we
      can open-code the operation.  Check for a widening multiply at the
      wider mode as well.  */
@@ -6259,8 +6233,6 @@ init_optabs (void)
   init_optab (udot_prod_optab, UNKNOWN);
 
   init_optab (vec_extract_optab, UNKNOWN);
-  init_optab (vec_extract_even_optab, UNKNOWN);
-  init_optab (vec_extract_odd_optab, UNKNOWN);
   init_optab (vec_set_optab, UNKNOWN);
   init_optab (vec_init_optab, UNKNOWN);
   init_optab (vec_shl_optab, UNKNOWN);
@@ -6868,86 +6840,6 @@ can_vec_perm_p (enum machine_mode mode, bool variable,
   return true;
 }
 
-/* Return true if we can implement with VEC_PERM_EXPR for this target.
-   If PSEL is non-null, return the selector for the permutation.  */
-
-bool
-can_vec_perm_for_code_p (enum tree_code code, enum machine_mode mode,
-                        rtx *psel)
-{
-  bool need_sel_test = false;
-  enum insn_code icode;
-
-  /* If the target doesn't implement a vector mode for the vector type,
-     then no operations are supported.  */
-  if (!VECTOR_MODE_P (mode))
-    return false;
-
-  /* Do as many tests as possible without reqiring the selector.  */
-  icode = direct_optab_handler (vec_perm_optab, mode);
-  if (icode == CODE_FOR_nothing && GET_MODE_INNER (mode) != QImode)
-    {
-      enum machine_mode qimode
-       = mode_for_vector (QImode, GET_MODE_SIZE (mode));
-      if (VECTOR_MODE_P (qimode))
-       icode = direct_optab_handler (vec_perm_optab, qimode);
-    }
-  if (icode == CODE_FOR_nothing)
-    {
-      icode = direct_optab_handler (vec_perm_const_optab, mode);
-      if (icode != CODE_FOR_nothing
-         && targetm.vectorize.vec_perm_const_ok != NULL)
-       need_sel_test = true;
-    }
-  if (icode == CODE_FOR_nothing)
-    return false;
-
-  /* If the selector is required, or if we need to test it, build it.  */
-  if (psel || need_sel_test)
-    {
-      int i, nelt = GET_MODE_NUNITS (mode), alt = 0;
-      unsigned char *data = XALLOCAVEC (unsigned char, nelt);
-
-      switch (code)
-       {
-       case VEC_EXTRACT_ODD_EXPR:
-         alt = 1;
-         /* FALLTHRU */
-       case VEC_EXTRACT_EVEN_EXPR:
-         for (i = 0; i < nelt; ++i)
-           data[i] = i * 2 + alt;
-         break;
-
-       default:
-         gcc_unreachable ();
-       }
-
-      if (need_sel_test
-         && !targetm.vectorize.vec_perm_const_ok (mode, data))
-       return false;
-
-      if (psel)
-       {
-         rtvec vec = rtvec_alloc (nelt);
-         enum machine_mode imode = mode;
-
-         for (i = 0; i < nelt; ++i)
-           RTVEC_ELT (vec, i) = GEN_INT (data[i]);
-
-         if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
-           {
-             imode = int_mode_for_mode (GET_MODE_INNER (mode));
-             imode = mode_for_vector (imode, nelt);
-             gcc_assert (GET_MODE_CLASS (imode) == MODE_VECTOR_INT);
-           }
-
-         *psel = gen_rtx_CONST_VECTOR (imode, vec);
-       }
-    }
-
-  return true;
-}
-
 /* A subroutine of expand_vec_perm for expanding one vec_perm insn.  */
 
 static rtx
index a7c43ac5e8b68de11aa9d8063c5cddd1e0aff6ab..cc4854dcf48bf3f7a88f4be6a65df2b6019cfc20 100644 (file)
@@ -332,9 +332,6 @@ enum optab_index
   OTI_vec_set,
   /* Extract specified field of vector operand.  */
   OTI_vec_extract,
-  /* Extract even/odd fields of vector operands.  */
-  OTI_vec_extract_even,
-  OTI_vec_extract_odd,
   /* Initialize vector operand.  */
   OTI_vec_init,
   /* Whole vector shift. The shift amount is in bits.  */
@@ -559,8 +556,6 @@ enum optab_index
 
 #define vec_set_optab (&optab_table[OTI_vec_set])
 #define vec_extract_optab (&optab_table[OTI_vec_extract])
-#define vec_extract_even_optab (&optab_table[OTI_vec_extract_even])
-#define vec_extract_odd_optab (&optab_table[OTI_vec_extract_odd])
 #define vec_init_optab (&optab_table[OTI_vec_init])
 #define vec_shl_optab (&optab_table[OTI_vec_shl])
 #define vec_shr_optab (&optab_table[OTI_vec_shr])
@@ -1003,9 +998,6 @@ extern rtx expand_vec_shift_expr (sepops, rtx);
 /* Return tree if target supports vector operations for VEC_PERM_EXPR.  */
 extern bool can_vec_perm_p (enum machine_mode, bool, const unsigned char *);
 
-/* Return true if target supports vector operations using VEC_PERM_EXPR.  */
-extern bool can_vec_perm_for_code_p (enum tree_code, enum machine_mode, rtx *);
-
 /* Generate code for VEC_PERM_EXPR.  */
 extern rtx expand_vec_perm (enum machine_mode, rtx, rtx, rtx, rtx);
 
index 1fce5319d8cce2f77d7edc47d5a27c03686c188c..6e1a60403ef9361dcc8e6c6f5791d9e59ee299d7 100644 (file)
@@ -3711,8 +3711,6 @@ do_pointer_plus_expr_check:
     case VEC_PACK_TRUNC_EXPR:
     case VEC_PACK_SAT_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
       /* FIXME.  */
       return false;
 
index fb55346b1f45215200e1277ffe0ef40e240b2d73..c6ae65e7a42b51dec593c3531a83a7ee323f5825 100644 (file)
@@ -3399,8 +3399,6 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
     case VEC_PACK_TRUNC_EXPR:
     case VEC_PACK_SAT_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
-    case VEC_EXTRACT_EVEN_EXPR:
-    case VEC_EXTRACT_ODD_EXPR:
     case VEC_WIDEN_LSHIFT_HI_EXPR:
     case VEC_WIDEN_LSHIFT_LO_EXPR:
 
index 9363aea1192cb6be731840f2a9905cb4d9b3a34b..4b9b4536641469a999a26fba7201421c4a372989 100644 (file)
@@ -2388,22 +2388,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_block_node (buffer, node, spc, flags);
       break;
 
-    case VEC_EXTRACT_EVEN_EXPR:
-      pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-
-    case VEC_EXTRACT_ODD_EXPR:
-      pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-
     default:
       NIY;
     }
index e6f03813a402528a5de5553f916df3809a3f98b4..43f7662e658e24936c9eee39644118e09e7d18cc 100644 (file)
@@ -3794,15 +3794,13 @@ vect_create_destination_var (tree scalar_dest, tree vectype)
 
 /* Function vect_strided_store_supported.
 
-   Returns TRUE is INTERLEAVE_HIGH and INTERLEAVE_LOW operations are supported,
-   and FALSE otherwise.  */
+   Returns TRUE if interleave high and interleave low permutations
+   are supported, and FALSE otherwise.  */
 
 bool
 vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
 {
-  enum machine_mode mode;
-
-  mode = TYPE_MODE (vectype);
+  enum machine_mode mode = TYPE_MODE (vectype);
 
   /* vect_permute_store_chain requires the group size to be a power of two.  */
   if (exact_log2 (count) == -1)
@@ -3813,7 +3811,7 @@ vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
       return false;
     }
 
-  /* Check that the operation is supported.  */
+  /* Check that the permutation is supported.  */
   if (VECTOR_MODE_P (mode))
     {
       unsigned int i, nelt = GET_MODE_NUNITS (mode);
@@ -3923,11 +3921,9 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
   tree perm_mask_low, perm_mask_high;
   unsigned int i, n;
-  unsigned int j, nelt = GET_MODE_NUNITS (TYPE_MODE (vectype));
+  unsigned int j, nelt = TYPE_VECTOR_SUBPARTS (vectype);
   unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
 
-  gcc_assert (vect_strided_store_supported (vectype, length));
-
   *result_chain = VEC_copy (tree, heap, dr_chain);
 
   for (i = 0, n = nelt / 2; i < n; i++)
@@ -3936,9 +3932,12 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
       sel[i * 2 + 1] = i + nelt;
     }
   perm_mask_high = vect_gen_perm_mask (vectype, sel);
+  gcc_assert (perm_mask_high != NULL);
+
   for (i = 0; i < nelt; i++)
     sel[i] += nelt / 2;
   perm_mask_low = vect_gen_perm_mask (vectype, sel);
+  gcc_assert (perm_mask_low != NULL);
 
   for (i = 0, n = exact_log2 (length); i < n; i++)
     {
@@ -4246,16 +4245,13 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
 
 /* Function vect_strided_load_supported.
 
-   Returns TRUE is EXTRACT_EVEN and EXTRACT_ODD operations are supported,
+   Returns TRUE if even and odd permutations are supported,
    and FALSE otherwise.  */
 
 bool
 vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
 {
-  optab ee_optab, eo_optab;
-  enum machine_mode mode;
-
-  mode = TYPE_MODE (vectype);
+  enum machine_mode mode = TYPE_MODE (vectype);
 
   /* vect_permute_load_chain requires the group size to be a power of two.  */
   if (exact_log2 (count) == -1)
@@ -4266,18 +4262,22 @@ vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
       return false;
     }
 
-  ee_optab = optab_for_tree_code (VEC_EXTRACT_EVEN_EXPR,
-                                 vectype, optab_default);
-  eo_optab = optab_for_tree_code (VEC_EXTRACT_ODD_EXPR,
-                                 vectype, optab_default);
-  if (ee_optab && eo_optab
-      && optab_handler (ee_optab, mode) != CODE_FOR_nothing
-      && optab_handler (eo_optab, mode) != CODE_FOR_nothing)
-    return true;
+  /* Check that the permutation is supported.  */
+  if (VECTOR_MODE_P (mode))
+    {
+      unsigned int i, nelt = GET_MODE_NUNITS (mode);
+      unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
 
-  if (can_vec_perm_for_code_p (VEC_EXTRACT_EVEN_EXPR, mode, NULL)
-      && can_vec_perm_for_code_p (VEC_EXTRACT_ODD_EXPR, mode, NULL))
-    return true;
+      for (i = 0; i < nelt; i++)
+       sel[i] = i * 2;
+      if (can_vec_perm_p (mode, false, sel))
+       {
+         for (i = 0; i < nelt; i++)
+           sel[i] = i * 2 + 1;
+         if (can_vec_perm_p (mode, false, sel))
+           return true;
+       }
+    }
 
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "extract even/odd not supported by target");
@@ -4379,17 +4379,28 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
                         VEC(tree,heap) **result_chain)
 {
   tree perm_dest, data_ref, first_vect, second_vect;
+  tree perm_mask_even, perm_mask_odd;
   gimple perm_stmt;
   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
-  int i;
-  unsigned int j;
-
-  gcc_assert (vect_strided_load_supported (vectype, length));
+  unsigned int i, j, log_length = exact_log2 (length);
+  unsigned nelt = TYPE_VECTOR_SUBPARTS (vectype);
+  unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
 
   *result_chain = VEC_copy (tree, heap, dr_chain);
-  for (i = 0; i < exact_log2 (length); i++)
+
+  for (i = 0; i < nelt; ++i)
+    sel[i] = i * 2;
+  perm_mask_even = vect_gen_perm_mask (vectype, sel);
+  gcc_assert (perm_mask_even != NULL);
+
+  for (i = 0; i < nelt; ++i)
+    sel[i] = i * 2 + 1;
+  perm_mask_odd = vect_gen_perm_mask (vectype, sel);
+  gcc_assert (perm_mask_odd != NULL);
+
+  for (i = 0; i < log_length; i++)
     {
-      for (j = 0; j < length; j +=2)
+      for (j = 0; j < length; j += 2)
        {
          first_vect = VEC_index (tree, dr_chain, j);
          second_vect = VEC_index (tree, dr_chain, j+1);
@@ -4399,9 +4410,9 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
          DECL_GIMPLE_REG_P (perm_dest) = 1;
          add_referenced_var (perm_dest);
 
-         perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_EVEN_EXPR,
-                                                   perm_dest, first_vect,
-                                                   second_vect);
+         perm_stmt = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, perm_dest,
+                                                    first_vect, second_vect,
+                                                    perm_mask_even);
 
          data_ref = make_ssa_name (perm_dest, perm_stmt);
          gimple_assign_set_lhs (perm_stmt, data_ref);
@@ -4415,9 +4426,10 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
          DECL_GIMPLE_REG_P (perm_dest) = 1;
          add_referenced_var (perm_dest);
 
-         perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_ODD_EXPR,
-                                                   perm_dest, first_vect,
-                                                   second_vect);
+         perm_stmt = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, perm_dest,
+                                                    first_vect, second_vect,
+                                                    perm_mask_odd);
+
          data_ref = make_ssa_name (perm_dest, perm_stmt);
          gimple_assign_set_lhs (perm_stmt, data_ref);
          vect_finish_stmt_generation (stmt, perm_stmt, gsi);
index 3d97ba0efd17cfc3e462d965cfcb2b4af4b8b3fb..9dec8c63770265602c7e0f02d7db5d7fa06f68b3 100644 (file)
@@ -773,13 +773,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
       || code == VIEW_CONVERT_EXPR)
     return;
 
-  /* These are only created by the vectorizer, after having queried
-     the target support.  It's more than just looking at the optab,
-     and there's no need to do it again.  */
-  if (code == VEC_EXTRACT_EVEN_EXPR
-      || code == VEC_EXTRACT_ODD_EXPR)
-    return;
-
   gcc_assert (code != CONVERT_EXPR);
 
   /* The signedness is determined from input argument.  */
index a08b009141b7b96f194a3a0217bda72d27a9157c..4deb16bed0744f274b9c89d6aeefc12f108178a6 100644 (file)
@@ -4542,8 +4542,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
 
      Then permutation statements are generated:
 
-     VS5: vx5 = VEC_EXTRACT_EVEN_EXPR < vx0, vx1 >
-     VS6: vx6 = VEC_EXTRACT_ODD_EXPR < vx0, vx1 >
+     VS5: vx5 = VEC_PERM_EXPR < vx0, vx1, { 0, 2, ..., i*2 } >
+     VS6: vx6 = VEC_PERM_EXPR < vx0, vx1, { 1, 3, ..., i*2+1 } >
        ...
 
      And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
index 2f096f9ba12bb2f0ed9a9ca9c24f6442a8be18be..a30724913880a2c638a531778d154a8a824cf5b4 100644 (file)
@@ -1188,10 +1188,6 @@ DEFTREECODE (VEC_PACK_SAT_EXPR, "vec_pack_sat_expr", tcc_binary, 2)
    the output vector.  */
 DEFTREECODE (VEC_PACK_FIX_TRUNC_EXPR, "vec_pack_fix_trunc_expr", tcc_binary, 2)
 
-/* Extract even/odd fields from vectors.  */
-DEFTREECODE (VEC_EXTRACT_EVEN_EXPR, "vec_extract_even_expr", tcc_binary, 2)
-DEFTREECODE (VEC_EXTRACT_ODD_EXPR, "vec_extract_odd_expr", tcc_binary, 2)
-
 /* Widening vector shift left in bits.
    Operand 0 is a vector to be shifted with N elements of size S.
    Operand 1 is an integer shift amount in bits.