aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-09-29 07:16:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-09-29 07:16:10 +0000
commitea60dd34cd352452eeab30aba4b84a204f2caef5 (patch)
treee30ecb562876ab20fab51104cf717d611ff43429 /gcc
parentca0e1607e9f7a185b9c0e29509b2ab84727d9041 (diff)
downloadgcc-ea60dd34cd352452eeab30aba4b84a204f2caef5.zip
gcc-ea60dd34cd352452eeab30aba4b84a204f2caef5.tar.gz
gcc-ea60dd34cd352452eeab30aba4b84a204f2caef5.tar.bz2
tree-vect-stmts.c (vectorizable_load): Avoid emitting vector constructors with vector elements.
2016-09-29 Richard Biener <rguenther@suse.de> * tree-vect-stmts.c (vectorizable_load): Avoid emitting vector constructors with vector elements. From-SVN: r240611
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/tree-vect-stmts.c41
2 files changed, 41 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eac9546..56f7255 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2016-09-29 Richard Biener <rguenther@suse.de>
+ * tree-vect-stmts.c (vectorizable_load): Avoid emitting vector
+ constructors with vector elements.
+
+2016-09-29 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/77768
* tree-ssa-sccvn.c (visit_reference_op_store): Properly deal
with stores to a place we know has a constant value.
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 47770ad..d698785 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -6862,17 +6862,40 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
int nloads = nunits;
int lnel = 1;
tree ltype = TREE_TYPE (vectype);
+ tree lvectype = vectype;
auto_vec<tree> dr_chain;
if (memory_access_type == VMAT_STRIDED_SLP)
{
- nloads = nunits / group_size;
if (group_size < nunits)
{
- lnel = group_size;
- ltype = build_vector_type (TREE_TYPE (vectype), group_size);
+ /* Avoid emitting a constructor of vector elements by performing
+ the loads using an integer type of the same size,
+ constructing a vector of those and then re-interpreting it
+ as the original vector type. This works around the fact
+ that the vec_init optab was only designed for scalar
+ element modes and thus expansion goes through memory.
+ This avoids a huge runtime penalty due to the general
+ inability to perform store forwarding from smaller stores
+ to a larger load. */
+ unsigned lsize
+ = group_size * TYPE_PRECISION (TREE_TYPE (vectype));
+ enum machine_mode elmode = mode_for_size (lsize, MODE_INT, 0);
+ enum machine_mode vmode = mode_for_vector (elmode,
+ nunits / group_size);
+ /* If we can't construct such a vector fall back to
+ element loads of the original vector type. */
+ if (VECTOR_MODE_P (vmode)
+ && optab_handler (vec_init_optab, vmode) != CODE_FOR_nothing)
+ {
+ nloads = nunits / group_size;
+ lnel = group_size;
+ ltype = build_nonstandard_integer_type (lsize, 1);
+ lvectype = build_vector_type (ltype, nloads);
+ }
}
else
{
+ nloads = 1;
lnel = nunits;
ltype = vectype;
}
@@ -6925,9 +6948,17 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
}
if (nloads > 1)
{
- tree vec_inv = build_constructor (vectype, v);
- new_temp = vect_init_vector (stmt, vec_inv, vectype, gsi);
+ tree vec_inv = build_constructor (lvectype, v);
+ new_temp = vect_init_vector (stmt, vec_inv, lvectype, gsi);
new_stmt = SSA_NAME_DEF_STMT (new_temp);
+ if (lvectype != vectype)
+ {
+ new_stmt = gimple_build_assign (make_ssa_name (vectype),
+ VIEW_CONVERT_EXPR,
+ build1 (VIEW_CONVERT_EXPR,
+ vectype, new_temp));
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ }
}
if (slp)