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
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)
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
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));
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
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,
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);