https://gcc.gnu.org/g:2d7d8179cbccaddb308c966b9c1d4840c0d56b03

commit r15-5205-g2d7d8179cbccaddb308c966b9c1d4840c0d56b03
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Wed Nov 13 17:21:35 2024 +0000

    aarch64: Relax add_overloaded_function assert
    
    There are some SVE intrinsics that support one set of suffixes for
    one extension (E1, say) and another set of suffixes for another
    extension (E2, say).  It is usually the case that, mutatis mutandis,
    E2 extends E1.  Listing E1 first would then ensure that the manual
    C overload would also require E1, making it suitable for resolving
    both the E1 forms and, where appropriate, the E2 forms.
    
    However, there was one exception: the I8MM, F32MM, and F64MM extensions
    to SVE each added variants of svmmla, but there was no svmmla for SVE
    itself.  This was handled by adding an SVE entry for svmmla that only
    defined the C overload; it had no variants of its own.
    
    This situation occurs more often with upcoming patches.  Rather than
    keep adding these dummy entries, it seemed better to make the code
    automatically compute the lowest common denominator for all definitions
    that share the same C overload.
    
    gcc/
            * config/aarch64/aarch64-protos.h
            (aarch64_required_extensions::common_denominator): New member
            function.
            * config/aarch64/aarch64-sve-builtins-base.def: Remove zero-variant
            entry for mmla.
            * config/aarch64/aarch64-sve-builtins-shapes.cc (mmla_def): Remove
            support for it.
            * config/aarch64/aarch64-sve-builtins.cc
            (function_builder::add_overloaded): Relax the assert for duplicate
            definitions and instead calculate the common denominator of all
            requirements.

Diff:
---
 gcc/config/aarch64/aarch64-protos.h               | 13 +++++++++++++
 gcc/config/aarch64/aarch64-sve-builtins-base.def  |  1 -
 gcc/config/aarch64/aarch64-sve-builtins-shapes.cc | 14 ++++----------
 gcc/config/aarch64/aarch64-sve-builtins.cc        | 18 +++++++++++-------
 4 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 05d3258abf7b..72df4a575b32 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -759,6 +759,19 @@ struct aarch64_required_extensions
             sm_on ? sm_on | flags : 0 };
   }
 
+  /* Return a requirement that is as restrictive as possible while still being
+     no more restrictive than THIS and no more restrictive than OTHER.  */
+  inline CONSTEXPR aarch64_required_extensions
+  common_denominator (const aarch64_required_extensions &other)
+  {
+    return { sm_off && other.sm_off
+            ? sm_off & other.sm_off
+            : sm_off | other.sm_off,
+            sm_on && other.sm_on
+            ? sm_on & other.sm_on
+            : sm_on | other.sm_on };
+  }
+
   /* Require non-streaming mode and the features in FLAGS.  */
   static inline CONSTEXPR aarch64_required_extensions
   nonstreaming_only (aarch64_feature_flags flags)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.def 
b/gcc/config/aarch64/aarch64-sve-builtins-base.def
index 0353f56e7057..99800382762d 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.def
@@ -311,7 +311,6 @@ DEF_SVE_FUNCTION (svldnf1sw, load_ext, d_integer, implicit)
 DEF_SVE_FUNCTION (svldnf1ub, load_ext, hsd_integer, implicit)
 DEF_SVE_FUNCTION (svldnf1uh, load_ext, sd_integer, implicit)
 DEF_SVE_FUNCTION (svldnf1uw, load_ext, d_integer, implicit)
-DEF_SVE_FUNCTION (svmmla, mmla, none, none)
 DEF_SVE_FUNCTION (svprfb_gather, prefetch_gather_offset, none, implicit)
 DEF_SVE_FUNCTION (svprfd_gather, prefetch_gather_index, none, implicit)
 DEF_SVE_FUNCTION (svprfh_gather, prefetch_gather_index, none, implicit)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
index 1088fbaa676e..072d3a965c06 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
@@ -932,16 +932,10 @@ struct mmla_def : public overloaded_base<0>
   build (function_builder &b, const function_group_info &group) const override
   {
     b.add_overloaded_functions (group, MODE_none);
-    /* svmmla is distributed over several extensions.  Allow the common
-       denominator to define the overloaded svmmla function without
-       defining any specific versions.  */
-    if (group.types[0][0] != NUM_TYPE_SUFFIXES)
-      {
-       if (type_suffixes[group.types[0][0]].float_p)
-         build_all (b, "v0,v0,v0,v0", group, MODE_none);
-       else
-         build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
-      }
+    if (type_suffixes[group.types[0][0]].float_p)
+      build_all (b, "v0,v0,v0,v0", group, MODE_none);
+    else
+      build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
   }
 
   tree
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc 
b/gcc/config/aarch64/aarch64-sve-builtins.cc
index be6ababde50d..b3d961452d32 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -1604,13 +1604,17 @@ add_overloaded_function (const function_instance 
&instance,
   char *name = get_name (instance, true);
   tree id = get_identifier (name);
   if (registered_function **map_value = name_map->get (id))
-    gcc_assert ((*map_value)->instance == instance
-               && (required_extensions.sm_off == 0
-                   || ((*map_value)->required_extensions.sm_off
-                       & ~required_extensions.sm_off) == 0)
-               && (required_extensions.sm_on == 0
-                   || ((*map_value)->required_extensions.sm_on
-                       & ~required_extensions.sm_on) == 0));
+    {
+      auto &dst_extensions = (*map_value)->required_extensions;
+      /* Make sure that any streaming and streaming-compatible attributes
+        on the function type are still correct.  (It might not matter if
+        they aren't, so this could be relaxed in future if we're sure that
+        it's safe.)  */
+      gcc_assert ((*map_value)->instance == instance
+                 && (dst_extensions.sm_off || !required_extensions.sm_off)
+                 && (dst_extensions.sm_on || !required_extensions.sm_on));
+      dst_extensions = dst_extensions.common_denominator (required_extensions);
+    }
   else
     {
       registered_function &rfn

Reply via email to