diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-04-18 08:55:13 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-04-18 08:55:13 +0200 |
commit | 49eab32e6e79af5ef80832d058539c8d73a74ef9 (patch) | |
tree | 6feeaff5594c0c4711acd5642ea25a480536999c /gcc/tree-vect-stmts.c | |
parent | 5af0793001c54632a5160a352cfdee6195338314 (diff) | |
download | gcc-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.c | 41 |
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) |