]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
autovectorizer: Add basic support for convert optabs
authorVictor Do Nascimento <victor.donascimento@arm.com>
Wed, 22 May 2024 09:06:57 +0000 (10:06 +0100)
committerVictor Do Nascimento <victor.donascimento@arm.com>
Mon, 30 Sep 2024 14:59:42 +0000 (15:59 +0100)
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'.

gcc/gimple-match-exports.cc
gcc/gimple-match.h
gcc/optabs.cc
gcc/tree-vect-loop.cc
gcc/tree-vect-patterns.cc

index 86e40100899a0ac3963d49d1a6b421136e548c8c..d3e626a1a2451c6d023768c21bda9e54878bceeb 100644 (file)
@@ -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.  */
 
index 8edff578ba9a14bfd529bb3ce8928612efa481ac..645810076d157bdfc18706f7da9a468d8d823a47 100644 (file)
@@ -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);
index 2bcb3f7b47aefbb12c26532229260840556ddcbc..0e651e9e514063355e1ef8cb1b0c567c9736919c 100644 (file)
@@ -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);
index 0ce1bf8ebbacc541acdb718234570f544ca913e9..a5a44613cb246e43a452a1e78efbbac982db4d6b 100644 (file)
@@ -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);
 }
index b174ff1e705cec8e7bb414c760eb170ca98222cb..9bf8526ac995c6c2678b25f5df4316aec41333e0 100644 (file)
@@ -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))