Rename vshuffle/vec_shuffle to vec_perm.
* doc/extend.texi (__builtin_shuffle): Improve the description to include the modulus of the selector. Mention OpenCL. * doc/md.texi (vec_perm, vec_perm_const): Document named patterns. * tree.def (VEC_PERM_EXPR): Rename from VEC_SHUFFLE_EXPR. * genopinit.c (optabs): Rename vshuffle to vec_perm. * c-typeck.c (c_build_vec_perm_expr): Rename from c_build_vec_shuffle_expr. Update for name changes. * optabs.c (expand_vec_perm_expr_p): Rename from expand_vec_shuffle_expr_p. (expand_vec_perm_expr): Rename from expand_vec_shuffle_expr. * optabs.h (OTI_vec_perm): Rename from DOI_vshuffle. (vec_perm_optab): Rename from vshuffle_optab. * expr.c, gimple-pretty-print.c, gimple.c, gimplify.c, c-tree.h, c-parser.c, tree-cfg.c, tree-inline.c, tree-pretty-print.c, tree-ssa-operands.c, tree-vect-generic.c: Update for name changes. * config/i386/i386.c (ix86_expand_vec_perm): Rename from ix86_expand_vshuffle. * config/i386/i386-protos.h: Update. * config/i386/sse.md (VEC_PERM_AVX2): Rename from VSHUFFLE_AVX2. (vec_perm<VEC_PERM_AVX2>): Rename from vshuffle<VSHUFFLE_AVX2>. From-SVN: r179701
This commit is contained in:
parent
524857ec5d
commit
2205ed2513
22 changed files with 136 additions and 88 deletions
|
@ -1,3 +1,28 @@
|
|||
2011-10-07 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* doc/extend.texi (__builtin_shuffle): Improve the description to
|
||||
include the modulus of the selector. Mention OpenCL.
|
||||
* doc/md.texi (vec_perm, vec_perm_const): Document named patterns.
|
||||
|
||||
* tree.def (VEC_PERM_EXPR): Rename from VEC_SHUFFLE_EXPR.
|
||||
* genopinit.c (optabs): Rename vshuffle to vec_perm.
|
||||
* c-typeck.c (c_build_vec_perm_expr): Rename from
|
||||
c_build_vec_shuffle_expr. Update for name changes.
|
||||
* optabs.c (expand_vec_perm_expr_p): Rename from
|
||||
expand_vec_shuffle_expr_p.
|
||||
(expand_vec_perm_expr): Rename from expand_vec_shuffle_expr.
|
||||
* optabs.h (OTI_vec_perm): Rename from DOI_vshuffle.
|
||||
(vec_perm_optab): Rename from vshuffle_optab.
|
||||
* expr.c, gimple-pretty-print.c, gimple.c, gimplify.c,
|
||||
c-tree.h, c-parser.c, tree-cfg.c, tree-inline.c, tree-pretty-print.c,
|
||||
tree-ssa-operands.c, tree-vect-generic.c: Update for name changes.
|
||||
|
||||
* config/i386/i386.c (ix86_expand_vec_perm): Rename from
|
||||
ix86_expand_vshuffle.
|
||||
* config/i386/i386-protos.h: Update.
|
||||
* config/i386/sse.md (VEC_PERM_AVX2): Rename from VSHUFFLE_AVX2.
|
||||
(vec_perm<VEC_PERM_AVX2>): Rename from vshuffle<VSHUFFLE_AVX2>.
|
||||
|
||||
2011-10-07 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/i386/predicates.md (avx2_pblendw_operand): New.
|
||||
|
|
|
@ -5990,7 +5990,7 @@ c_parser_alignof_expression (c_parser *parser)
|
|||
}
|
||||
|
||||
/* Helper function to read arguments of builtins which are interfaces
|
||||
for the middle-end nodes like COMPLEX_EXPR, VEC_SHUFFLE_EXPR and
|
||||
for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
|
||||
others. The name of the builtin is passed using BNAME parameter.
|
||||
Function returns true if there were no errors while parsing and
|
||||
stores the arguments in CEXPR_LIST. */
|
||||
|
@ -6534,13 +6534,13 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
|
||||
if (VEC_length (c_expr_t, cexpr_list) == 2)
|
||||
expr.value =
|
||||
c_build_vec_shuffle_expr
|
||||
c_build_vec_perm_expr
|
||||
(loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
|
||||
NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value);
|
||||
|
||||
else if (VEC_length (c_expr_t, cexpr_list) == 3)
|
||||
expr.value =
|
||||
c_build_vec_shuffle_expr
|
||||
c_build_vec_perm_expr
|
||||
(loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
|
||||
VEC_index (c_expr_t, cexpr_list, 1)->value,
|
||||
VEC_index (c_expr_t, cexpr_list, 2)->value);
|
||||
|
|
|
@ -595,7 +595,7 @@ extern tree c_begin_omp_task (void);
|
|||
extern tree c_finish_omp_task (location_t, tree, tree);
|
||||
extern tree c_finish_omp_clauses (tree);
|
||||
extern tree c_build_va_arg (location_t, tree, tree);
|
||||
extern tree c_build_vec_shuffle_expr (location_t, tree, tree, tree);
|
||||
extern tree c_build_vec_perm_expr (location_t, tree, tree, tree);
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement that specifies a return value is seen. */
|
||||
|
|
|
@ -2846,7 +2846,7 @@ build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params,
|
|||
return require_complete_type (result);
|
||||
}
|
||||
|
||||
/* Build a VEC_SHUFFLE_EXPR if V0, V1 and MASK are not error_mark_nodes
|
||||
/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes
|
||||
and have vector types, V0 has the same type as V1, and the number of
|
||||
elements of V0, V1, MASK is the same.
|
||||
|
||||
|
@ -2857,9 +2857,9 @@ build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params,
|
|||
an implementation accident and this semantics is not guaranteed to
|
||||
the user. */
|
||||
tree
|
||||
c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask)
|
||||
c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
|
||||
{
|
||||
tree vec_shuffle;
|
||||
tree ret;
|
||||
bool wrap = true;
|
||||
bool maybe_const = false;
|
||||
bool two_arguments = false;
|
||||
|
@ -2915,7 +2915,7 @@ c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Avoid C_MAYBE_CONST_EXPRs inside VEC_SHUFFLE_EXPR. */
|
||||
/* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */
|
||||
v0 = c_fully_fold (v0, false, &maybe_const);
|
||||
wrap &= maybe_const;
|
||||
|
||||
|
@ -2930,12 +2930,12 @@ c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask)
|
|||
mask = c_fully_fold (mask, false, &maybe_const);
|
||||
wrap &= maybe_const;
|
||||
|
||||
vec_shuffle = build3 (VEC_SHUFFLE_EXPR, TREE_TYPE (v0), v0, v1, mask);
|
||||
ret = build3 (VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
|
||||
|
||||
if (!wrap)
|
||||
vec_shuffle = c_wrap_maybe_const (vec_shuffle, true);
|
||||
ret = c_wrap_maybe_const (ret, true);
|
||||
|
||||
return vec_shuffle;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convert the argument expressions in the vector VALUES
|
||||
|
|
|
@ -123,7 +123,7 @@ extern bool ix86_expand_int_movcc (rtx[]);
|
|||
extern bool ix86_expand_fp_movcc (rtx[]);
|
||||
extern bool ix86_expand_fp_vcond (rtx[]);
|
||||
extern bool ix86_expand_int_vcond (rtx[]);
|
||||
extern void ix86_expand_vshuffle (rtx[]);
|
||||
extern void ix86_expand_vec_perm (rtx[]);
|
||||
extern void ix86_expand_sse_unpack (rtx[], bool, bool);
|
||||
extern bool ix86_expand_int_addcc (rtx[]);
|
||||
extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool);
|
||||
|
|
|
@ -19325,8 +19325,10 @@ ix86_expand_int_vcond (rtx operands[])
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Expand a variable vector permutation. */
|
||||
|
||||
void
|
||||
ix86_expand_vshuffle (rtx operands[])
|
||||
ix86_expand_vec_perm (rtx operands[])
|
||||
{
|
||||
rtx target = operands[0];
|
||||
rtx op0 = operands[1];
|
||||
|
|
|
@ -6199,19 +6199,19 @@
|
|||
;; ??? Irritatingly, the 256-bit VPSHUFB only shuffles within the 128-bit
|
||||
;; lanes. For now, we don't try to support V32QI or V16HImode. So we
|
||||
;; don't want to use VI_AVX2.
|
||||
(define_mode_iterator VSHUFFLE_AVX2
|
||||
(define_mode_iterator VEC_PERM_AVX2
|
||||
[V16QI V8HI V4SI V2DI V4SF V2DF
|
||||
(V8SI "TARGET_AVX2") (V4DI "TARGET_AVX2")
|
||||
(V8SF "TARGET_AVX2") (V4DF "TARGET_AVX2")])
|
||||
|
||||
(define_expand "vshuffle<mode>"
|
||||
[(match_operand:VSHUFFLE_AVX2 0 "register_operand" "")
|
||||
(match_operand:VSHUFFLE_AVX2 1 "register_operand" "")
|
||||
(match_operand:VSHUFFLE_AVX2 2 "register_operand" "")
|
||||
(define_expand "vec_perm<mode>"
|
||||
[(match_operand:VEC_PERM_AVX2 0 "register_operand" "")
|
||||
(match_operand:VEC_PERM_AVX2 1 "register_operand" "")
|
||||
(match_operand:VEC_PERM_AVX2 2 "register_operand" "")
|
||||
(match_operand:<sseintvecmode> 3 "register_operand" "")]
|
||||
"TARGET_SSSE3 || TARGET_AVX || TARGET_XOP"
|
||||
{
|
||||
ix86_expand_vshuffle (operands);
|
||||
ix86_expand_vec_perm (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
|
|
@ -6586,16 +6586,18 @@ c = a == b; /* The result would be @{0,-1, 0,-1@} */
|
|||
|
||||
Vector shuffling is available using functions
|
||||
@code{__builtin_shuffle (vec, mask)} and
|
||||
@code{__builtin_shuffle (vec0, vec1, mask)}. Both functions construct
|
||||
a permutation of elements from one or two vectors and return a vector
|
||||
of the same type as input vector(s). The mask is a vector of
|
||||
integer-typed elements. The size of each element of the mask must be
|
||||
the same as the size of each input vector element. The number of
|
||||
elements in input vector(s) and mask must be the same.
|
||||
@code{__builtin_shuffle (vec0, vec1, mask)}.
|
||||
Both functions construct a permutation of elements from one or two
|
||||
vectors and return a vector of the same type as the input vector(s).
|
||||
The @var{mask} is an integral vector with the same width (@var{W})
|
||||
and element count (@var{N}) as the output vector.
|
||||
|
||||
The elements of the input vectors are numbered from left to right across
|
||||
one or both of the vectors. Each element in the mask specifies a number
|
||||
of element from the input vector(s). Consider the following example.
|
||||
The elements of the input vectors are numbered in memory ordering of
|
||||
@var{vec0} beginning at 0 and @var{vec1} beginning at @var{N}. The
|
||||
elements of @var{mask} are considered modulo @var{N} in the single-operand
|
||||
case and modulo @math{2*@var{N}} in the two-operand case.
|
||||
|
||||
Consider the following example,
|
||||
|
||||
@smallexample
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
|
@ -6610,6 +6612,9 @@ res = __builtin_shuffle (a, mask1); /* res is @{1,2,2,4@} */
|
|||
res = __builtin_shuffle (a, b, mask2); /* res is @{1,5,3,6@} */
|
||||
@end smallexample
|
||||
|
||||
Note that @code{__builtin_shuffle} is intentionally semantically
|
||||
compatible with the OpenCL @code{shuffle} and @code{shuffle2} functions.
|
||||
|
||||
You can declare variables and use them in function calls and returns, as
|
||||
well as in assignments and some casts. You can specify a vector type as
|
||||
a return type for a function. Vector types can also be used as function
|
||||
|
@ -6620,20 +6625,6 @@ to and from other datatypes of the same size).
|
|||
You cannot operate between vectors of different lengths or different
|
||||
signedness without a cast.
|
||||
|
||||
A port that supports hardware vector operations, usually provides a set
|
||||
of built-in functions that can be used to operate on vectors. For
|
||||
example, a function to add two vectors and multiply the result by a
|
||||
third could look like this:
|
||||
|
||||
@smallexample
|
||||
v4si f (v4si a, v4si b, v4si c)
|
||||
@{
|
||||
v4si tmp = __builtin_addv4si (a, b);
|
||||
return __builtin_mulv4si (tmp, c);
|
||||
@}
|
||||
|
||||
@end smallexample
|
||||
|
||||
@node Offsetof
|
||||
@section Offsetof
|
||||
@findex __builtin_offsetof
|
||||
|
|
|
@ -4028,6 +4028,34 @@ will be set to the value @var{op1} & @var{msk} | @var{op2} & ~@var{msk}
|
|||
where @var{msk} is computed by element-wise evaluation of the vector
|
||||
comparison with a truth value of all-ones and a false value of all-zeros.
|
||||
|
||||
@cindex @code{vec_perm@var{m}} instruction pattern
|
||||
@item @samp{vec_perm@var{m}}
|
||||
Output a (variable) vector permutation. Operand 0 is the destination
|
||||
to receive elements from operand 1 and operand 2, which are of mode
|
||||
@var{m}. Operand 3 is the @dfn{selector}. It is an integral mode
|
||||
vector of the same width and number of elements as mode @var{m}.
|
||||
|
||||
The input elements are numbered from 0 in operand 1 through
|
||||
@math{2*@var{N}-1} in operand 2. The elements of the selector must
|
||||
be computed modulo @math{2*@var{N}}. Note that if
|
||||
@code{rtx_equal_p(operand1, operand2)}, this can be implemented
|
||||
with just operand 1 and selector elements modulo @var{N}.
|
||||
|
||||
@cindex @code{vec_perm_const@var{m}) instruction pattern
|
||||
@item @samp{vec_perm_const@var{m}}
|
||||
Like @samp{vec_perm} except that the permutation is a compile-time
|
||||
constant. That is, operand 3, the @dfn{selector}, is a @code{CONST_VECTOR}.
|
||||
|
||||
Some targets cannot perform a permutation with a variable selector,
|
||||
but can efficiently perform a constant permutation. Further, the
|
||||
target hook @code{vec_perm_ok} is queried to determine if the
|
||||
specific constant permutation is available efficiently; the named
|
||||
pattern is never expanded without @code{vec_perm_ok} returning true.
|
||||
|
||||
There is no need for a target to supply both @samp{vec_perm@var{m}}
|
||||
and @samp{vec_perm_const@var{m}} if the former can trivially implement
|
||||
the operation with, say, the vector constant loaded into a register.
|
||||
|
||||
@cindex @code{push@var{m}1} instruction pattern
|
||||
@item @samp{push@var{m}1}
|
||||
Output a push instruction. Operand 0 is value to push. Used only when
|
||||
|
|
|
@ -8605,9 +8605,10 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
|||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
mode = TYPE_MODE (TREE_TYPE (treeop0));
|
||||
goto binop;
|
||||
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
target = expand_vec_shuffle_expr (type, treeop0, treeop1, treeop2, target);
|
||||
|
||||
case VEC_PERM_EXPR:
|
||||
target = expand_vec_perm_expr (type, treeop0, treeop1, treeop2, target);
|
||||
gcc_assert (target);
|
||||
return target;
|
||||
|
||||
case DOT_PROD_EXPR:
|
||||
|
|
|
@ -253,7 +253,7 @@ static const char * const optabs[] =
|
|||
"set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))",
|
||||
"set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
|
||||
"set_optab_handler (vec_realign_load_optab, $A, CODE_FOR_$(vec_realign_load_$a$))",
|
||||
"set_direct_optab_handler (vshuffle_optab, $A, CODE_FOR_$(vshuffle$a$))",
|
||||
"set_direct_optab_handler (vec_perm_optab, $A, CODE_FOR_$(vec_perm$a$))",
|
||||
"set_convert_optab_handler (vcond_optab, $A, $B, CODE_FOR_$(vcond$a$b$))",
|
||||
"set_convert_optab_handler (vcondu_optab, $A, $B, CODE_FOR_$(vcondu$a$b$))",
|
||||
"set_optab_handler (ssum_widen_optab, $A, CODE_FOR_$(widen_ssum$I$a3$))",
|
||||
|
|
|
@ -418,8 +418,8 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
|
|||
pp_string (buffer, ">");
|
||||
break;
|
||||
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
pp_string (buffer, "VEC_SHUFFLE_EXPR <");
|
||||
case VEC_PERM_EXPR:
|
||||
pp_string (buffer, "VEC_PERM_EXPR <");
|
||||
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
|
||||
pp_string (buffer, ", ");
|
||||
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
|
||||
|
|
|
@ -2639,7 +2639,7 @@ get_gimple_rhs_num_ops (enum tree_code code)
|
|||
|| (SYM) == DOT_PROD_EXPR \
|
||||
|| (SYM) == REALIGN_LOAD_EXPR \
|
||||
|| (SYM) == VEC_COND_EXPR \
|
||||
|| (SYM) == VEC_SHUFFLE_EXPR \
|
||||
|| (SYM) == VEC_PERM_EXPR \
|
||||
|| (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS \
|
||||
: ((SYM) == CONSTRUCTOR \
|
||||
|| (SYM) == OBJ_TYPE_REF \
|
||||
|
|
|
@ -7287,7 +7287,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
}
|
||||
|
||||
case FMA_EXPR:
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
case VEC_PERM_EXPR:
|
||||
/* Classified as tcc_expression. */
|
||||
goto expr_3;
|
||||
|
||||
|
|
16
gcc/optabs.c
16
gcc/optabs.c
|
@ -6620,10 +6620,10 @@ vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
|
|||
return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
|
||||
}
|
||||
|
||||
/* Return true if VEC_SHUFFLE_EXPR can be expanded using SIMD extensions
|
||||
/* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions
|
||||
of the CPU. */
|
||||
bool
|
||||
expand_vec_shuffle_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask)
|
||||
expand_vec_perm_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask)
|
||||
{
|
||||
int v0_mode_s = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))));
|
||||
int mask_mode_s = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask))));
|
||||
|
@ -6639,19 +6639,19 @@ expand_vec_shuffle_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask)
|
|||
!= TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
|
||||
return false;
|
||||
|
||||
return direct_optab_handler (vshuffle_optab, mode) != CODE_FOR_nothing;
|
||||
return direct_optab_handler (vec_perm_optab, mode) != CODE_FOR_nothing;
|
||||
}
|
||||
|
||||
/* Generate instructions for VEC_COND_EXPR given its type and three
|
||||
operands. */
|
||||
rtx
|
||||
expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target)
|
||||
expand_vec_perm_expr (tree type, tree v0, tree v1, tree mask, rtx target)
|
||||
{
|
||||
struct expand_operand ops[4];
|
||||
enum insn_code icode;
|
||||
enum machine_mode mode = TYPE_MODE (type);
|
||||
|
||||
gcc_checking_assert (expand_vec_shuffle_expr_p (mode, v0, v1, mask));
|
||||
gcc_checking_assert (expand_vec_perm_expr_p (mode, v0, v1, mask));
|
||||
|
||||
if (TREE_CODE (mask) == VECTOR_CST)
|
||||
{
|
||||
|
@ -6659,7 +6659,7 @@ expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target)
|
|||
tree fn = targetm.vectorize.builtin_vec_perm (TREE_TYPE (v0), &m_type);
|
||||
|
||||
if (!fn)
|
||||
goto vshuffle;
|
||||
goto vec_perm;
|
||||
|
||||
if (m_type != TREE_TYPE (TREE_TYPE (mask)))
|
||||
{
|
||||
|
@ -6674,8 +6674,8 @@ expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target)
|
|||
return expand_expr_real_1 (call, target, VOIDmode, EXPAND_NORMAL, NULL);
|
||||
}
|
||||
|
||||
vshuffle:
|
||||
icode = direct_optab_handler (vshuffle_optab, mode);
|
||||
vec_perm:
|
||||
icode = direct_optab_handler (vec_perm_optab, mode);
|
||||
|
||||
if (icode == CODE_FOR_nothing)
|
||||
return 0;
|
||||
|
|
16
gcc/optabs.h
16
gcc/optabs.h
|
@ -377,6 +377,9 @@ enum optab_index
|
|||
OTI_vec_pack_sfix_trunc,
|
||||
OTI_vec_pack_ufix_trunc,
|
||||
|
||||
/* Vector shuffling. */
|
||||
OTI_vec_perm,
|
||||
|
||||
/* Perform a raise to the power of integer. */
|
||||
OTI_powi,
|
||||
|
||||
|
@ -557,6 +560,7 @@ enum optab_index
|
|||
#define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat])
|
||||
#define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc])
|
||||
#define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc])
|
||||
#define vec_perm_optab (&direct_optab_table[(int) OTI_vec_perm])
|
||||
|
||||
#define powi_optab (&optab_table[OTI_powi])
|
||||
|
||||
|
@ -617,7 +621,6 @@ enum convert_optab_index
|
|||
#define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes])
|
||||
#define vcond_optab (&convert_optab_table[(int) COI_vcond])
|
||||
#define vcondu_optab (&convert_optab_table[(int) COI_vcondu])
|
||||
#define vshuffle_optab (&direct_optab_table[(int) DOI_vshuffle])
|
||||
|
||||
/* Contains the optab used for each rtx code. */
|
||||
extern optab code_to_optab[NUM_RTX_CODE + 1];
|
||||
|
@ -639,9 +642,6 @@ enum direct_optab_index
|
|||
DOI_reload_in,
|
||||
DOI_reload_out,
|
||||
|
||||
/* Vector shuffling. */
|
||||
DOI_vshuffle,
|
||||
|
||||
/* Block move operation. */
|
||||
DOI_movmem,
|
||||
|
||||
|
@ -888,11 +888,11 @@ extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
|
|||
/* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */
|
||||
extern rtx expand_vec_shift_expr (sepops, rtx);
|
||||
|
||||
/* Return tree if target supports vector operations for VEC_SHUFFLE_EXPR. */
|
||||
bool expand_vec_shuffle_expr_p (enum machine_mode, tree, tree, tree);
|
||||
/* Return tree if target supports vector operations for VEC_PERM_EXPR. */
|
||||
bool expand_vec_perm_expr_p (enum machine_mode, tree, tree, tree);
|
||||
|
||||
/* Generate code for VEC_SHUFFLE_EXPR. */
|
||||
extern rtx expand_vec_shuffle_expr (tree, tree, tree, tree, rtx);
|
||||
/* Generate code for VEC_PERM_EXPR. */
|
||||
extern rtx expand_vec_perm_expr (tree, tree, tree, tree, rtx);
|
||||
|
||||
/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
|
||||
if the target does not have such an insn. */
|
||||
|
|
|
@ -3727,11 +3727,11 @@ verify_gimple_assign_ternary (gimple stmt)
|
|||
}
|
||||
break;
|
||||
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
case VEC_PERM_EXPR:
|
||||
if (!useless_type_conversion_p (lhs_type, rhs1_type)
|
||||
|| !useless_type_conversion_p (lhs_type, rhs2_type))
|
||||
{
|
||||
error ("type mismatch in vector shuffle expression");
|
||||
error ("type mismatch in vector permute expression");
|
||||
debug_generic_expr (lhs_type);
|
||||
debug_generic_expr (rhs1_type);
|
||||
debug_generic_expr (rhs2_type);
|
||||
|
@ -3743,7 +3743,7 @@ verify_gimple_assign_ternary (gimple stmt)
|
|||
|| TREE_CODE (rhs2_type) != VECTOR_TYPE
|
||||
|| TREE_CODE (rhs3_type) != VECTOR_TYPE)
|
||||
{
|
||||
error ("vector types expected in vector shuffle expression");
|
||||
error ("vector types expected in vector permute expression");
|
||||
debug_generic_expr (lhs_type);
|
||||
debug_generic_expr (rhs1_type);
|
||||
debug_generic_expr (rhs2_type);
|
||||
|
@ -3758,7 +3758,7 @@ verify_gimple_assign_ternary (gimple stmt)
|
|||
!= TYPE_VECTOR_SUBPARTS (lhs_type))
|
||||
{
|
||||
error ("vectors with different element number found "
|
||||
"in vector shuffle expression");
|
||||
"in vector permute expression");
|
||||
debug_generic_expr (lhs_type);
|
||||
debug_generic_expr (rhs1_type);
|
||||
debug_generic_expr (rhs2_type);
|
||||
|
@ -3770,7 +3770,7 @@ verify_gimple_assign_ternary (gimple stmt)
|
|||
|| GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs3_type)))
|
||||
!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1_type))))
|
||||
{
|
||||
error ("invalid mask type in vector shuffle expression");
|
||||
error ("invalid mask type in vector permute expression");
|
||||
debug_generic_expr (lhs_type);
|
||||
debug_generic_expr (rhs1_type);
|
||||
debug_generic_expr (rhs2_type);
|
||||
|
|
|
@ -3285,7 +3285,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
|
|||
??? We may consider mapping RTL costs to this. */
|
||||
case COND_EXPR:
|
||||
case VEC_COND_EXPR:
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
case VEC_PERM_EXPR:
|
||||
|
||||
case PLUS_EXPR:
|
||||
case POINTER_PLUS_EXPR:
|
||||
|
|
|
@ -2070,8 +2070,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
pp_string (buffer, " > ");
|
||||
break;
|
||||
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
pp_string (buffer, " VEC_SHUFFLE_EXPR < ");
|
||||
case VEC_PERM_EXPR:
|
||||
pp_string (buffer, " VEC_PERM_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);
|
||||
|
|
|
@ -943,7 +943,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
|
|||
|
||||
case COND_EXPR:
|
||||
case VEC_COND_EXPR:
|
||||
case VEC_SHUFFLE_EXPR:
|
||||
case VEC_PERM_EXPR:
|
||||
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), uflags);
|
||||
get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
|
||||
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
|
||||
|
|
|
@ -597,21 +597,21 @@ vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec)
|
|||
idx, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Check if VEC_SHUFFLE_EXPR within the given setting is supported
|
||||
/* Check if VEC_PERM_EXPR within the given setting is supported
|
||||
by hardware, or lower it piecewise.
|
||||
|
||||
When VEC_SHUFFLE_EXPR has the same first and second operands:
|
||||
VEC_SHUFFLE_EXPR <v0, v0, mask> the lowered version would be
|
||||
When VEC_PERM_EXPR has the same first and second operands:
|
||||
VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
|
||||
{v0[mask[0]], v0[mask[1]], ...}
|
||||
MASK and V0 must have the same number of elements.
|
||||
|
||||
Otherwise VEC_SHUFFLE_EXPR <v0, v1, mask> is lowered to
|
||||
Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
|
||||
{mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
|
||||
V0 and V1 must have the same type. MASK, V0, V1 must have the
|
||||
same number of arguments. */
|
||||
|
||||
static void
|
||||
lower_vec_shuffle (gimple_stmt_iterator *gsi)
|
||||
lower_vec_perm (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
tree mask = gimple_assign_rhs3 (stmt);
|
||||
|
@ -628,7 +628,7 @@ lower_vec_shuffle (gimple_stmt_iterator *gsi)
|
|||
bool two_operand_p = !operand_equal_p (vec0, vec1, 0);
|
||||
unsigned i;
|
||||
|
||||
if (expand_vec_shuffle_expr_p (TYPE_MODE (vect_type), vec0, vec1, mask))
|
||||
if (expand_vec_perm_expr_p (TYPE_MODE (vect_type), vec0, vec1, mask))
|
||||
return;
|
||||
|
||||
v = VEC_alloc (constructor_elt, gc, elements);
|
||||
|
@ -721,9 +721,9 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
|
|||
rhs_class = get_gimple_rhs_class (code);
|
||||
lhs = gimple_assign_lhs (stmt);
|
||||
|
||||
if (code == VEC_SHUFFLE_EXPR)
|
||||
if (code == VEC_PERM_EXPR)
|
||||
{
|
||||
lower_vec_shuffle (gsi);
|
||||
lower_vec_perm (gsi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
11
gcc/tree.def
11
gcc/tree.def
|
@ -497,18 +497,19 @@ DEFTREECODE (COND_EXPR, "cond_expr", tcc_expression, 3)
|
|||
*/
|
||||
DEFTREECODE (VEC_COND_EXPR, "vec_cond_expr", tcc_expression, 3)
|
||||
|
||||
/* Vector shuffle expression. A = VEC_SHUFFLE_EXPR<v0, v1, mask>
|
||||
means
|
||||
/* Vector permutation expression. A = VEC_PERM_EXPR<v0, v1, mask> means
|
||||
|
||||
foreach i in length (mask):
|
||||
A = mask[i] < length (v0) ? v0[mask[i]] : v1[mask[i] - length (mask)]
|
||||
N = length(mask)
|
||||
foreach i in N:
|
||||
M = mask[i] % (2*N)
|
||||
A = M < N ? v0[M] : v1[M-N]
|
||||
|
||||
V0 and V1 are vectors of the same type. MASK is an integer-typed
|
||||
vector. The number of MASK elements must be the same with the
|
||||
number of elements in V0 and V1. The size of the inner type
|
||||
of the MASK and of the V0 and V1 must be the same.
|
||||
*/
|
||||
DEFTREECODE (VEC_SHUFFLE_EXPR, "vec_shuffle_expr", tcc_expression, 3)
|
||||
DEFTREECODE (VEC_PERM_EXPR, "vec_perm_expr", tcc_expression, 3)
|
||||
|
||||
/* Declare local variables, including making RTL and allocating space.
|
||||
BIND_EXPR_VARS is a chain of VAR_DECL nodes for the variables.
|
||||
|
|
Loading…
Add table
Reference in a new issue