summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/doc/generic.texi9
-rw-r--r--gcc/doc/md.texi14
-rw-r--r--gcc/expr.c4
-rw-r--r--gcc/fold-const.c27
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/gimple-pretty-print.c2
-rw-r--r--gcc/optabs.c108
-rw-r--r--gcc/optabs.h8
-rw-r--r--gcc/tree-cfg.c2
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree-pretty-print.c16
-rw-r--r--gcc/tree-vect-data-refs.c86
-rw-r--r--gcc/tree-vect-generic.c7
-rw-r--r--gcc/tree-vect-stmts.c4
-rw-r--r--gcc/tree.def4
17 files changed, 80 insertions, 246 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 278464097e9..a5e914a3735 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index dfe5442880c..2b2e464791c 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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:
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index 4f26238322c..31e8855bf84 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -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
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 6dd6a5835a3..93183e6f895 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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
diff --git a/gcc/expr.c b/gcc/expr.c
index cb28f480dd5..c10f9157687 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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:
{
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 89c68cf582b..5d3196b7377 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
{
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 9cd77fac367..baccd452b63 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -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$))",
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index b93d66d8e3f..3ba7183a553 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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++)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 1c13b5a660f..b586eb91626 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -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
diff --git a/gcc/optabs.h b/gcc/optabs.h
index a7c43ac5e8b..cc4854dcf48 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -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);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 1fce5319d8c..6e1a60403ef 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index fb55346b1f4..c6ae65e7a42 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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:
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 9363aea1192..4b9b4536641 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -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;
}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index e6f03813a40..43f7662e658 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -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);
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 3d97ba0efd1..9dec8c63770 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -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. */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index a08b009141b..4deb16bed07 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -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
diff --git a/gcc/tree.def b/gcc/tree.def
index 2f096f9ba12..a3072491388 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -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.