diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-31 16:52:19 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-31 16:52:19 +0000 |
commit | f381ff7c6e8c029e43335f024db6ecd9f1b0d50b (patch) | |
tree | 021f641e722e04eb77cf47f6a52a9de1f42432ef /gcc/tree-vect-stmts.c | |
parent | 68f57f43da4451a9e2d4a281a8cf93292087df7d (diff) | |
download | gcc-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.c | 26 |
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); + } + } } } } |