diff mbox series

[v2,36/36] arm: [MVE intrinsics] use long_type_suffix / half_type_suffix helpers

Message ID 20240904132650.2720446-37-christophe.lyon@linaro.org
State New
Headers show
Series arm: [MVE intrinsics] Re-implement more intrinsics | expand

Commit Message

Christophe Lyon Sept. 4, 2024, 1:26 p.m. UTC
In several places we are looking for a type twice or half as large as
the type suffix: this patch introduces helper functions to avoid code
duplication. long_type_suffix is similar to the SVE counterpart, but
adds an 'expected_tclass' parameter.  half_type_suffix is similar to
it, but does not exist in SVE.

2024-08-28  Christophe Lyon  <christophe.lyon@linaro.org>

	gcc/

	* config/arm/arm-mve-builtins-shapes.cc (long_type_suffix): New.
	(half_type_suffix): New.
	(struct binary_move_narrow_def): Use new helper.
	(struct binary_move_narrow_unsigned_def): Likewise.
	(struct binary_rshift_narrow_def): Likewise.
	(struct binary_rshift_narrow_unsigned_def): Likewise.
	(struct binary_widen_def): Likewise.
	(struct binary_widen_n_def): Likewise.
	(struct binary_widen_opt_n_def): Likewise.
	(struct unary_widen_def): Likewise.
---
 gcc/config/arm/arm-mve-builtins-shapes.cc | 114 +++++++++++++---------
 1 file changed, 68 insertions(+), 46 deletions(-)

Comments

Richard Earnshaw (lists) Oct. 14, 2024, 6:24 p.m. UTC | #1
On 04/09/2024 14:26, Christophe Lyon wrote:
> In several places we are looking for a type twice or half as large as
> the type suffix: this patch introduces helper functions to avoid code
> duplication. long_type_suffix is similar to the SVE counterpart, but
> adds an 'expected_tclass' parameter.  half_type_suffix is similar to
> it, but does not exist in SVE.
> 
> 2024-08-28  Christophe Lyon  <christophe.lyon@linaro.org>
> 
> 	gcc/
> 
> 	* config/arm/arm-mve-builtins-shapes.cc (long_type_suffix): New.
> 	(half_type_suffix): New.
> 	(struct binary_move_narrow_def): Use new helper.
> 	(struct binary_move_narrow_unsigned_def): Likewise.
> 	(struct binary_rshift_narrow_def): Likewise.
> 	(struct binary_rshift_narrow_unsigned_def): Likewise.
> 	(struct binary_widen_def): Likewise.
> 	(struct binary_widen_n_def): Likewise.
> 	(struct binary_widen_opt_n_def): Likewise.
> 	(struct unary_widen_def): Likewise.

OK.

R.

