aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-stmts.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-04-18 08:55:13 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-04-18 08:55:13 +0200
commit49eab32e6e79af5ef80832d058539c8d73a74ef9 (patch)
tree6feeaff5594c0c4711acd5642ea25a480536999c /gcc/tree-vect-stmts.c
parent5af0793001c54632a5160a352cfdee6195338314 (diff)
downloadgcc-49eab32e6e79af5ef80832d058539c8d73a74ef9.zip
gcc-49eab32e6e79af5ef80832d058539c8d73a74ef9.tar.gz
gcc-49eab32e6e79af5ef80832d058539c8d73a74ef9.tar.bz2
re PR tree-optimization/48616 (-ftree-vectorize -mxop miscompiles right shift)
PR tree-optimization/48616 * tree-vect-stmts.c (vectorizable_shift): If SLP, determine whether the shift is by scalar or vector based on whether all SLP scalar stmts have the same rhs. * gcc.dg/pr48616.c: New test. From-SVN: r172638
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r--gcc/tree-vect-stmts.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 20ca7a4..0c7ab5a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2077,7 +2077,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
tree vop0, vop1;
unsigned int k;
- bool scalar_shift_arg = false;
+ bool scalar_shift_arg = true;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
int vf;
@@ -2159,8 +2159,34 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
/* Determine whether the shift amount is a vector, or scalar. If the
shift/rotate amount is a vector, use the vector/vector shift optabs. */
+ if (dt[1] == vect_internal_def && !slp_node)
+ scalar_shift_arg = false;
+ else if (dt[1] == vect_constant_def
+ || dt[1] == vect_external_def
+ || dt[1] == vect_internal_def)
+ {
+ /* In SLP, need to check whether the shift count is the same,
+ in loops if it is a constant or invariant, it is always
+ a scalar shift. */
+ if (slp_node)
+ {
+ VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node);
+ gimple slpstmt;
+
+ FOR_EACH_VEC_ELT (gimple, stmts, k, slpstmt)
+ if (!operand_equal_p (gimple_assign_rhs2 (slpstmt), op1, 0))
+ scalar_shift_arg = false;
+ }
+ }
+ else
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "operand mode requires invariant argument.");
+ return false;
+ }
+
/* Vector shifted by vector. */
- if (dt[1] == vect_internal_def)
+ if (!scalar_shift_arg)
{
optab = optab_for_tree_code (code, vectype, optab_vector);
if (vect_print_dump_info (REPORT_DETAILS))
@@ -2168,13 +2194,12 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
}
/* See if the machine has a vector shifted by scalar insn and if not
then see if it has a vector shifted by vector insn. */
- else if (dt[1] == vect_constant_def || dt[1] == vect_external_def)
+ else
{
optab = optab_for_tree_code (code, vectype, optab_scalar);
if (optab
&& optab_handler (optab, TYPE_MODE (vectype)) != CODE_FOR_nothing)
{
- scalar_shift_arg = true;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vector/scalar shift/rotate found.");
}
@@ -2185,6 +2210,8 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
&& (optab_handler (optab, TYPE_MODE (vectype))
!= CODE_FOR_nothing))
{
+ scalar_shift_arg = false;
+
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vector/vector shift/rotate found.");
@@ -2197,12 +2224,6 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
}
}
}
- else
- {
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "operand mode requires invariant argument.");
- return false;
- }
/* Supportable by target? */
if (!optab)