get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2226691/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226691,
    "url": "http://patchwork.ozlabs.org/api/patches/2226691/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.11@forge-stage.sourceware.org/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.11@forge-stage.sourceware.org>",
    "list_archive_url": null,
    "date": "2026-04-22T18:21:59",
    "name": "[v1,11/13] c: Add target_version attribute support.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "73446de189ace03dbf80f18aa27a23e84552a786",
    "submitter": {
        "id": 93228,
        "url": "http://patchwork.ozlabs.org/api/people/93228/?format=api",
        "name": "\\\"alfie.richards via Sourceware Forge\\\"",
        "email": "forge-bot+alfie.richards@forge-stage.sourceware.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.11@forge-stage.sourceware.org/mbox/",
    "series": [
        {
            "id": 501072,
            "url": "http://patchwork.ozlabs.org/api/series/501072/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501072",
            "date": "2026-04-22T18:21:54",
            "name": "FMV refactor and ACLE compliance for C++",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501072/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226691/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226691/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g17B41Mx1z1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 04:32:28 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 573BE4C31825\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 18:32:26 +0000 (GMT)",
            "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 68CA04422A92\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:23:34 +0000 (GMT)",
            "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id BB7594345E\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:23:30 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 573BE4C31825",
            "OpenDKIM Filter v2.11.0 sourceware.org 68CA04422A92"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 68CA04422A92",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 68CA04422A92",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776882214; cv=none;\n b=GHpxKr0N4jFCYOVeK5mQvZwllf5GD9HD9dGfomHkydDEVrYJ8Vo9VLXJnkdyQGgk0qjg2YAn68tD//ruEguLBGEdijBr6zAf3c6k26PT0GINfOxmudOooOsHeNeibG9b+idkCpjy3zn/5MkR3uJ7XyOH7PqWop/0xcCGv1TQ9D4=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776882214; c=relaxed/simple;\n bh=GjFkGc4RPly+cBi7Zcv9FkEI10Lm7Xbc4NLXZqwQrXA=;\n h=From:Date:Subject:To:Message-ID;\n b=Ooo3yey776PSthNXi0q+mddkOjzIbW5i19wZdeRwKCqBs3r7wGZOaN6RKhXcDZ/HUT3U/Tsuf9lmtwBdFVHwMOChMnJ47eUDrzo9YMUo4JPbWfp0LJhoWXKRRR8sOYZL0YSQoil5Us6Vudd4dgmnXdSSllrHc6fqmtepen592C4=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "\"\\\"alfie.richards via Sourceware Forge\\\"\"\n <forge-bot+alfie.richards@forge-stage.sourceware.org>",
        "Date": "Wed, 22 Apr 2026 18:21:59 +0000",
        "Subject": "[PATCH v1 11/13] c: Add target_version attribute support.",
        "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>",
        "Message-ID": "\n <bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.11@forge-stage.sourceware.org>",
        "X-Mailer": "batrachomyomachia",
        "X-Requested-Reviewer": [
            "rsandifo",
            "rearnsha"
        ],
        "X-Pull-Request-Organization": "gcc",
        "X-Pull-Request-Repository": "gcc-TEST",
        "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/49",
        "References": "\n <bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.0@forge-stage.sourceware.org>",
        "In-Reply-To": "\n <bmm.hhuodmon6a.gcc.gcc-TEST.alfie.richards.49.1.0@forge-stage.sourceware.org>",
        "X-Patch-URL": "\n https://forge.sourceware.org/alfie.richards/gcc-TEST/commit/d21158abe9bb538b2ca07e5629251c683a37f81c",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n alfierichards@sourceware.org",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: Alfie Richards <alfie.richards@arm.com>\n\nThis commit introduces support for the target_version attribute in the c\nfrontend, following the behavior defined in the Arm C Language Extension.\n\nKey changes include:\n\n- During pushdecl, the compiler now checks whether the current symbol is\n  part of a multiversioned set.\n  - New versions are added to the function multiversioning (FMV) set, and the\n    symbol binding is updated to include the default version (if present).\n    This means the binding for a multiversioned symbol will always reference\n    the default version (if present), as it defines the scope and signature\n    for the entire set.\n  - Pre-existing versions are merged with their previous version (or diagnosed).\n- Lookup logic is adjusted to prevent resolving non-default versions.\n- start_decl and start_function are updated to handle marking and mangling of\n  versioned functions.\n- c_parse_final_cleanups now includes a call to process_same_body_aliases.\n  This has no functional impact other than setting cpp_implicit_aliases_done\n  on all nodes, which is necessary for certain shared FMV logic.\n\ngcc/c/ChangeLog:\n\n\t* c-decl.cc (maybe_mark_function_versioned): New function.\n\t(merge_decls): Preserve DECL_FUNCTION_VERSIONED in merging.\n\t(duplicate_decls): Add check and diagnostic for unmergable version decls.\n\t(pushdecl): Add FMV target_version logic.\n\t(lookup_name): Don't resolve non-default versions.\n\t(start_decl): Mark and mangle versioned functions.\n\t(start_function): Mark and mangle versioned functions.\n\t(c_parse_final_cleanups): Add call to process_same_body_aliases.\n\ngcc/testsuite/ChangeLog:\n\n\t* gcc.target/aarch64/mv-1.c: New test.\n\t* gcc.target/aarch64/mv-and-mvc1.c: New test.\n\t* gcc.target/aarch64/mv-and-mvc2.c: New test.\n\t* gcc.target/aarch64/mv-and-mvc3.c: New test.\n\t* gcc.target/aarch64/mv-and-mvc4.c: New test.\n\t* gcc.target/aarch64/mv-symbols1.c: New test.\n\t* gcc.target/aarch64/mv-symbols10.c: New test.\n\t* gcc.target/aarch64/mv-symbols11.c: New test.\n\t* gcc.target/aarch64/mv-symbols12.c: New test.\n\t* gcc.target/aarch64/mv-symbols13.c: New test.\n\t* gcc.target/aarch64/mv-symbols14.c: New test.\n\t* gcc.target/aarch64/mv-symbols2.c: New test.\n\t* gcc.target/aarch64/mv-symbols3.c: New test.\n\t* gcc.target/aarch64/mv-symbols4.c: New test.\n\t* gcc.target/aarch64/mv-symbols5.c: New test.\n\t* gcc.target/aarch64/mv-symbols6.c: New test.\n\t* gcc.target/aarch64/mv-symbols7.c: New test.\n\t* gcc.target/aarch64/mv-symbols8.c: New test.\n\t* gcc.target/aarch64/mv-symbols9.c: New test.\n\t* gcc.target/aarch64/mvc-symbols1.c: New test.\n\t* gcc.target/aarch64/mvc-symbols2.c: New test.\n\t* gcc.target/aarch64/mvc-symbols3.c: New test.\n\t* gcc.target/aarch64/mvc-symbols4.c: New test.\n---\n gcc/c/c-decl.cc                               | 115 ++++++++++++++++++\n gcc/testsuite/gcc.target/aarch64/mv-1.c       |  43 +++++++\n .../gcc.target/aarch64/mv-and-mvc1.c          |  37 ++++++\n .../gcc.target/aarch64/mv-and-mvc2.c          |  28 +++++\n .../gcc.target/aarch64/mv-and-mvc3.c          |  40 ++++++\n .../gcc.target/aarch64/mv-and-mvc4.c          |  37 ++++++\n .../gcc.target/aarch64/mv-symbols1.c          |  38 ++++++\n .../gcc.target/aarch64/mv-symbols10.c         |  42 +++++++\n .../gcc.target/aarch64/mv-symbols11.c         |  16 +++\n .../gcc.target/aarch64/mv-symbols12.c         |  27 ++++\n .../gcc.target/aarch64/mv-symbols13.c         |  28 +++++\n .../gcc.target/aarch64/mv-symbols14.c         |  34 ++++++\n .../gcc.target/aarch64/mv-symbols2.c          |  28 +++++\n .../gcc.target/aarch64/mv-symbols3.c          |  27 ++++\n .../gcc.target/aarch64/mv-symbols4.c          |  31 +++++\n .../gcc.target/aarch64/mv-symbols5.c          |  36 ++++++\n .../gcc.target/aarch64/mv-symbols6.c          |  20 +++\n .../gcc.target/aarch64/mv-symbols7.c          |  47 +++++++\n .../gcc.target/aarch64/mv-symbols8.c          |  47 +++++++\n .../gcc.target/aarch64/mv-symbols9.c          |  44 +++++++\n .../gcc.target/aarch64/mvc-symbols1.c         |  25 ++++\n .../gcc.target/aarch64/mvc-symbols2.c         |  15 +++\n .../gcc.target/aarch64/mvc-symbols3.c         |  19 +++\n .../gcc.target/aarch64/mvc-symbols4.c         |  12 ++\n 24 files changed, 836 insertions(+)\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-1.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols1.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols10.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols11.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols12.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols13.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols14.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols2.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols3.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols4.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols5.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols6.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols7.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols8.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols9.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c\n create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c",
    "diff": "diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc\nindex 8e8bac6c32b9..b1b586253b82 100644\n--- a/gcc/c/c-decl.cc\n+++ b/gcc/c/c-decl.cc\n@@ -2088,6 +2088,29 @@ previous_tag (tree type)\n   return NULL_TREE;\n }\n \n+/* Subroutine to mark functions as versioned when using the attribute\n+   'target_version'.  */\n+\n+static void\n+maybe_mark_function_versioned (tree decl)\n+{\n+  if (!DECL_FUNCTION_VERSIONED (decl))\n+    {\n+      /* We need to insert function version now to make sure the correct\n+\t pre-mangled assembler name is recorded.  */\n+      cgraph_node *node = cgraph_node::get_create (decl);\n+\n+      if (!node->function_version ())\n+\tnode->insert_new_function_version ();\n+\n+      DECL_FUNCTION_VERSIONED (decl) = 1;\n+\n+      tree mangled_name\n+\t= targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));\n+      SET_DECL_ASSEMBLER_NAME (decl, mangled_name);\n+    }\n+ }\n+\n /* Subroutine of duplicate_decls.  Compare NEWDECL to OLDDECL.\n    Returns true if the caller should proceed to merge the two, false\n    if OLDDECL should simply be discarded.  As a side effect, issues\n@@ -2507,6 +2530,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,\n \t\t\t\"but not here\");\n \t    }\n \t}\n+      /* Check if these are unmergable overlapping FMV declarations.  */\n+      if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE\n+\t  && !diagnose_versioned_decls (olddecl, newdecl))\n+\treturn false;\n     }\n   else if (VAR_P (newdecl))\n     {\n@@ -2974,6 +3001,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)\n \n   if (TREE_CODE (newdecl) == FUNCTION_DECL)\n     {\n+      if (DECL_FUNCTION_VERSIONED (olddecl)\n+\t  || DECL_FUNCTION_VERSIONED (newdecl))\n+\t{\n+\t  maybe_mark_function_versioned (olddecl);\n+\t  maybe_mark_function_versioned (newdecl);\n+\t}\n       /* If we're redefining a function previously defined as extern\n \t inline, make sure we emit debug info for the inline before we\n \t throw it away, in case it was inlined into a function that\n@@ -3373,6 +3406,56 @@ pushdecl (tree x)\n \t\tTREE_TYPE (b_use->decl) = b_use->u.type;\n \t    }\n \t}\n+\n+      /* Check if x is part of a FMV set with b_use.  */\n+      if (b_use && TREE_CODE (b_use->decl) == FUNCTION_DECL\n+\t  && TREE_CODE (x) == FUNCTION_DECL && DECL_FILE_SCOPE_P (b_use->decl)\n+\t  && DECL_FILE_SCOPE_P (x)\n+\t  && distinct_version_decls (x, b_use->decl)\n+\t  && comptypes (vistype, type) != 0)\n+\t{\n+\t  if (current_scope->depth != b->depth)\n+\t    error (\"FMV versions must all be declared at the same scope level\");\n+\n+\t  maybe_mark_function_versioned (b_use->decl);\n+\t  maybe_mark_function_versioned (b->decl);\n+\t  maybe_mark_function_versioned (x);\n+\n+\t  cgraph_node *b_node = cgraph_node::get_create (b_use->decl);\n+\t  cgraph_function_version_info *b_v = b_node->function_version ();\n+\t  if (!b_v)\n+\t    b_v = b_node->insert_new_function_version ();\n+\n+\t  /* Check if this new node conflicts with any previous functions\n+\t     in the set.  */\n+\t  cgraph_function_version_info *version = b_v;\n+\t  for (; version; version = version->next)\n+\t    if (!distinct_version_decls (version->this_node->decl, x))\n+\t      {\n+\t\t/* The decls define overlapping version, so attempt to merge\n+\t\t   or diagnose the conflict.  */\n+\t\tif (duplicate_decls (x, version->this_node->decl))\n+\t\t  return version->this_node->decl;\n+\t\telse\n+\t\t  return error_mark_node;\n+\t      }\n+\n+\t  /* This is a new version to be added to FMV structure.  */\n+\t  cgraph_node::add_function_version (b_v, x);\n+\n+\t  /* Get the first node from the structure.  */\n+\t  cgraph_function_version_info *default_v = b_v;\n+\t  while (default_v->prev)\n+\t    default_v = default_v->prev;\n+\t  /* Always use the default node for the bindings.  */\n+\t  b_use->decl = default_v->this_node->decl;\n+\t  b->decl = default_v->this_node->decl;\n+\n+\t  /* Node is not a duplicate, so no need to do the rest of the\n+\t     checks.  */\n+\t  return x;\n+\t}\n+\n       if (duplicate_decls (x, b_use->decl))\n \t{\n \t  if (b_use != b)\n@@ -4497,6 +4580,12 @@ tree\n lookup_name (tree name)\n {\n   struct c_binding *b = I_SYMBOL_BINDING (name);\n+  /* Do not resolve non-default function versions.  */\n+  if (b\n+      && TREE_CODE (b->decl) == FUNCTION_DECL\n+      && DECL_FUNCTION_VERSIONED (b->decl)\n+      && !is_function_default_version (b->decl))\n+    return NULL_TREE;\n   if (b && !b->invisible)\n     {\n       maybe_record_typedef_use (b->decl);\n@@ -5771,6 +5860,17 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,\n       && VAR_OR_FUNCTION_DECL_P (decl))\n       objc_check_global_decl (decl);\n \n+  /* To enable versions to be created across TU's we mark and mangle all\n+     non-default versioned functions.  */\n+  if (TREE_CODE (decl) == FUNCTION_DECL\n+      && !TARGET_HAS_FMV_TARGET_ATTRIBUTE\n+      && get_target_version (decl).is_valid ())\n+    {\n+      maybe_mark_function_versioned (decl);\n+      if (current_scope != file_scope)\n+\terror (\"versioned declarations are only allowed at file scope\");\n+    }\n+\n   /* Add this decl to the current scope.\n      TEM may equal DECL or it may be a previous decl of the same name.  */\n   if (do_push)\n@@ -10732,6 +10832,17 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,\n       warn_parm_array_mismatch (origloc, old_decl, parms);\n     }\n \n+  /* To enable versions to be created across TU's we mark and mangle all\n+     non-default versioned functions.  */\n+  if (TREE_CODE (decl1) == FUNCTION_DECL\n+      && !TARGET_HAS_FMV_TARGET_ATTRIBUTE\n+      && get_target_version (decl1).is_valid ())\n+    {\n+      maybe_mark_function_versioned (decl1);\n+      if (current_scope != file_scope)\n+\terror (\"versioned definitions are only allowed at file scope\");\n+    }\n+\n   /* Record the decl so that the function name is defined.\n      If we already have a decl for this name, and it is a FUNCTION_DECL,\n      use the old decl.  */\n@@ -13578,6 +13689,10 @@ c_parse_final_cleanups (void)\n     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));\n   c_write_global_declarations_1 (BLOCK_VARS (ext_block));\n \n+  /* Call this to set cpp_implicit_aliases_done on all nodes.  This is\n+     important for function multiversioning aliases to get resolved.  */\n+  symtab->process_same_body_aliases ();\n+\n   if (!in_lto_p)\n     free_attr_access_data ();\n \ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-1.c b/gcc/testsuite/gcc.target/aarch64/mv-1.c\nnew file mode 100644\nindex 000000000000..6f095ecd7a73\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-1.c\n@@ -0,0 +1,43 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"rng\"))) int\n+foo ()\n+{\n+  return 2;\n+}\n+\n+__attribute__ ((target_version (\"flagm\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+\n+__attribute__ ((target_version (\"rng+flagm\"))) int\n+foo ()\n+{\n+  return 4;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* Check usage of the first two FMV features, in case of off-by-one errors.  */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mrng:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MrngMflagm:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mflagm:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c\nnew file mode 100644\nindex 000000000000..39ed306eec25\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c\n@@ -0,0 +1,37 @@\n+/* { dg-do compile } */\n+/* { dg-require-ifunc \"\" } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__((target_version(\"default\")))\n+int foo ()\n+{\n+  return 0;\n+}\n+\n+__attribute__((target_clones(\"dotprod\", \"sve+sve2\")))\n+int foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__((target_clones(\"sve\", \"sve2\")))\n+int foo ()\n+{\n+  return 2;\n+}\n+\n+int bar()\n+{\n+  return foo ();\n+}\n+\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c\nnew file mode 100644\nindex 000000000000..17c7cbdd02da\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c\n@@ -0,0 +1,28 @@\n+/* { dg-do compile } */\n+/* { dg-require-ifunc \"\" } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__((target_version(\"default\")))\n+int foo ();\n+\n+__attribute__((target_clones(\"dotprod\", \"sve+sve2\")))\n+int foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__((target_clones(\"sve\", \"sve2\")))\n+int foo ()\n+{\n+  return 2;\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c\nnew file mode 100644\nindex 000000000000..8325c8e06999\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c\n@@ -0,0 +1,40 @@\n+/* { dg-do compile } */\n+/* { dg-require-ifunc \"\" } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__((target_clones(\"dotprod\", \"sve+sve2\")))\n+int foo ();\n+\n+__attribute__((target_version(\"default\")))\n+int foo ()\n+{\n+  return 0;\n+}\n+\n+__attribute__((target_clones(\"sve\", \"sve2\")))\n+int foo ()\n+{\n+  return 2;\n+}\n+\n+int bar()\n+{\n+  return foo ();\n+}\n+\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\n+// { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\.default\\n\" 1 } }\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\._MsveMsve2\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\._Msve\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\._Msve2\\n\" 1 } } */\n+\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c\nnew file mode 100644\nindex 000000000000..951c9500d747\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c\n@@ -0,0 +1,37 @@\n+/* { dg-do compile } */\n+/* { dg-require-ifunc \"\" } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__((target_version(\"dotprod\")))\n+int foo ()\n+{\n+  return 0;\n+}\n+\n+__attribute__((target_clones(\"default\", \"sve+sve2\")))\n+int foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__((target_clones(\"sve\", \"sve2\")))\n+int foo ()\n+{\n+  return 2;\n+}\n+\n+int bar()\n+{\n+  return foo ();\n+}\n+\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Msve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c\nnew file mode 100644\nindex 000000000000..798227826e50\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c\n@@ -0,0 +1,38 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// Basic case of fmv correctness with all functions and use in one TU.\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* When updating any of the symbol names in these tests, make sure to also\n+   update any tests for their absence in mv-symbolsN.C */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c\nnew file mode 100644\nindex 000000000000..d5256389d7bb\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c\n@@ -0,0 +1,42 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+int\n+foo ();\n+\n+int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._MsveMsve2\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c\nnew file mode 100644\nindex 000000000000..fd3dc345a599\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c\n@@ -0,0 +1,16 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// Check that types can be combined\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo (int a, int (*b)[4]) { return 1; }\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo (int a, int (*b)[]) { return 3; }\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c\nnew file mode 100644\nindex 000000000000..1a0b667eb5f1\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c\n@@ -0,0 +1,27 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo () { return 1; }\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo () { return 3; }\n+\n+int bar ()\n+{\n+  int (*test)() = foo;\n+\n+  test();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\], foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\], foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c\nnew file mode 100644\nindex 000000000000..308dace64a78\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c\n@@ -0,0 +1,28 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ();\n+\n+int bar ()\n+{\n+  int (*test)() = foo;\n+\n+  test();\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo () { return 3; }\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\], foo\\._Mdotprod\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\], foo\\.default\\n\" 0 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx\\[0-9\\]+, foo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\n+\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c\nnew file mode 100644\nindex 000000000000..d1af69fe31d9\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c\n@@ -0,0 +1,34 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+int foo ();\n+\n+__attribute__ ((target_version (\"default\")))  int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c\nnew file mode 100644\nindex 000000000000..a8732caf2140\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c\n@@ -0,0 +1,28 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// FMV correctness with definitions but no call\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c\nnew file mode 100644\nindex 000000000000..962bae935773\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c\n@@ -0,0 +1,27 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// FMV correctness with declarations but no implementation\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ();\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c\nnew file mode 100644\nindex 000000000000..a476800b2c53\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c\n@@ -0,0 +1,31 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// FMV correctness with a default implementation and declarations of other\n+// versions\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ();\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c\nnew file mode 100644\nindex 000000000000..4df20009f795\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c\n@@ -0,0 +1,36 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+// FMV correctness with default declaration, and implementations of other\n+// versions.\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* When updating any of the symbol names in these tests, make sure to also\n+   update any tests for their absence in mvc-symbolsN.C */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c\nnew file mode 100644\nindex 000000000000..cbf8bcaf8e16\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c\n@@ -0,0 +1,20 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+int bar()\n+{\n+  return foo();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"bl\\tfoo.default\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \".global\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \".set\\tfoo,foo.default\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c\nnew file mode 100644\nindex 000000000000..2ea4d2ebf0fb\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c\n@@ -0,0 +1,47 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ();\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._MsveMsve2\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c\nnew file mode 100644\nindex 000000000000..3e3eaf21aa9e\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c\n@@ -0,0 +1,47 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"default\"))) int\n+foo ();\n+\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"default\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._MsveMsve2\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c\nnew file mode 100644\nindex 000000000000..8e0864f1663f\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c\n@@ -0,0 +1,44 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ();\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ();\n+\n+int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+__attribute__ ((target_version (\"dotprod\"))) int\n+foo ()\n+{\n+  return 3;\n+}\n+__attribute__ ((target_version (\"sve+sve2\"))) int\n+foo ()\n+{\n+  return 5;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._MsveMsve2\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\._Mdotprod\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tadrp\\tx., foo\\.default\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c\nnew file mode 100644\nindex 000000000000..3ad15e5bb73d\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c\n@@ -0,0 +1,25 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_clones (\"default\", \"dotprod\", \"sve+sve2\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* When updating any of the symbol names in these tests, make sure to also\n+   update any tests for their absence in mvc-symbolsN.C */\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c\nnew file mode 100644\nindex 000000000000..78385ed904bb\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c\n@@ -0,0 +1,15 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_clones (\"default\", \"dotprod\", \"sve+sve2\"))) int\n+foo ()\n+{\n+  return 1;\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 1 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c\nnew file mode 100644\nindex 000000000000..1cbe3fd08509\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c\n@@ -0,0 +1,19 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_clones (\"default\", \"dotprod\", \"sve+sve2\"))) int\n+foo ();\n+\n+int\n+bar ()\n+{\n+  return foo ();\n+}\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\tbl\\tfoo\\n\" 1 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\ndiff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c\nnew file mode 100644\nindex 000000000000..abaf60f91c3e\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c\n@@ -0,0 +1,12 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O0\" } */\n+\n+__attribute__ ((target_clones (\"default\", \"dotprod\", \"sve+sve2\"))) int\n+foo ();\n+\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.default:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._Mdotprod:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\._MsveMsve2:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\nfoo\\.resolver:\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.type\\tfoo, %gnu_indirect_function\\n\" 0 } } */\n+/* { dg-final { scan-assembler-times \"\\n\\t\\.set\\tfoo,foo\\.resolver\\n\" 0 } } */\n",
    "prefixes": [
        "v1",
        "11/13"
    ]
}