summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-stmts.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-30 17:05:10 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-30 17:05:10 +0000
commitdbe41d8cd456967fb142ff1fa49dec23c694070d (patch)
tree2a5008f0e2734867398f5c1300db88d05c5e8016 /gcc/tree-vect-stmts.c
parentb2cc50a9fce6a1be302a7f4ea6a27b1f43536451 (diff)
downloadgcc-dbe41d8cd456967fb142ff1fa49dec23c694070d.tar.gz
PR tree-optimization/59591
* tree-vect-stmts.c (vectorizable_mask_load_store): Fix up handling of modifier = NARROW masked gathers. (permute_vec_elements): Use gimple_get_lhs instead of gimple_assign_lhs. * gcc.dg/vect/pr59591-1.c: New test. * gcc.dg/vect/pr59591-2.c: New test. * gcc.target/i386/pr59591-1.c: New test. * gcc.target/i386/pr59591-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206248 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r--gcc/tree-vect-stmts.c72
1 files changed, 42 insertions, 30 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index e3009d9a474..a07c14d153e 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1855,14 +1855,24 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
tree vec_oprnd0 = NULL_TREE, op;
tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gather_decl));
tree rettype, srctype, ptrtype, idxtype, masktype, scaletype;
- tree ptr, vec_mask = NULL_TREE, mask_op, var, scale;
+ tree ptr, vec_mask = NULL_TREE, mask_op = NULL_TREE, var, scale;
tree perm_mask = NULL_TREE, prev_res = NULL_TREE;
+ tree mask_perm_mask = NULL_TREE;
edge pe = loop_preheader_edge (loop);
gimple_seq seq;
basic_block new_bb;
enum { NARROW, NONE, WIDEN } modifier;
int gather_off_nunits = TYPE_VECTOR_SUBPARTS (gather_off_vectype);
+ rettype = TREE_TYPE (TREE_TYPE (gather_decl));
+ srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ scaletype = TREE_VALUE (arglist);
+ gcc_checking_assert (types_compatible_p (srctype, rettype)
+ && types_compatible_p (srctype, masktype));
+
if (nunits == gather_off_nunits)
modifier = NONE;
else if (nunits == gather_off_nunits / 2)
@@ -1888,19 +1898,14 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
perm_mask = vect_gen_perm_mask (vectype, sel);
gcc_assert (perm_mask != NULL_TREE);
ncopies *= 2;
+ for (i = 0; i < nunits; ++i)
+ sel[i] = i | gather_off_nunits;
+ mask_perm_mask = vect_gen_perm_mask (masktype, sel);
+ gcc_assert (mask_perm_mask != NULL_TREE);
}
else
gcc_unreachable ();
- rettype = TREE_TYPE (TREE_TYPE (gather_decl));
- srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- scaletype = TREE_VALUE (arglist);
- gcc_checking_assert (types_compatible_p (srctype, rettype)
- && types_compatible_p (srctype, masktype));
-
vec_dest = vect_create_destination_var (gimple_call_lhs (stmt), vectype);
ptr = fold_convert (ptrtype, gather_base);
@@ -1940,28 +1945,35 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
op = var;
}
- if (j == 0)
- vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ if (mask_perm_mask && (j & 1))
+ mask_op = permute_vec_elements (mask_op, mask_op,
+ mask_perm_mask, stmt, gsi);
else
{
- vect_is_simple_use (vec_mask, NULL, loop_vinfo, NULL, &def_stmt,
- &def, &dt);
- vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
- }
+ if (j == 0)
+ vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ else
+ {
+ vect_is_simple_use (vec_mask, NULL, loop_vinfo, NULL,
+ &def_stmt, &def, &dt);
+ vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
+ }
- mask_op = vec_mask;
- if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask)))
- {
- gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
- == TYPE_VECTOR_SUBPARTS (masktype));
- var = vect_get_new_vect_var (masktype, vect_simple_var, NULL);
- var = make_ssa_name (var, NULL);
- mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
- new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
- mask_op, NULL_TREE);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
- mask_op = var;
+ mask_op = vec_mask;
+ if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask)))
+ {
+ gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
+ == TYPE_VECTOR_SUBPARTS (masktype));
+ var = vect_get_new_vect_var (masktype, vect_simple_var,
+ NULL);
+ var = make_ssa_name (var, NULL);
+ mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
+ new_stmt
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
+ mask_op, NULL_TREE);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ mask_op = var;
+ }
}
new_stmt
@@ -5446,7 +5458,7 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt,
tree perm_dest, data_ref;
gimple perm_stmt;
- perm_dest = vect_create_destination_var (gimple_assign_lhs (stmt), vectype);
+ perm_dest = vect_create_destination_var (gimple_get_lhs (stmt), vectype);
data_ref = make_ssa_name (perm_dest, NULL);
/* Generate the permute statement. */