summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-stmts.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-31 16:52:19 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-31 16:52:19 +0000
commitf381ff7c6e8c029e43335f024db6ecd9f1b0d50b (patch)
tree021f641e722e04eb77cf47f6a52a9de1f42432ef /gcc/tree-vect-stmts.c
parent68f57f43da4451a9e2d4a281a8cf93292087df7d (diff)
downloadgcc-f381ff7c6e8c029e43335f024db6ecd9f1b0d50b.tar.gz
* tree-vect-stmts.c (vectorizable_shift): If op1 is vect_external_def
in a loop and has different type from op0, cast it to op0's type before the loop first. For slp give up. Don't crash if op1_vectype is NULL. * gcc.dg/vshift-3.c: New test. * gcc.dg/vshift-4.c: New test. * gcc.dg/vshift-5.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180704 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r--gcc/tree-vect-stmts.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 08abd23c0a1..c6df30e9310 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2453,7 +2453,10 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
optab = optab_for_tree_code (code, vectype, optab_vector);
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vector/vector shift/rotate found.");
- if (TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
+ if (!op1_vectype)
+ op1_vectype = get_same_sized_vectype (TREE_TYPE (op1), vectype_out);
+ if (op1_vectype == NULL_TREE
+ || TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unusable type for last operand in"
@@ -2487,9 +2490,28 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
/* Unlike the other binary operators, shifts/rotates have
the rhs being int, instead of the same type as the lhs,
so make sure the scalar is the right type if we are
- dealing with vectors of short/char. */
+ dealing with vectors of long long/long/short/char. */
if (dt[1] == vect_constant_def)
op1 = fold_convert (TREE_TYPE (vectype), op1);
+ else if (!useless_type_conversion_p (TREE_TYPE (vectype),
+ TREE_TYPE (op1)))
+ {
+ if (slp_node
+ && TYPE_MODE (TREE_TYPE (vectype))
+ != TYPE_MODE (TREE_TYPE (op1)))
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "unusable type for last operand in"
+ " vector/vector shift/rotate.");
+ return false;
+ }
+ if (vec_stmt && !slp_node)
+ {
+ op1 = fold_convert (TREE_TYPE (vectype), op1);
+ op1 = vect_init_vector (stmt, op1,
+ TREE_TYPE (vectype), NULL);
+ }
+ }
}
}
}