]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Generalise _m rules for SVE intrinsics
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 5 Dec 2023 10:11:28 +0000 (10:11 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Tue, 5 Dec 2023 10:11:28 +0000 (10:11 +0000)
In SVE there was a simple rule that unary merging (_m) intrinsics
had a separate initial argument to specify the values of inactive
lanes, whereas other merging functions took inactive lanes from
the first operand to the operation.

That rule began to break down in SVE2, and it continues to do
so in SME.  This patch therefore adds a virtual function to
specify whether the separate initial argument is present or not.
The old rule is still the default.

gcc/
* config/aarch64/aarch64-sve-builtins.h
(function_shape::has_merge_argument_p): New member function.
* config/aarch64/aarch64-sve-builtins.cc:
(function_resolver::check_gp_argument): Use it.
(function_expander::get_fallback_value): Likewise.
* config/aarch64/aarch64-sve-builtins-shapes.cc
(apply_predication): Likewise.
(unary_convert_narrowt_def::has_merge_argument_p): New function.

gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
gcc/config/aarch64/aarch64-sve-builtins.cc
gcc/config/aarch64/aarch64-sve-builtins.h

index 2c25b122f05645c2d599f091c9dc2f34b83504d5..68708712001929227937ab62a42a6d1b18bb44e9 100644 (file)
@@ -66,8 +66,8 @@ apply_predication (const function_instance &instance, tree return_type,
         the same type as the result.  For unary_convert_narrowt it also
         provides the "bottom" half of active elements, and is present
         for all types of predication.  */
-      if ((argument_types.length () == 2 && instance.pred == PRED_m)
-         || instance.shape == shapes::unary_convert_narrowt)
+      auto nargs = argument_types.length () - 1;
+      if (instance.shape->has_merge_argument_p (instance, nargs))
        argument_types.quick_insert (0, return_type);
     }
 }
@@ -3271,6 +3271,12 @@ SHAPE (unary_convert)
    predicate.  */
 struct unary_convert_narrowt_def : public overloaded_base<1>
 {
+  bool
+  has_merge_argument_p (const function_instance &, unsigned int) const override
+  {
+    return true;
+  }
+
   void
   build (function_builder &b, const function_group_info &group) const override
   {
index d5ac1dc76c58f22451b19cee223f5522f4cc9967..7950977c14b93f9b9cc349b9582bfd91d244ec04 100644 (file)
@@ -2287,7 +2287,7 @@ function_resolver::check_gp_argument (unsigned int nops,
   if (pred != PRED_none)
     {
       /* Unary merge operations should use resolve_unary instead.  */
-      gcc_assert (nops != 1 || pred != PRED_m);
+      gcc_assert (!shape->has_merge_argument_p (*this, nops));
       nargs = nops + 1;
       if (!check_num_arguments (nargs)
          || !require_vector_type (i, VECTOR_TYPE_svbool_t))
@@ -2997,7 +2997,7 @@ function_expander::get_fallback_value (machine_mode mode, unsigned int nops,
 
   gcc_assert (pred == PRED_m || pred == PRED_x);
   if (merge_argno == DEFAULT_MERGE_ARGNO)
-    merge_argno = nops == 1 && pred == PRED_m ? 0 : 1;
+    merge_argno = shape->has_merge_argument_p (*this, nops) ? 0 : 1;
 
   if (merge_argno == 0)
     return args[argno++];
index e770a4042fe289017cf0c66ae6a63585ad19ac0e..b0218bbad6e7b71f384464cb8304d2215f309f64 100644 (file)
@@ -712,6 +712,9 @@ public:
 class function_shape
 {
 public:
+  virtual bool has_merge_argument_p (const function_instance &,
+                                    unsigned int) const;
+
   virtual bool explicit_type_suffix_p (unsigned int) const = 0;
 
   /* True if the group suffix is present in overloaded names.
@@ -987,6 +990,16 @@ function_base::vectors_per_tuple (const function_instance &instance) const
   return instance.group_suffix ().vectors_per_tuple;
 }
 
+/* Return true if INSTANCE (which has NARGS arguments) has an initial
+   vector argument whose only purpose is to specify the values of
+   inactive lanes.  */
+inline bool
+function_shape::has_merge_argument_p (const function_instance &instance,
+                                     unsigned int nargs) const
+{
+  return nargs == 1 && instance.pred == PRED_m;
+}
+
 /* Return the mode of the result of a call.  */
 inline machine_mode
 function_expander::result_mode () const