diff options
Diffstat (limited to 'gcc/tree-vect-transform.c')
-rw-r--r-- | gcc/tree-vect-transform.c | 97 |
1 files changed, 62 insertions, 35 deletions
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index cc48981..82a4c84 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -502,7 +502,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code, int element_bitsize = tree_low_cst (bitsize, 1); int nelements = vec_size_in_bits / element_bitsize; - optab = optab_for_tree_code (code, vectype); + optab = optab_for_tree_code (code, vectype, optab_default); /* We have a whole vector shift available. */ if (VECTOR_MODE_P (mode) @@ -2458,7 +2458,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt, have_whole_vector_shift = false; else { - optab optab = optab_for_tree_code (code, vectype); + optab optab = optab_for_tree_code (code, vectype, optab_default); if (optab_handler (optab, mode)->insn_code == CODE_FOR_nothing) have_whole_vector_shift = false; } @@ -2818,7 +2818,7 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt) /* 4. Supportable by target? */ /* 4.1. check support for the operation in the loop */ - optab = optab_for_tree_code (code, vectype); + optab = optab_for_tree_code (code, vectype, optab_default); if (!optab) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -2909,7 +2909,7 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt) if (!reduction_code_for_scalar_code (orig_code, &epilog_reduc_code)) return false; - reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype); + reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype, optab_default); if (!reduc_optab) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -3852,6 +3852,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, VEC(tree,heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL; tree vop0, vop1; unsigned int k; + bool shift_p = false; bool scalar_shift_arg = false; /* FORNOW: SLP with multiple types is not supported. The SLP analysis verifies @@ -3896,8 +3897,6 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, if (code == POINTER_PLUS_EXPR) code = PLUS_EXPR; - optab = optab_for_tree_code (code, vectype); - /* Support only unary or binary operations. */ op_type = TREE_OPERAND_LENGTH (operation); if (op_type != unary_op && op_type != binary_op) @@ -3926,6 +3925,56 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, } } + /* If this is a shift/rotate, 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 (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR + || code == RROTATE_EXPR) + { + shift_p = true; + + /* vector shifted by vector */ + if (dt[1] == vect_loop_def) + { + optab = optab_for_tree_code (code, vectype, optab_vector); + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "vector/vector shift/rotate found."); + } + + /* 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_invariant_def) + { + optab = optab_for_tree_code (code, vectype, optab_scalar); + if (optab + && (optab_handler (optab, TYPE_MODE (vectype))->insn_code + != CODE_FOR_nothing)) + { + scalar_shift_arg = true; + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "vector/scalar shift/rotate found."); + } + else + { + optab = optab_for_tree_code (code, vectype, optab_vector); + if (vect_print_dump_info (REPORT_DETAILS) + && optab + && (optab_handler (optab, TYPE_MODE (vectype))->insn_code + != CODE_FOR_nothing)) + fprintf (vect_dump, "vector/vector shift/rotate found."); + } + } + + else + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "operand mode requires invariant argument."); + return false; + } + } + else + optab = optab_for_tree_code (code, vectype, optab_default); + /* Supportable by target? */ if (!optab) { @@ -3960,29 +4009,6 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, return false; } - if (code == LSHIFT_EXPR || code == RSHIFT_EXPR) - { - /* FORNOW: not yet supported. */ - if (!VECTOR_MODE_P (vec_mode)) - return false; - - /* Invariant argument is needed for a vector shift - by a scalar shift operand. */ - optab_op2_mode = insn_data[icode].operand[2].mode; - if (!VECTOR_MODE_P (optab_op2_mode)) - { - if (dt[1] != vect_constant_def && dt[1] != vect_invariant_def) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "operand mode requires invariant" - " argument."); - return false; - } - - scalar_shift_arg = true; - } - } - if (!vec_stmt) /* transformation not required. */ { STMT_VINFO_TYPE (stmt_info) = op_vec_info_type; @@ -4075,8 +4101,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, /* Handle uses. */ if (j == 0) { - if (op_type == binary_op - && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)) + if (op_type == binary_op && scalar_shift_arg) { /* Vector shl and shr insn patterns can be defined with scalar operand 2 (shift operand). In this case, use constant or loop @@ -4495,9 +4520,9 @@ vect_strided_store_supported (tree vectype) /* Check that the operation is supported. */ interleave_high_optab = optab_for_tree_code (VEC_INTERLEAVE_HIGH_EXPR, - vectype); + vectype, optab_default); interleave_low_optab = optab_for_tree_code (VEC_INTERLEAVE_LOW_EXPR, - vectype); + vectype, optab_default); if (!interleave_high_optab || !interleave_low_optab) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -5238,7 +5263,8 @@ vect_strided_load_supported (tree vectype) mode = (int) TYPE_MODE (vectype); - perm_even_optab = optab_for_tree_code (VEC_EXTRACT_EVEN_EXPR, vectype); + perm_even_optab = optab_for_tree_code (VEC_EXTRACT_EVEN_EXPR, vectype, + optab_default); if (!perm_even_optab) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -5253,7 +5279,8 @@ vect_strided_load_supported (tree vectype) return false; } - perm_odd_optab = optab_for_tree_code (VEC_EXTRACT_ODD_EXPR, vectype); + perm_odd_optab = optab_for_tree_code (VEC_EXTRACT_ODD_EXPR, vectype, + optab_default); if (!perm_odd_optab) { if (vect_print_dump_info (REPORT_DETAILS)) |