> ---
>  gcc/config/arm/arm-mve-builtins-shapes.cc | 114 +++++++++++++---------
>  1 file changed, 68 insertions(+), 46 deletions(-)
> 
> diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc b/gcc/config/arm/arm-mve-builtins-shapes.cc
> index 9deed178966..0a108cf0127 100644
> --- a/gcc/config/arm/arm-mve-builtins-shapes.cc
> +++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
> @@ -320,6 +320,45 @@ build_16_32 (function_builder &b, const char *signature,
>      }
>  }
>  
> +/* TYPE is the largest type suffix associated with the arguments of R, but the
> +   result is twice as wide.  Return the associated type suffix of
> +   EXPECTED_TCLASS if it exists, otherwise report an appropriate error and
> +   return NUM_TYPE_SUFFIXES.  */
> +static type_suffix_index
> +long_type_suffix (function_resolver &r,
> +		  type_suffix_index type,
> +		  type_class_index expected_tclass)
> +{
> +  unsigned int element_bits = type_suffixes[type].element_bits;
> +  if (expected_tclass == function_resolver::SAME_TYPE_CLASS)
> +    expected_tclass = type_suffixes[type].tclass;
> +
> +  if (type_suffixes[type].integer_p && element_bits < 64)
> +    return find_type_suffix (expected_tclass, element_bits * 2);
> +
> +  r.report_no_such_form (type);
> +  return NUM_TYPE_SUFFIXES;
> +}
> +
> +/* Return the type suffix half as wide as TYPE with EXPECTED_TCLASS if it
> +   exists, otherwise report an appropriate error and return
> +   NUM_TYPE_SUFFIXES.  */
> +static type_suffix_index
> +half_type_suffix (function_resolver &r,
> +		  type_suffix_index type,
> +		  type_class_index expected_tclass)
> +{
> +  unsigned int element_bits = type_suffixes[type].element_bits;
> +  if (expected_tclass == function_resolver::SAME_TYPE_CLASS)
> +    expected_tclass = type_suffixes[type].tclass;
> +
> +  if (type_suffixes[type].integer_p && element_bits > 8)
> +    return find_type_suffix (expected_tclass, element_bits / 2);
> +
> +  r.report_no_such_form (type);
> +  return NUM_TYPE_SUFFIXES;
> +}
> +
>  /* Declare the function shape NAME, pointing it to an instance
>     of class <NAME>_def.  */
>  #define SHAPE(NAME) \
> @@ -779,16 +818,13 @@ struct binary_move_narrow_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, narrow_suffix;
>      if (!r.check_gp_argument (2, i, nargs)
> -	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES)
> +	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
> +	|| ((narrow_suffix = half_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES))
>        return error_mark_node;
>  
> -    type_suffix_index narrow_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits / 2);
> -
> -
>      if (!r.require_matching_vector_type (0, narrow_suffix))
>        return error_mark_node;
>  
> @@ -816,15 +852,13 @@ struct binary_move_narrow_unsigned_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, narrow_suffix;
>      if (!r.check_gp_argument (2, i, nargs)
> -	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES)
> +	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
> +	|| ((narrow_suffix = half_type_suffix (r, type, TYPE_unsigned))
> +	    == NUM_TYPE_SUFFIXES))
>        return error_mark_node;
>  
> -    type_suffix_index narrow_suffix
> -      = find_type_suffix (TYPE_unsigned,
> -			  type_suffixes[type].element_bits / 2);
> -
>      if (!r.require_matching_vector_type (0, narrow_suffix))
>        return error_mark_node;
>  
> @@ -1112,16 +1146,14 @@ struct binary_rshift_narrow_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, narrow_suffix;
>      if (!r.check_gp_argument (3, i, nargs)
>  	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
> +	|| ((narrow_suffix = half_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES)
>  	|| !r.require_integer_immediate (i))
>        return error_mark_node;
>  
> -    type_suffix_index narrow_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits / 2);
> -
>      if (!r.require_matching_vector_type (0, narrow_suffix))
>        return error_mark_node;
>  
> @@ -1159,16 +1191,14 @@ struct binary_rshift_narrow_unsigned_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, narrow_suffix;
>      if (!r.check_gp_argument (3, i, nargs)
>  	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
> +	|| ((narrow_suffix = half_type_suffix (r, type, TYPE_unsigned))
> +	    == NUM_TYPE_SUFFIXES)
>  	|| !r.require_integer_immediate (i))
>        return error_mark_node;
>  
> -    type_suffix_index narrow_suffix
> -      = find_type_suffix (TYPE_unsigned,
> -			  type_suffixes[type].element_bits / 2);
> -
>      if (!r.require_matching_vector_type (0, narrow_suffix))
>        return error_mark_node;
>  
> @@ -1205,15 +1235,13 @@ struct binary_widen_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, wide_suffix;
>      if (!r.check_gp_argument (2, i, nargs)
> -	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES)
> +	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
> +	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES))
>        return error_mark_node;
>  
> -    type_suffix_index wide_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits * 2);
> -
>      if (!r.require_matching_vector_type (i, type))
>        return error_mark_node;
>  
> @@ -1298,17 +1326,15 @@ struct binary_widen_n_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, wide_suffix;
>      tree res;
>      if (!r.check_gp_argument (2, i, nargs)
>  	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
> +	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES)
>  	|| !r.require_integer_immediate (i))
>        return error_mark_node;
>  
> -    type_suffix_index wide_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits * 2);
> -
>      /* Check the inactive argument has the wide type.  */
>      if (((r.pred == PRED_m) && (r.infer_vector_type (0) == wide_suffix))
>  	|| r.pred == PRED_none
> @@ -1352,15 +1378,13 @@ struct binary_widen_opt_n_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, wide_suffix;
>      if (!r.check_gp_argument (2, i, nargs)
> -	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES)
> +	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
> +	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES))
>        return error_mark_node;
>  
> -    type_suffix_index wide_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits * 2);
> -
>      /* Skip last argument, may be scalar, will be checked below by
>         finish_opt_n_resolution.  */
>      unsigned int last_arg = i--;
> @@ -1939,16 +1963,14 @@ struct unary_widen_def : public overloaded_base<0>
>    resolve (function_resolver &r) const override
>    {
>      unsigned int i, nargs;
> -    type_suffix_index type;
> +    type_suffix_index type, wide_suffix;
>      tree res;
>      if (!r.check_gp_argument (1, i, nargs)
> -	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
> +	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
> +	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
> +	    == NUM_TYPE_SUFFIXES))
>        return error_mark_node;
>  
> -    type_suffix_index wide_suffix
> -      = find_type_suffix (type_suffixes[type].tclass,
> -			  type_suffixes[type].element_bits * 2);
> -
>      /* Check the inactive argument has the wide type.  */
>      if ((r.pred == PRED_m)
>  	&& (r.infer_vector_type (0) != wide_suffix))
diff mbox series

