diff options
-rw-r--r-- | gcc/tree-vect-generic.cc | 6 | ||||
-rw-r--r-- | gcc/tree-vect-slp.cc | 19 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.cc | 38 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 4 |
4 files changed, 52 insertions, 15 deletions
diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index c2f7a29..173ebd9 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -1755,10 +1755,8 @@ expand_vector_conversion (gimple_stmt_iterator *gsi) modifier = WIDEN; auto_vec<std::pair<tree, tree_code> > converts; - if (supportable_indirect_convert_operation (code, - ret_type, arg_type, - converts, - arg)) + if (supportable_indirect_convert_operation (code, ret_type, arg_type, + converts)) { new_rhs = arg; for (unsigned int i = 0; i < converts.length () - 1; i++) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index ac17330..8ed746e 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -10199,6 +10199,25 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node) SLP_TREE_VEC_DEFS (op_node).quick_push (vop); } +/* Get the scalar definition of the Nth lane from SLP_NODE or NULL_TREE + if there is no definition for it in the scalar IL or it is not known. */ + +tree +vect_get_slp_scalar_def (slp_tree slp_node, unsigned n) +{ + if (SLP_TREE_DEF_TYPE (slp_node) == vect_internal_def) + { + if (!SLP_TREE_SCALAR_STMTS (slp_node).exists ()) + return NULL_TREE; + stmt_vec_info def = SLP_TREE_SCALAR_STMTS (slp_node)[n]; + if (!def) + return NULL_TREE; + return gimple_get_lhs (STMT_VINFO_STMT (def)); + } + else + return SLP_TREE_SCALAR_OPS (slp_node)[n]; +} + /* Get the Ith vectorized definition from SLP_NODE. */ tree diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 1b639ae..6bbb16b 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -5610,10 +5610,8 @@ vectorizable_conversion (vec_info *vinfo, return false; gcc_assert (code.is_tree_code ()); if (supportable_indirect_convert_operation (code, - vectype_out, - vectype_in, - converts, - op0)) + vectype_out, vectype_in, + converts, op0, slp_op0)) { gcc_assert (converts.length () <= 2); if (converts.length () == 1) @@ -5750,7 +5748,16 @@ vectorizable_conversion (vec_info *vinfo, else if (code == FLOAT_EXPR) { wide_int op_min_value, op_max_value; - if (!vect_get_range_info (op0, &op_min_value, &op_max_value)) + if (slp_node) + { + tree def; + /* ??? Merge ranges in case of more than one lane. */ + if (SLP_TREE_LANES (slp_op0) != 1 + || !(def = vect_get_slp_scalar_def (slp_op0, 0)) + || !vect_get_range_info (def, &op_min_value, &op_max_value)) + goto unsupported; + } + else if (!vect_get_range_info (op0, &op_min_value, &op_max_value)) goto unsupported; cvt_type @@ -15197,7 +15204,7 @@ supportable_indirect_convert_operation (code_helper code, tree vectype_out, tree vectype_in, vec<std::pair<tree, tree_code> > &converts, - tree op0) + tree op0, slp_tree slp_op0) { bool found_mode = false; scalar_mode lhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_out)); @@ -15269,10 +15276,21 @@ supportable_indirect_convert_operation (code_helper code, In the future, if it is supported, changes may need to be made to this part, such as checking the RANGE of each element in the vector. */ - if (TREE_CODE (op0) != SSA_NAME - || !SSA_NAME_RANGE_INFO (op0) - || !vect_get_range_info (op0, &op_min_value, - &op_max_value)) + if (slp_op0) + { + tree def; + /* ??? Merge ranges in case of more than one lane. */ + if (SLP_TREE_LANES (slp_op0) != 1 + || !(def = vect_get_slp_scalar_def (slp_op0, 0)) + || !vect_get_range_info (def, + &op_min_value, &op_max_value)) + break; + } + else if (!op0 + || TREE_CODE (op0) != SSA_NAME + || !SSA_NAME_RANGE_INFO (op0) + || !vect_get_range_info (op0, &op_min_value, + &op_max_value)) break; if (cvt_type == NULL_TREE diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 44d3a1d..b0cb081 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -2345,7 +2345,8 @@ extern bool supportable_narrowing_operation (code_helper, tree, tree, extern bool supportable_indirect_convert_operation (code_helper, tree, tree, vec<std::pair<tree, tree_code> > &, - tree = NULL_TREE); + tree = NULL_TREE, + slp_tree = NULL); extern int compare_step_with_zero (vec_info *, stmt_vec_info); extern unsigned record_stmt_cost (stmt_vector_for_cost *, int, @@ -2598,6 +2599,7 @@ extern bool vect_make_slp_decision (loop_vec_info); extern void vect_detect_hybrid_slp (loop_vec_info); extern void vect_optimize_slp (vec_info *); extern void vect_gather_slp_loads (vec_info *); +extern tree vect_get_slp_scalar_def (slp_tree, unsigned); extern void vect_get_slp_defs (slp_tree, vec<tree> *); extern void vect_get_slp_defs (vec_info *, slp_tree, vec<vec<tree> > *, unsigned n = -1U); |