&& direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED));
}
+/* As above, overloading the function for conversion-type optabs. */
+bool
+directly_supported_p (code_helper code, tree otype, tree itype,
+ optab_subtype query_type)
+{
+ if (code.is_tree_code ())
+ {
+ convert_optab optab = optab_for_tree_code (tree_code (code), itype,
+ query_type);
+ return (optab != unknown_optab
+ && convert_optab_handler (optab, TYPE_MODE (otype),
+ TYPE_MODE (itype)) != CODE_FOR_nothing);
+ }
+ gcc_assert (query_type == optab_default
+ || (query_type == optab_vector && VECTOR_TYPE_P (itype))
+ || (query_type == optab_scalar && !VECTOR_TYPE_P (itype)));
+ internal_fn ifn = associated_internal_fn (combined_fn (code), itype);
+ return (direct_internal_fn_p (ifn)
+ && direct_internal_fn_supported_p (ifn, tree_pair (otype, itype),
+ OPTIMIZE_FOR_SPEED));
+}
+
+
/* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
for a code_helper CODE operating on type TYPE. */
#ifdef GCC_OPTABS_TREE_H
bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
+bool directly_supported_p (code_helper, tree, tree,
+ optab_subtype = optab_default);
#endif
internal_fn get_conditional_internal_fn (code_helper, tree);
widen_pattern_optab
= optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
if (ops->code == WIDEN_MULT_PLUS_EXPR
- || ops->code == WIDEN_MULT_MINUS_EXPR)
+ || ops->code == WIDEN_MULT_MINUS_EXPR
+ || ops->code == DOT_PROD_EXPR)
icode = find_widening_optab_handler (widen_pattern_optab,
TYPE_MODE (TREE_TYPE (ops->op2)),
tmode0);
gcc_assert (STMT_VINFO_REDUC_VECTYPE_IN (stmt_info));
return !directly_supported_p (DOT_PROD_EXPR,
+ STMT_VINFO_VECTYPE (stmt_info),
STMT_VINFO_REDUC_VECTYPE_IN (stmt_info),
optab_vector_mixed_sign);
}
return true;
}
+/* Return true if the target supports a vector version of CODE,
+ where CODE is known to map to a conversion optab with the given SUBTYPE.
+ ITYPE specifies the type of (some of) the scalar inputs and OTYPE
+ specifies the type of the scalar result.
+
+ When returning true, set *VECOTYPE_OUT to the vector version of OTYPE.
+ Also set *VECITYPE_OUT to the vector version of ITYPE if VECITYPE_OUT
+ is nonnull. */
+
+static bool
+vect_supportable_conv_optab_p (vec_info *vinfo, tree otype, tree_code code,
+ tree itype, tree *vecotype_out,
+ tree *vecitype_out = NULL,
+ enum optab_subtype subtype = optab_default)
+{
+ tree vecitype = get_vectype_for_scalar_type (vinfo, itype);
+ tree vecotype = get_vectype_for_scalar_type (vinfo, otype);
+ if (!vecitype || !vecotype)
+ return false;
+
+ if (!directly_supported_p (code, vecotype, vecitype, subtype))
+ return false;
+
+ *vecotype_out = vecotype;
+ if (vecitype_out)
+ *vecitype_out = vecitype;
+ return true;
+}
+
/* Round bit precision PRECISION up to a full element. */
static unsigned int
half_type = signed_type_for (half_type);
tree half_vectype;
- if (!vect_supportable_direct_optab_p (vinfo, type, DOT_PROD_EXPR, half_type,
+ if (!vect_supportable_conv_optab_p (vinfo, type, DOT_PROD_EXPR, half_type,
type_out, &half_vectype, subtype))
{
/* We can emulate a mixed-sign dot-product using a sequence of
signed dot-products; see vect_emulate_mixed_dot_prod for details. */
if (subtype != optab_vector_mixed_sign
- || !vect_supportable_direct_optab_p (vinfo, signed_type_for (type),
+ || !vect_supportable_conv_optab_p (vinfo, signed_type_for (type),
DOT_PROD_EXPR, half_type,
type_out, &half_vectype,
optab_vector))