aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVictor Do Nascimento <victor.donascimento@arm.com>2024-05-22 10:06:57 +0100
committerVictor Do Nascimento <victor.donascimento@arm.com>2024-09-30 15:59:42 +0100
commitc7fba0e96641e57164fc72bdbffd9a1cea244818 (patch)
treefecce3d409cf91ec05492fead19b7fc5dcb2938d /gcc
parent2f68d69e47b5b627c6bb71a6bb3d7b2e0e641b2f (diff)
downloadgcc-c7fba0e96641e57164fc72bdbffd9a1cea244818.zip
gcc-c7fba0e96641e57164fc72bdbffd9a1cea244818.tar.gz
gcc-c7fba0e96641e57164fc72bdbffd9a1cea244818.tar.bz2
autovectorizer: Add basic support for convert optabs
Given the shift from modeling dot products as direct optabs to treating them as conversion optabs, we make necessary changes to the autovectorizer code to ensure that given the relevant tree code, together with the input and output data modes, we can retrieve the relevant optab and subsequently the insn_code for it. gcc/ChangeLog: * gimple-match-exports.cc (directly_supported_p): Add overload for conversion-type optabs. * gimple-match.h (directly_supported_p): Add new function prototype. * optabs.cc (expand_widen_pattern_expr): Make the DOT_PROD_EXPR tree code use `find_widening_optab_handler' to retrieve icode. * tree-vect-loop.cc (vect_is_emulated_mixed_dot_prod): make it call conversion-type overloaded `directly_supported_p'. * tree-vect-patterns.cc (vect_supportable_conv_optab_p): New. (vect_recog_dot_prod_pattern): s/direct/conv/ in call to `vect_supportable_direct_optab_p'.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-match-exports.cc23
-rw-r--r--gcc/gimple-match.h2
-rw-r--r--gcc/optabs.cc3
-rw-r--r--gcc/tree-vect-loop.cc1
-rw-r--r--gcc/tree-vect-patterns.cc33
5 files changed, 59 insertions, 3 deletions
diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc
index 86e4010..d3e626a 100644
--- a/gcc/gimple-match-exports.cc
+++ b/gcc/gimple-match-exports.cc
@@ -1401,6 +1401,29 @@ directly_supported_p (code_helper code, tree type, optab_subtype query_type)
&& 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. */
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
index 8edff57..6458100 100644
--- a/gcc/gimple-match.h
+++ b/gcc/gimple-match.h
@@ -421,6 +421,8 @@ code_helper canonicalize_code (code_helper, tree);
#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);
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 2bcb3f7..0e651e9 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -317,7 +317,8 @@ expand_widen_pattern_expr (const_sepops ops, rtx op0, rtx op1, rtx wide_op,
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);
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 0ce1bf8..a5a4461 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -5244,6 +5244,7 @@ vect_is_emulated_mixed_dot_prod (stmt_vec_info stmt_info)
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);
}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index b174ff1..9bf8526 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -262,6 +262,35 @@ vect_supportable_direct_optab_p (vec_info *vinfo, tree otype, tree_code code,
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
@@ -1282,13 +1311,13 @@ vect_recog_dot_prod_pattern (vec_info *vinfo,
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))