Patch

diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc b/gcc/config/arm/arm-mve-builtins-shapes.cc
index 9deed178966..0a108cf0127 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.cc
+++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
@@ -320,6 +320,45 @@  build_16_32 (function_builder &b, const char *signature,
     }
 }
 
+/* TYPE is the largest type suffix associated with the arguments of R, but the
+   result is twice as wide.  Return the associated type suffix of
+   EXPECTED_TCLASS if it exists, otherwise report an appropriate error and
+   return NUM_TYPE_SUFFIXES.  */
+static type_suffix_index
+long_type_suffix (function_resolver &r,
+		  type_suffix_index type,
+		  type_class_index expected_tclass)
+{
+  unsigned int element_bits = type_suffixes[type].element_bits;
+  if (expected_tclass == function_resolver::SAME_TYPE_CLASS)
+    expected_tclass = type_suffixes[type].tclass;
+
+  if (type_suffixes[type].integer_p && element_bits < 64)
+    return find_type_suffix (expected_tclass, element_bits * 2);
+
+  r.report_no_such_form (type);
+  return NUM_TYPE_SUFFIXES;
+}
+
+/* Return the type suffix half as wide as TYPE with EXPECTED_TCLASS if it
+   exists, otherwise report an appropriate error and return
+   NUM_TYPE_SUFFIXES.  */
+static type_suffix_index
+half_type_suffix (function_resolver &r,
+		  type_suffix_index type,
+		  type_class_index expected_tclass)
+{
+  unsigned int element_bits = type_suffixes[type].element_bits;
+  if (expected_tclass == function_resolver::SAME_TYPE_CLASS)
+    expected_tclass = type_suffixes[type].tclass;
+
+  if (type_suffixes[type].integer_p && element_bits > 8)
+    return find_type_suffix (expected_tclass, element_bits / 2);
+
+  r.report_no_such_form (type);
+  return NUM_TYPE_SUFFIXES;
+}
+
 /* Declare the function shape NAME, pointing it to an instance
    of class <NAME>_def.  */
 #define SHAPE(NAME) \
@@ -779,16 +818,13 @@  struct binary_move_narrow_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, narrow_suffix;
     if (!r.check_gp_argument (2, i, nargs)
-	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES)
+	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
+	|| ((narrow_suffix = half_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES))
       return error_mark_node;
 
-    type_suffix_index narrow_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits / 2);
-
-
     if (!r.require_matching_vector_type (0, narrow_suffix))
       return error_mark_node;
 
@@ -816,15 +852,13 @@  struct binary_move_narrow_unsigned_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, narrow_suffix;
     if (!r.check_gp_argument (2, i, nargs)
-	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES)
+	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
+	|| ((narrow_suffix = half_type_suffix (r, type, TYPE_unsigned))
+	    == NUM_TYPE_SUFFIXES))
       return error_mark_node;
 
-    type_suffix_index narrow_suffix
-      = find_type_suffix (TYPE_unsigned,
-			  type_suffixes[type].element_bits / 2);
-
     if (!r.require_matching_vector_type (0, narrow_suffix))
       return error_mark_node;
 
@@ -1112,16 +1146,14 @@  struct binary_rshift_narrow_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, narrow_suffix;
     if (!r.check_gp_argument (3, i, nargs)
 	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
+	|| ((narrow_suffix = half_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES)
 	|| !r.require_integer_immediate (i))
       return error_mark_node;
 
-    type_suffix_index narrow_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits / 2);
-
     if (!r.require_matching_vector_type (0, narrow_suffix))
       return error_mark_node;
 
@@ -1159,16 +1191,14 @@  struct binary_rshift_narrow_unsigned_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, narrow_suffix;
     if (!r.check_gp_argument (3, i, nargs)
 	|| (type = r.infer_vector_type (1)) == NUM_TYPE_SUFFIXES
+	|| ((narrow_suffix = half_type_suffix (r, type, TYPE_unsigned))
+	    == NUM_TYPE_SUFFIXES)
 	|| !r.require_integer_immediate (i))
       return error_mark_node;
 
-    type_suffix_index narrow_suffix
-      = find_type_suffix (TYPE_unsigned,
-			  type_suffixes[type].element_bits / 2);
-
     if (!r.require_matching_vector_type (0, narrow_suffix))
       return error_mark_node;
 
@@ -1205,15 +1235,13 @@  struct binary_widen_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, wide_suffix;
     if (!r.check_gp_argument (2, i, nargs)
-	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES)
+	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
+	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES))
       return error_mark_node;
 
-    type_suffix_index wide_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits * 2);
-
     if (!r.require_matching_vector_type (i, type))
       return error_mark_node;
 
@@ -1298,17 +1326,15 @@  struct binary_widen_n_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, wide_suffix;
     tree res;
     if (!r.check_gp_argument (2, i, nargs)
 	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
+	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES)
 	|| !r.require_integer_immediate (i))
       return error_mark_node;
 
-    type_suffix_index wide_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits * 2);
-
     /* Check the inactive argument has the wide type.  */
     if (((r.pred == PRED_m) && (r.infer_vector_type (0) == wide_suffix))
 	|| r.pred == PRED_none
@@ -1352,15 +1378,13 @@  struct binary_widen_opt_n_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, wide_suffix;
     if (!r.check_gp_argument (2, i, nargs)
-	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES)
+	|| (type = r.infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES
+	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES))
       return error_mark_node;
 
-    type_suffix_index wide_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits * 2);
-
     /* Skip last argument, may be scalar, will be checked below by
        finish_opt_n_resolution.  */
     unsigned int last_arg = i--;
@@ -1939,16 +1963,14 @@  struct unary_widen_def : public overloaded_base<0>
   resolve (function_resolver &r) const override
   {
     unsigned int i, nargs;
-    type_suffix_index type;
+    type_suffix_index type, wide_suffix;
     tree res;
     if (!r.check_gp_argument (1, i, nargs)
-	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
+	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
+	|| ((wide_suffix = long_type_suffix (r, type, r.SAME_TYPE_CLASS))
+	    == NUM_TYPE_SUFFIXES))
       return error_mark_node;
 
-    type_suffix_index wide_suffix
-      = find_type_suffix (type_suffixes[type].tclass,
-			  type_suffixes[type].element_bits * 2);
-
     /* Check the inactive argument has the wide type.  */
     if ((r.pred == PRED_m)
 	&& (r.infer_vector_type (0) != wide_suffix))