[clang] [flang] [llvm] Re-land: "[AArch64] Add ability to list extensions enabled for a target" (#95805) (PR #96795)

Lucas Duarte Prates via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 26 09:33:07 PDT 2024


https://github.com/pratlucas created https://github.com/llvm/llvm-project/pull/96795

This introduces the new `--print-enabled-extensions` command line option
to AArch64, which prints the list of extensions that are enabled for the
target specified by the combination of `--target`/`-march`/`-mcpu`
values.

The goal of the this option is both to enable the manual inspection of
the enabled extensions by users and to enhance the testability of
architecture versions and CPU targets implemented in the compiler.

As part of this change, a new field for `FEAT_*` architecture feature
names was added to the TableGen entries. The output of the existing
`--print-supported-extensions` option was updated accordingly to show
these in a separate column.


>From e615f1b5cb86615673377ed1e05498b5b03da908 Mon Sep 17 00:00:00 2001
From: Lucas Duarte Prates <lucas.prates at arm.com>
Date: Wed, 26 Jun 2024 14:28:26 +0100
Subject: [PATCH] Re-land: "[AArch64] Add ability to list extensions enabled
 for a target" (#95805)

This introduces the new `--print-enabled-extensions` command line option
to AArch64, which prints the list of extensions that are enabled for the
target specified by the combination of `--target`/`-march`/`-mcpu`
values.

The goal of the this option is both to enable the manual inspection of
the enabled extensions by users and to enhance the testability of
architecture versions and CPU targets implemented in the compiler.

As part of this change, a new field for `FEAT_*` architecture feature
names was added to the TableGen entries. The output of the existing
`--print-supported-extensions` option was updated accordingly to show
these in a separate column.
---
 clang/include/clang/Driver/Options.td         |   5 +
 .../include/clang/Frontend/FrontendOptions.h  |   4 +
 clang/lib/Driver/Driver.cpp                   |  19 +-
 clang/lib/Driver/ToolChain.cpp                |   8 +-
 clang/lib/Driver/ToolChains/Clang.cpp         |   2 +-
 clang/test/CodeGen/aarch64-targetattr.c       |   8 +-
 clang/test/Driver/aarch64-fp16.c              |  78 +--
 clang/test/Driver/aarch64-sve2.c              |   2 +-
 clang/test/Driver/aarch64-v81a.c              |  14 +
 clang/test/Driver/aarch64-v82a.c              |  18 +
 clang/test/Driver/aarch64-v83a.c              |  23 +
 clang/test/Driver/aarch64-v84a.c              |  34 ++
 clang/test/Driver/aarch64-v85a.c              |  42 ++
 clang/test/Driver/aarch64-v86a.c              |  47 ++
 clang/test/Driver/aarch64-v87a.c              |  50 ++
 clang/test/Driver/aarch64-v88a.c              |  53 ++
 clang/test/Driver/aarch64-v89a.c              |  59 ++
 clang/test/Driver/aarch64-v8a.c               |  29 +
 clang/test/Driver/aarch64-v91a.c              |  52 ++
 clang/test/Driver/aarch64-v92a.c              |  55 ++
 clang/test/Driver/aarch64-v93a.c              |  58 ++
 clang/test/Driver/aarch64-v94a.c              |  64 +++
 clang/test/Driver/aarch64-v95a.c              |  67 +++
 clang/test/Driver/aarch64-v9a.c               |  62 ++
 .../test/Driver/print-supported-extensions.c  |   4 +-
 .../Preprocessor/aarch64-target-features.c    |  52 +-
 clang/tools/driver/cc1_main.cpp               |  46 +-
 flang/test/Driver/target-cpu-features.f90     |   4 +-
 llvm/include/llvm/MC/MCSubtargetInfo.h        |   3 +
 .../llvm/TargetParser/AArch64TargetParser.h   |  23 +-
 llvm/lib/MC/MCSubtargetInfo.cpp               |  10 +
 llvm/lib/Target/AArch64/AArch64Features.td    | 542 +++++++++---------
 llvm/lib/TargetParser/AArch64TargetParser.cpp |  60 +-
 .../TargetParser/TargetParserTest.cpp         | 113 ++--
 llvm/utils/TableGen/ARMTargetDefEmitter.cpp   |  14 +-
 35 files changed, 1302 insertions(+), 422 deletions(-)
 create mode 100644 clang/test/Driver/aarch64-v8a.c
 create mode 100644 clang/test/Driver/aarch64-v9a.c

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index dd55838dcf384..724cf3351b88c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5710,6 +5710,11 @@ def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">
   Visibility<[ClangOption, CC1Option, CLOption]>,
   HelpText<"Print supported -march extensions (RISC-V, AArch64 and ARM only)">,
   MarshallingInfoFlag<FrontendOpts<"PrintSupportedExtensions">>;
+def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">,
+  Visibility<[ClangOption, CC1Option, CLOption]>,
+  HelpText<"Print the extensions enabled by the given target and -march/-mcpu options."
+           " (AArch64 only)">,
+  MarshallingInfoFlag<FrontendOpts<"PrintEnabledExtensions">>;
 def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
 def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
 def time : Flag<["-"], "time">,
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index ebb8e9e59c6b6..5e5034fe01eb5 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -306,6 +306,10 @@ class FrontendOptions {
   LLVM_PREFERRED_TYPE(bool)
   unsigned PrintSupportedExtensions : 1;
 
+  /// Print the extensions enabled for the current target.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned PrintEnabledExtensions : 1;
+
   /// Show the -version text.
   LLVM_PREFERRED_TYPE(bool)
   unsigned ShowVersion : 1;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 6823f5424cef0..8fa8673b0fd69 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -363,6 +363,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
     // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
   } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
@@ -2163,7 +2164,8 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
   if (C.getArgs().hasArg(options::OPT_v) ||
       C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
       C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
-      C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
+      C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
+      C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
     PrintVersion(C, llvm::errs());
     SuppressMissingInputWarning = true;
   }
@@ -4347,13 +4349,14 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
   }
 
   for (auto Opt : {options::OPT_print_supported_cpus,
-                   options::OPT_print_supported_extensions}) {
+                   options::OPT_print_supported_extensions,
+                   options::OPT_print_enabled_extensions}) {
     // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a
     // custom Compile phase that prints out supported cpu models and quits.
     //
-    // If --print-supported-extensions is specified, call the helper function
-    // RISCVMarchHelp in RISCVISAInfo.cpp that prints out supported extensions
-    // and quits.
+    // If either --print-supported-extensions or --print-enabled-extensions is
+    // specified, call the corresponding helper function that prints out the
+    // supported/enabled extensions and quits.
     if (Arg *A = Args.getLastArg(Opt)) {
       if (Opt == options::OPT_print_supported_extensions &&
           !C.getDefaultToolChain().getTriple().isRISCV() &&
@@ -4363,6 +4366,12 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
             << "--print-supported-extensions";
         return;
       }
+      if (Opt == options::OPT_print_enabled_extensions &&
+          !C.getDefaultToolChain().getTriple().isAArch64()) {
+        C.getDriver().Diag(diag::err_opt_not_valid_on_target)
+            << "--print-enabled-extensions";
+        return;
+      }
 
       // Use the -mcpu=? flag as the dummy input to cc1.
       Actions.clear();
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 40ab2e91125d1..8f4cc47e418b5 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -195,11 +195,11 @@ static void getAArch64MultilibFlags(const Driver &D,
                                        UnifiedFeatures.end());
   std::vector<std::string> MArch;
   for (const auto &Ext : AArch64::Extensions)
-    if (FeatureSet.contains(Ext.Feature))
-      MArch.push_back(Ext.Name.str());
+    if (FeatureSet.contains(Ext.PosTargetFeature))
+      MArch.push_back(Ext.UserVisibleName.str());
   for (const auto &Ext : AArch64::Extensions)
-    if (FeatureSet.contains(Ext.NegFeature))
-      MArch.push_back(("no" + Ext.Name).str());
+    if (FeatureSet.contains(Ext.NegTargetFeature))
+      MArch.push_back(("no" + Ext.UserVisibleName).str());
   StringRef ArchName;
   for (const auto &ArchInfo : AArch64::ArchInfos)
     if (FeatureSet.contains(ArchInfo->ArchFeature))
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c0f6bc0c2e45a..1b7cc82ea816e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1524,7 +1524,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
       auto isPAuthLR = [](const char *member) {
         llvm::AArch64::ExtensionInfo pauthlr_extension =
             llvm::AArch64::getExtensionByID(llvm::AArch64::AEK_PAUTHLR);
-        return pauthlr_extension.Feature == member;
+        return pauthlr_extension.PosTargetFeature == member;
       };
 
       if (std::any_of(CmdArgs.begin(), CmdArgs.end(), isPAuthLR))
diff --git a/clang/test/CodeGen/aarch64-targetattr.c b/clang/test/CodeGen/aarch64-targetattr.c
index 7aabecd1c07b8..e4e0ae7b66afc 100644
--- a/clang/test/CodeGen/aarch64-targetattr.c
+++ b/clang/test/CodeGen/aarch64-targetattr.c
@@ -196,14 +196,14 @@ void minusarch() {}
 // CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+v8.1a,+v8.2a,+v8a" }
 // CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+sve2,+v8.1a,+v8.2a,+v8a" }
 // CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" }
-// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a710" "target-features"="+bf16,+complxnum,+crc,+dotprod,+flagm,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+mte,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sb,+sve,+sve2,+sve2-bitperm,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+v9a" }
+// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a710" "target-features"="+bf16,+complxnum,+crc,+dotprod,+ete,+flagm,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+mte,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sb,+sve,+sve2,+sve2-bitperm,+trbe,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+v9a" }
 // CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "tune-cpu"="cortex-a710" }
-// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a" }
+// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+ete,+fp-armv8,+neon,+trbe,+v8a" }
 // CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "tune-cpu"="generic" }
 // CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+crc,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+v8.1a,+v8.2a,+v8a" "tune-cpu"="cortex-a710" }
 // CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+sve" "tune-cpu"="cortex-a710" }
-// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
-// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,-sve" }
+// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
+// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,-sve" }
 // CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+sve" }
 // CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16" }
 // CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
diff --git a/clang/test/Driver/aarch64-fp16.c b/clang/test/Driver/aarch64-fp16.c
index 4da1834cf6876..72ccd79850148 100644
--- a/clang/test/Driver/aarch64-fp16.c
+++ b/clang/test/Driver/aarch64-fp16.c
@@ -21,7 +21,7 @@
 
 // RUN: %clang --target=aarch64 -march=armv8a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-FP16FML %s
-// GENERICV8A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV8A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16FML %s
@@ -35,11 +35,11 @@
 // GENERICV82A-FP16-SAME: {{$}}
 
 // RUN: %clang --target=aarch64 -march=armv8.2-a+profile -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-SPE %s
-// GENERICV82A-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+spe"{{.*}} "-target-feature" "+neon"
+// GENERICV82A-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+neon"{{.*}} "-target-feature" "+spe"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16FML %s
-// GENERICV82A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV82A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16-NO-FP16FML %s
@@ -51,15 +51,15 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16FML-NO-FP16 %s
-// GENERICV82A-FP16FML-NO-FP16: "-target-feature" "-fullfp16"{{.*}} "-target-feature" "-fp16fml"
+// GENERICV82A-FP16FML-NO-FP16: "-target-feature" "-fp16fml"{{.*}} "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16-FP16FML %s
-// GENERICV82A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV82A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+fp16+profile -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16-SPE %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+fp16+profile -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16-SPE %s
-// GENERICV82A-FP16-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.2a"{{.*}}  "-target-feature" "+fullfp16"{{.*}} "-target-feature" "+spe"{{.*}} "-target-feature" "+neon"
+// GENERICV82A-FP16-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.2a"{{.*}}  "-target-feature" "+fullfp16"{{.*}} "-target-feature" "+neon"{{.*}} "-target-feature" "+spe"
 // GENERICV82A-FP16-SPE-NOT:  "-target-feature" "{{[+-]}}fp16fml"
 // GENERICV82A-FP16-SPE-SAME: {{$}}
 
@@ -74,7 +74,7 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16FML %s
-// GENERICV83A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV83A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16-NO-FP16FML %s
@@ -88,11 +88,11 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16FML-NO-FP16 %s
-// GENERICV83A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV83A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-NO-FP16-FP16FML %s
-// GENERICV83A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV83A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16FML %s
@@ -101,27 +101,27 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16 %s
-// GENERICV84A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV84A-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16FML %s
-// GENERICV84A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV84A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16-NO-FP16FML %s
-// GENERICV84A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV84A-FP16-NO-FP16FML: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16FML-FP16 %s
-// GENERICV84A-NO-FP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV84A-NO-FP16FML-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16FML-NO-FP16 %s
-// GENERICV84A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV84A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.4a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.4-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16-FP16FML %s
-// GENERICV84A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV84A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML %s
@@ -130,27 +130,27 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16 %s
-// GENERICV85A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV85A-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML %s
-// GENERICV85A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV85A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16-NO-FP16FML %s
-// GENERICV85A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV85A-FP16-NO-FP16FML: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML-FP16 %s
-// GENERICV85A-NO-FP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV85A-NO-FP16FML-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML-NO-FP16 %s
-// GENERICV85A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV85A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.5a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.5-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16-FP16FML %s
-// GENERICV85A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV85A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16FML %s
@@ -159,27 +159,27 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16 %s
-// GENERICV86A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV86A-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16FML %s
-// GENERICV86A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV86A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16-NO-FP16FML %s
-// GENERICV86A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV86A-FP16-NO-FP16FML: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16FML-FP16 %s
-// GENERICV86A-NO-FP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV86A-NO-FP16FML-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-FP16FML-NO-FP16 %s
-// GENERICV86A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV86A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.6a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.6-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-NO-FP16-FP16FML %s
-// GENERICV86A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV86A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16FML %s
@@ -188,27 +188,27 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16 %s
-// GENERICV87A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV87A-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16FML %s
-// GENERICV87A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV87A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16-NO-FP16FML %s
-// GENERICV87A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV87A-FP16-NO-FP16FML: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16FML-FP16 %s
-// GENERICV87A-NO-FP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV87A-NO-FP16FML-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-FP16FML-NO-FP16 %s
-// GENERICV87A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV87A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.7a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.7-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-NO-FP16-FP16FML %s
-// GENERICV87A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV87A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16FML %s
@@ -217,24 +217,24 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16 %s
-// GENERICV88A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV88A-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16FML %s
-// GENERICV88A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV88A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16-NO-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16-NO-FP16FML %s
-// GENERICV88A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV88A-FP16-NO-FP16FML: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16FML-FP16 %s
-// GENERICV88A-NO-FP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV88A-NO-FP16FML-FP16: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16FML-NO-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-FP16FML-NO-FP16 %s
-// GENERICV88A-FP16FML-NO-FP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
+// GENERICV88A-FP16FML-NO-FP16: "-target-feature" "-fp16fml" "-target-feature" "-fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.8a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16-FP16FML %s
 // RUN: %clang --target=aarch64 -march=armv8.8-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-NO-FP16-FP16FML %s
-// GENERICV88A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+// GENERICV88A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
diff --git a/clang/test/Driver/aarch64-sve2.c b/clang/test/Driver/aarch64-sve2.c
index c801f44d3cb84..389c3a52bde44 100644
--- a/clang/test/Driver/aarch64-sve2.c
+++ b/clang/test/Driver/aarch64-sve2.c
@@ -5,4 +5,4 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv9-a+nosve2 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-NOSVE2 %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9a+nosve2 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-NOSVE2 %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9-a+nosve2 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-NOSVE2 %s
-// GENERICV9A-NOSVE2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9a"{{.*}} "-target-feature" "+neon" "-target-feature" "+sve" "-target-feature" "-sve2"
+// GENERICV9A-NOSVE2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9a"{{.*}} "-target-feature" "+neon"{{.*}} "-target-feature" "+sve" "-target-feature" "-sve2"
diff --git a/clang/test/Driver/aarch64-v81a.c b/clang/test/Driver/aarch64-v81a.c
index e84652ec7f11e..f3873b3ab1864 100644
--- a/clang/test/Driver/aarch64-v81a.c
+++ b/clang/test/Driver/aarch64-v81a.c
@@ -19,3 +19,17 @@
 // RUN: %clang --target=arm64 -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s
 // RUN: %clang --target=arm64 -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s
 // ARM64-GENERICV81A: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.1a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.1-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v82a.c b/clang/test/Driver/aarch64-v82a.c
index 9dd355934c105..318c270cad396 100644
--- a/clang/test/Driver/aarch64-v82a.c
+++ b/clang/test/Driver/aarch64-v82a.c
@@ -13,3 +13,21 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
 // GENERICV82A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.2-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v83a.c b/clang/test/Driver/aarch64-v83a.c
index b0ff9fb3abc24..f35c500ee0a9b 100644
--- a/clang/test/Driver/aarch64-v83a.c
+++ b/clang/test/Driver/aarch64-v83a.c
@@ -13,3 +13,26 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
 // GENERICV83A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.3a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.3-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v84a.c b/clang/test/Driver/aarch64-v84a.c
index 030990bfe5131..d72c79fc14cec 100644
--- a/clang/test/Driver/aarch64-v84a.c
+++ b/clang/test/Driver/aarch64-v84a.c
@@ -13,3 +13,37 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
 // GENERICV84A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.4a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.4-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v85a.c b/clang/test/Driver/aarch64-v85a.c
index 3e1e921dcc013..06c0989bc8e9b 100644
--- a/clang/test/Driver/aarch64-v85a.c
+++ b/clang/test/Driver/aarch64-v85a.c
@@ -13,3 +13,45 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BE %s
 // GENERICV85A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.5a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.5-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v86a.c b/clang/test/Driver/aarch64-v86a.c
index ba2b57979b518..04d372e762a37 100644
--- a/clang/test/Driver/aarch64-v86a.c
+++ b/clang/test/Driver/aarch64-v86a.c
@@ -13,3 +13,50 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-BE %s
 // GENERICV86A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.6a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.6-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v87a.c b/clang/test/Driver/aarch64-v87a.c
index ee4b68882739a..b385e7cfb2ad6 100644
--- a/clang/test/Driver/aarch64-v87a.c
+++ b/clang/test/Driver/aarch64-v87a.c
@@ -13,3 +13,53 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s
 // GENERICV87A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.7a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.7-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v88a.c b/clang/test/Driver/aarch64-v88a.c
index b680c1f567134..438796b91fff6 100644
--- a/clang/test/Driver/aarch64-v88a.c
+++ b/clang/test/Driver/aarch64-v88a.c
@@ -13,3 +13,56 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-BE %s
 // GENERICV88A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.8a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.8-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HBC
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MOPS
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NMI, FEAT_GICv3_NMI
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v89a.c b/clang/test/Driver/aarch64-v89a.c
index 903b793d046ba..42bcb127cd3bd 100644
--- a/clang/test/Driver/aarch64-v89a.c
+++ b/clang/test/Driver/aarch64-v89a.c
@@ -12,3 +12,62 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // GENERICV89A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.9a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8.9-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CHK
+// ARCH-EXTENSION: FEAT_CLRBHB
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSSC
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HBC
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MOPS
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NMI, FEAT_GICv3_NMI
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_PRFMSLC
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RASv2
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SPECRES2
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v8a.c b/clang/test/Driver/aarch64-v8a.c
new file mode 100644
index 0000000000000..a3b01560b22a6
--- /dev/null
+++ b/clang/test/Driver/aarch64-v8a.c
@@ -0,0 +1,29 @@
+// RUN: %clang --target=aarch64_be -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// RUN: %clang --target=aarch64_be -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// RUN: %clang --target=aarch64 -mbig-endian -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// RUN: %clang --target=aarch64 -mbig-endian -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// RUN: %clang --target=aarch64_be -mbig-endian -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// RUN: %clang --target=aarch64_be -mbig-endian -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-BE %s
+// GENERICV8A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8a"{{.*}} "-target-feature" "+neon"
+
+// RUN: %clang --target=aarch64 -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// RUN: %clang --target=aarch64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// RUN: %clang --target=aarch64 -mlittle-endian -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// RUN: %clang --target=aarch64 -mlittle-endian -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A %s
+// GENERICV8A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+v8a"{{.*}} "-target-feature" "+neon"{{.*}}
+
+// RUN: %clang --target=arm64 -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV8A %s
+// RUN: %clang --target=arm64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV8A %s
+// RUN: %clang --target=arm64 -mlittle-endian -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV8A %s
+// RUN: %clang --target=arm64 -mlittle-endian -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV8A %s
+// ARM64-GENERICV8A: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8a"{{.*}} "-target-feature" "+neon"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv8-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_TRBE
diff --git a/clang/test/Driver/aarch64-v91a.c b/clang/test/Driver/aarch64-v91a.c
index 80853a59d0153..c5667f8fb3bcd 100644
--- a/clang/test/Driver/aarch64-v91a.c
+++ b/clang/test/Driver/aarch64-v91a.c
@@ -13,3 +13,55 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A-BE %s
 // GENERICV91A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.1a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9.1-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/aarch64-v92a.c b/clang/test/Driver/aarch64-v92a.c
index ee644cc6f3c62..6088a69312dc4 100644
--- a/clang/test/Driver/aarch64-v92a.c
+++ b/clang/test/Driver/aarch64-v92a.c
@@ -13,3 +13,58 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
 // GENERICV92A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.2a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9.2-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v93a.c b/clang/test/Driver/aarch64-v93a.c
index 817559e28ccf4..5db3034078ea8 100644
--- a/clang/test/Driver/aarch64-v93a.c
+++ b/clang/test/Driver/aarch64-v93a.c
@@ -13,3 +13,61 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s
 // GENERICV93A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.3a"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9.3-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HBC
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MOPS
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NMI, FEAT_GICv3_NMI
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v94a.c b/clang/test/Driver/aarch64-v94a.c
index 9998cc8a4a216..d9f991fc95d3d 100644
--- a/clang/test/Driver/aarch64-v94a.c
+++ b/clang/test/Driver/aarch64-v94a.c
@@ -13,3 +13,67 @@
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv9.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A-BE %s
 // GENERICV94A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.4a"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9.4-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CHK
+// ARCH-EXTENSION: FEAT_CLRBHB
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSSC
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HBC
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MOPS
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NMI, FEAT_GICv3_NMI
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_PRFMSLC
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RASv2
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SPECRES2
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 62878f2127626..e3e97d2bef13f 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -25,3 +25,70 @@
 // RUN: %clang -target aarch64 -march=armv9.5a+tlbiw -### -c %s 2>&1 | FileCheck -check-prefix=V95A-TLBIW %s
 // RUN: %clang -target aarch64 -march=armv9.5-a+tlbiw -### -c %s 2>&1 | FileCheck -check-prefix=V95A-TLBIW %s
 // V95A-TLBIW: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+tlbiw"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9.5-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AMUv1p1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BF16
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CHK
+// ARCH-EXTENSION: FEAT_CLRBHB
+// ARCH-EXTENSION: FEAT_CPA
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSSC
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ECV
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FAMINMAX
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FGT
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_HBC
+// ARCH-EXTENSION: FEAT_HCX
+// ARCH-EXTENSION: FEAT_I8MM
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_LUT
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MOPS
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NMI, FEAT_GICv3_NMI
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_PRFMSLC
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RASv2
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SPECRES2
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
+// ARCH-EXTENSION: FEAT_WFxT
+// ARCH-EXTENSION: FEAT_XS
diff --git a/clang/test/Driver/aarch64-v9a.c b/clang/test/Driver/aarch64-v9a.c
new file mode 100644
index 0000000000000..f85e1c409010d
--- /dev/null
+++ b/clang/test/Driver/aarch64-v9a.c
@@ -0,0 +1,62 @@
+// RUN: %clang --target=aarch64 -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// RUN: %clang --target=aarch64 -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// RUN: %clang --target=aarch64 -mlittle-endian -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// RUN: %clang --target=aarch64 -mlittle-endian -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A %s
+// GENERICV9A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
+
+// RUN: %clang --target=aarch64_be -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// RUN: %clang --target=aarch64_be -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// RUN: %clang --target=aarch64 -mbig-endian -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// RUN: %clang --target=aarch64 -mbig-endian -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// RUN: %clang --target=aarch64_be -mbig-endian -march=armv9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// RUN: %clang --target=aarch64_be -mbig-endian -march=armv9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-BE %s
+// GENERICV9A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
+
+// ===== Architecture extensions =====
+
+// RUN: %if aarch64-registered-target %{ %clang -target aarch64 -march=armv9-a --print-enabled-extensions | FileCheck -check-prefix=ARCH-EXTENSION --implicit-check-not FEAT_ %s %}
+// ARCH-EXTENSION: FEAT_AMUv1
+// ARCH-EXTENSION: FEAT_AdvSIMD
+// ARCH-EXTENSION: FEAT_BTI
+// ARCH-EXTENSION: FEAT_CCIDX
+// ARCH-EXTENSION: FEAT_CRC32
+// ARCH-EXTENSION: FEAT_CSV2_2
+// ARCH-EXTENSION: FEAT_DIT
+// ARCH-EXTENSION: FEAT_DPB
+// ARCH-EXTENSION: FEAT_DPB2
+// ARCH-EXTENSION: FEAT_DotProd
+// ARCH-EXTENSION: FEAT_ETE
+// ARCH-EXTENSION: FEAT_FCMA
+// ARCH-EXTENSION: FEAT_FP
+// ARCH-EXTENSION: FEAT_FP16
+// ARCH-EXTENSION: FEAT_FRINTTS
+// ARCH-EXTENSION: FEAT_FlagM
+// ARCH-EXTENSION: FEAT_FlagM2
+// ARCH-EXTENSION: FEAT_JSCVT
+// ARCH-EXTENSION: FEAT_LOR
+// ARCH-EXTENSION: FEAT_LRCPC
+// ARCH-EXTENSION: FEAT_LRCPC2
+// ARCH-EXTENSION: FEAT_LSE
+// ARCH-EXTENSION: FEAT_LSE2
+// ARCH-EXTENSION: FEAT_MEC
+// ARCH-EXTENSION: FEAT_MPAM
+// ARCH-EXTENSION: FEAT_NV, FEAT_NV2
+// ARCH-EXTENSION: FEAT_PAN
+// ARCH-EXTENSION: FEAT_PAN2
+// ARCH-EXTENSION: FEAT_PAuth
+// ARCH-EXTENSION: FEAT_RAS, FEAT_RASv1p1
+// ARCH-EXTENSION: FEAT_RDM
+// ARCH-EXTENSION: FEAT_RME
+// ARCH-EXTENSION: FEAT_SB
+// ARCH-EXTENSION: FEAT_SEL2
+// ARCH-EXTENSION: FEAT_SPECRES
+// ARCH-EXTENSION: FEAT_SSBS, FEAT_SSBS2
+// ARCH-EXTENSION: FEAT_SVE
+// ARCH-EXTENSION: FEAT_SVE2
+// ARCH-EXTENSION: FEAT_TLBIOS, FEAT_TLBIRANGE
+// ARCH-EXTENSION: FEAT_TRBE
+// ARCH-EXTENSION: FEAT_TRF
+// ARCH-EXTENSION: FEAT_UAO
+// ARCH-EXTENSION: FEAT_VHE
diff --git a/clang/test/Driver/print-supported-extensions.c b/clang/test/Driver/print-supported-extensions.c
index 17894fc0f7ee0..b9b16352f8295 100644
--- a/clang/test/Driver/print-supported-extensions.c
+++ b/clang/test/Driver/print-supported-extensions.c
@@ -4,8 +4,8 @@
 // RUN: %if aarch64-registered-target %{ %clang --target=aarch64-linux-gnu \
 // RUN:   --print-supported-extensions 2>&1 | FileCheck %s --check-prefix AARCH64 %}
 // AARCH64: All available -march extensions for AArch64
-// AARCH64:     Name                Description
-// AARCH64:     aes                 Enable AES support (FEAT_AES, FEAT_PMULL)
+// AARCH64:     Name                Architecture Feature(s)                                Description
+// AARCH64:     aes                 FEAT_AES, FEAT_PMULL                                   Enable AES support
 
 // RUN: %if riscv-registered-target %{ %clang --target=riscv64-linux-gnu \
 // RUN:   --print-supported-extensions 2>&1 | FileCheck %s --check-prefix RISCV %}
diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c
index 6f359461dea88..71cc36acf3f0e 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -315,37 +315,37 @@
 // RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-THUNDERX2T99 %s
 // RUN: %clang -target aarch64 -mcpu=a64fx -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-A64FX %s
 // RUN: %clang -target aarch64 -mcpu=carmel -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-CARMEL %s
-// CHECK-MCPU-APPLE-A7: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8a" "-target-feature" "+aes"{{.*}} "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-APPLE-A10: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8a" "-target-feature" "+aes"{{.*}} "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-APPLE-A11: "-cc1"{{.*}} "-triple" "aarch64{{.*}}"{{.*}}"-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-APPLE-A12: "-cc1"{{.*}} "-triple" "aarch64"{{.*}} "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.3a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-A34: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-APPLE-A13: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "apple-a13" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon"
-// CHECK-MCPU-A35: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-A53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-A57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-A72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-CORTEX-R82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8r" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+flagm" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+predres" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+neon" "-target-feature" "+ssbs"
-// CHECK-MCPU-M3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-M4: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-A64FX: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+sve"
-// CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
+// CHECK-MCPU-APPLE-A7: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-APPLE-A10: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lor" "-target-feature" "+neon" "-target-feature" "+pan" "-target-feature" "+perfmon" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+vh"
+// CHECK-MCPU-APPLE-A11: "-cc1"{{.*}} "-triple" "aarch64{{.*}}"{{.*}}"-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2"
+// CHECK-MCPU-APPLE-A12: "-cc1"{{.*}} "-triple" "aarch64"{{.*}} "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.3a" "-target-feature" "+aes" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2"
+// CHECK-MCPU-A34: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-APPLE-A13: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3"
+// CHECK-MCPU-A35: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-A53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-A57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-A72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-CORTEX-R82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8r" "-target-feature" "+ccdp" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+flagm" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+predres" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+ssbs"
+// CHECK-MCPU-M3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-M4: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2"
+// CHECK-MCPU-KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2"
+// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+rdm" "-target-feature" "+sha2
+// CHECK-MCPU-A64FX: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sve"
+// CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64 %s
-// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+predres" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon" "-target-feature" "+ssbs"
+// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+altnzcv" "-target-feature" "+ccdp" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+fptoint" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+predres" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+specrestrict" "-target-feature" "+ssbs"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64_32 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64_32 %s
-// CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.3a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
+// CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.3a" "-target-feature" "+aes" "-target-feature" "+complxnum" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+pauth" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2"
 
 // RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s
 // RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s
 // RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto -mabi=aapcs-soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s
 // RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto+nofp+nosimd+nocrc+nocrypto -mabi=aapcs-soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s
 // RUN: %clang -target aarch64 -march=armv8-a+nosimd -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-3 %s
-// CHECK-MARCH-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+sha2" "-target-feature" "+neon"
+// CHECK-MARCH-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+sha2"
 // CHECK-MARCH-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-fp-armv8"{{.*}} "-target-feature" "-neon"
 // CHECK-MARCH-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-neon"
 
@@ -463,8 +463,8 @@
 // RUN: %clang -target aarch64 -mcpu=GENERIC+nocrc+CRC -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-2 %s
 // RUN: %clang -target aarch64 -mcpu=cortex-a53+noSIMD -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-3 %s
 // CHECK-MCPU-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-aes"{{.*}} "-target-feature" "-sha2"
-// CHECK-MCPU-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon"
-// CHECK-MCPU-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "-aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "-sha2" "-target-feature" "-neon"
+// CHECK-MCPU-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc"{{.*}} "-target-feature" "+fp-armv8"{{.*}} "-target-feature" "+neon"
+// CHECK-MCPU-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "-aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "-neon" "-target-feature" "+perfmon" "-target-feature" "-sha2"
 
 // RUN: %clang -target aarch64 -mcpu=cyclone+nocrc+nocrypto -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MARCH %s
 // RUN: %clang -target aarch64 -march=armv8-a -mcpu=cyclone+nocrc+nocrypto  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MARCH %s
@@ -492,9 +492,9 @@
 // RUN: %clang -target aarch64 -march=ARMV8.1A+CRYPTO -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-1 %s
 // RUN: %clang -target aarch64 -march=Armv8.1a+NOcrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-2 %s
 // RUN: %clang -target aarch64 -march=armv8.1a+noSIMD -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-FEATURE-3 %s
-// CHECK-V81A-FEATURE-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
-// CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+neon"
-// CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "-rdm" "-target-feature" "-neon"
+// CHECK-V81A-FEATURE-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+rdm" "-target-feature" "+sha2"
+// CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+rdm"
+// CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "-neon" "-target-feature" "-rdm"
 
 // ================== Check Memory Tagging Extensions (MTE).
 // RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a+memtag -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MEMTAG %s
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 2aebc6d3c0178..3c0599c2e5149 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -26,6 +26,7 @@
 #include "clang/Frontend/Utils.h"
 #include "clang/FrontendTool/Utils.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/LinkAllPasses.h"
 #include "llvm/MC/MCSubtargetInfo.h"
@@ -148,7 +149,7 @@ static int PrintSupportedExtensions(std::string TargetStr) {
   if (MachineTriple.isRISCV())
     llvm::riscvExtensionsHelp(DescMap);
   else if (MachineTriple.isAArch64())
-    llvm::AArch64::PrintSupportedExtensions(DescMap);
+    llvm::AArch64::PrintSupportedExtensions();
   else if (MachineTriple.isARM())
     llvm::ARM::PrintSupportedExtensions(DescMap);
   else {
@@ -161,6 +162,45 @@ static int PrintSupportedExtensions(std::string TargetStr) {
   return 0;
 }
 
+static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
+  std::string Error;
+  const llvm::Target *TheTarget =
+      llvm::TargetRegistry::lookupTarget(TargetOpts.Triple, Error);
+  if (!TheTarget) {
+    llvm::errs() << Error;
+    return 1;
+  }
+
+  // Create a target machine using the input features, the triple information
+  // and a dummy instance of llvm::TargetOptions. Note that this is _not_ the
+  // same as the `clang::TargetOptions` instance we have access to here.
+  llvm::TargetOptions BackendOptions;
+  std::string FeaturesStr = llvm::join(TargetOpts.FeaturesAsWritten, ",");
+  std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
+      TheTarget->createTargetMachine(TargetOpts.Triple, TargetOpts.CPU, FeaturesStr, BackendOptions, std::nullopt));
+  const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple();
+  const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo();
+
+  // Extract the feature names that are enabled for the given target.
+  // We do that by capturing the key from the set of SubtargetFeatureKV entries
+  // provided by MCSubtargetInfo, which match the '-target-feature' values.
+  const std::vector<llvm::SubtargetFeatureKV> Features =
+    MCInfo->getEnabledProcessorFeatures();
+  std::set<llvm::StringRef> EnabledFeatureNames;
+  for (const llvm::SubtargetFeatureKV &feature : Features)
+    EnabledFeatureNames.insert(feature.Key);
+
+  if (!MachineTriple.isAArch64()) {
+    // The option was already checked in Driver::HandleImmediateArgs,
+    // so we do not expect to get here if we are not a supported architecture.
+    assert(0 && "Unhandled triple for --print-enabled-extensions option.");
+    return 1;
+  }
+  llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
+
+  return 0;
+}
+
 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   ensureSufficientStack();
 
@@ -204,6 +244,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   if (Clang->getFrontendOpts().PrintSupportedExtensions)
     return PrintSupportedExtensions(Clang->getTargetOpts().Triple);
 
+  // --print-enabled-extensions takes priority over the actual compilation.
+  if (Clang->getFrontendOpts().PrintEnabledExtensions)
+    return PrintEnabledExtensions(Clang->getTargetOpts());
+
   // Infer the builtin include path if unspecified.
   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
       Clang->getHeaderSearchOpts().ResourceDir.empty())
diff --git a/flang/test/Driver/target-cpu-features.f90 b/flang/test/Driver/target-cpu-features.f90
index eea7a0f665b34..e78c3516db45a 100644
--- a/flang/test/Driver/target-cpu-features.f90
+++ b/flang/test/Driver/target-cpu-features.f90
@@ -31,11 +31,11 @@
 
 ! CHECK-A57: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
 ! CHECK-A57-SAME: "-target-cpu" "cortex-a57"
-! CHECK-A57-SAME: "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
+! CHECK-A57-SAME: "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+sha2
 
 ! CHECK-A76: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
 ! CHECK-A76-SAME: "-target-cpu" "cortex-a76"
-! CHECK-A76-SAME: "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+ssbs"
+! CHECK-A76-SAME: "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+neon" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+ssbs"
 
 ! CHECK-ARMV9: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
 ! CHECK-ARMV9-SAME: "-target-cpu" "generic"
diff --git a/llvm/include/llvm/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h
index ff76435d60843..deb7e2fd1c360 100644
--- a/llvm/include/llvm/MC/MCSubtargetInfo.h
+++ b/llvm/include/llvm/MC/MCSubtargetInfo.h
@@ -240,6 +240,9 @@ class MCSubtargetInfo {
     return ProcFeatures;
   }
 
+  /// Return the list of processor features currently enabled.
+  std::vector<SubtargetFeatureKV> getEnabledProcessorFeatures() const;
+
   /// HwMode IDs are stored and accessed in a bit set format, enabling
   /// users to efficiently retrieve specific IDs, such as the RegInfo
   /// HwMode ID, from the set as required. Using this approach, various
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index a40bca9563cdd..693759a1ccd82 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -22,6 +22,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include <array>
+#include <set>
 #include <vector>
 
 namespace llvm {
@@ -116,12 +117,18 @@ using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
 // SubtargetFeature which may represent either an actual extension or some
 // internal LLVM property.
 struct ExtensionInfo {
-  StringRef Name;                 // Human readable name, e.g. "profile".
+  StringRef UserVisibleName;      // Human readable name used in -march, -cpu
+                                  // and target func attribute, e.g. "profile".
   std::optional<StringRef> Alias; // An alias for this extension, if one exists.
   ArchExtKind ID;                 // Corresponding to the ArchExtKind, this
                                   // extensions representation in the bitfield.
-  StringRef Feature;              // -mattr enable string, e.g. "+spe"
-  StringRef NegFeature;           // -mattr disable string, e.g. "-spe"
+  StringRef ArchFeatureName;      // The feature name defined by the
+                                  // Architecture, e.g. FEAT_AdvSIMD.
+  StringRef Description;          // The textual description of the extension.
+  StringRef PosTargetFeature;     // -target-feature/-mattr enable string,
+                                  // e.g. "+spe".
+  StringRef NegTargetFeature;     // -target-feature/-mattr disable string,
+                                  // e.g. "-spe".
 };
 
 #define EMIT_EXTENSIONS
@@ -286,12 +293,12 @@ struct ExtensionSet {
       Features.emplace_back(T(BaseArch->ArchFeature));
 
     for (const auto &E : Extensions) {
-      if (E.Feature.empty() || !Touched.test(E.ID))
+      if (E.PosTargetFeature.empty() || !Touched.test(E.ID))
         continue;
       if (Enabled.test(E.ID))
-        Features.emplace_back(T(E.Feature));
+        Features.emplace_back(T(E.PosTargetFeature));
       else
-        Features.emplace_back(T(E.NegFeature));
+        Features.emplace_back(T(E.NegTargetFeature));
     }
   }
 
@@ -343,7 +350,9 @@ bool isX18ReservedByDefault(const Triple &TT);
 // themselves, they are sequential (0, 1, 2, 3, ...).
 uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
 
-void PrintSupportedExtensions(StringMap<StringRef> DescMap);
+void PrintSupportedExtensions();
+
+void printEnabledExtensions(std::set<StringRef> EnabledFeatureNames);
 
 } // namespace AArch64
 } // namespace llvm
diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp
index cf3aba17fc3d4..1de0a9f66669a 100644
--- a/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -336,6 +336,16 @@ void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const {
                                   ForwardingPaths);
 }
 
+std::vector<SubtargetFeatureKV>
+MCSubtargetInfo::getEnabledProcessorFeatures() const {
+  std::vector<SubtargetFeatureKV> EnabledFeatures;
+  auto IsEnabled = [&](const SubtargetFeatureKV &FeatureKV) {
+    return FeatureBits.test(FeatureKV.Value);
+  };
+  llvm::copy_if(ProcFeatures, std::back_inserter(EnabledFeatures), IsEnabled);
+  return EnabledFeatures;
+}
+
 std::optional<unsigned> MCSubtargetInfo::getCacheSize(unsigned Level) const {
   return std::nullopt;
 }
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 8c1003c085e63..8ec06ac0aef15 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -9,28 +9,46 @@
 //
 //===----------------------------------------------------------------------===//
 
-// A SubtargetFeature that can be toggled from the command line, and therefore
-// has an AEK_* entry in ArmExtKind.
+// A SubtargetFeature that represents one or more Architecture Extensions, as
+// defined by the Arm ARM and tipically identified by a 'FEAT_*' name.
+// Each Extension record defines an ExtensionInfo entry in the Target Parser
+// with a corresponding 'AEK_*' entry in the ArchExtKind enum.
 class Extension<
-  string TargetFeatureName,            // String used for -target-feature and -march, unless overridden.
+  string TargetFeatureName,            // String used for -target-feature, unless overridden.
   string Spelling,                     // The XYZ in HasXYZ and AEK_XYZ.
+  string ArchitectureFeatureName,      // The extension's "FEAT_*"" name(s) defined by the architecture
   string Desc,                         // Description.
   list<SubtargetFeature> Implies = []  // List of dependent features.
 > : SubtargetFeature<TargetFeatureName, "Has" # Spelling, "true", Desc, Implies>
 {
     string ArchExtKindSpelling = "AEK_" # Spelling; // ArchExtKind enum name.
 
-    // In general, the name written on the command line should match the name
-    // used for -target-feature. However, there are exceptions. Therefore we
-    // add a separate field for this, to allow overriding it. Strongly prefer
-    // not doing so.
-    string MArchName = TargetFeatureName;
+    string ArchFeatureName = ArchitectureFeatureName;
+
+    // The user visible name used by -march/-mcpu modifiers and target attribute
+    // values. Extensions are not available on these by default.
+    string UserVisibleName = "";
 
     // An alias that can be used on the command line, if the extension has one.
     // Used for correcting historical names while remaining backwards compatible.
-    string MArchAlias = "";
+    string UserVisibleAlias = "";
 }
 
+// An Extension that can be toggled via a '-march'/'-mcpu' modifier or a target
+// attribute, e.g. '+sm4".
+class ExtensionWithMArch<
+  string TargetFeatureName,            // String used for -target-feature and -march, unless overridden.
+  string Spelling,                     // The XYZ in HasXYZ and AEK_XYZ.
+  string ArchitectureFeatureName,      // The extension's "FEAT_*"" name(s) defined by the architecture
+  string Desc,                         // Description.
+  list<SubtargetFeature> Implies = []  // List of dependent features.
+> : Extension<TargetFeatureName, Spelling, ArchitectureFeatureName, Desc, Implies> {
+    // In general, the name written on the command line should match the name
+    // used for -target-feature. However, there are exceptions. Therefore we
+    // add a separate field for this, to allow overriding it. Strongly prefer
+    // not doing so.
+    let UserVisibleName = TargetFeatureName;
+}
 
 
 
@@ -45,21 +63,19 @@ class Extension<
 //  Armv8.0 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-let ArchExtKindSpelling = "AEK_FP", MArchName = "fp" in
-def FeatureFPARMv8 : Extension<"fp-armv8", "FPARMv8",
-  "Enable ARMv8 (FEAT_FP)">;
+let ArchExtKindSpelling = "AEK_FP", UserVisibleName = "fp" in
+def FeatureFPARMv8 : ExtensionWithMArch<"fp-armv8", "FPARMv8", "FEAT_FP",
+  "Enable ARMv8">;
 
-let ArchExtKindSpelling = "AEK_SIMD", MArchName = "simd" in
-def FeatureNEON : Extension<"neon", "NEON",
-  "Enable Advanced SIMD instructions (FEAT_AdvSIMD)", [FeatureFPARMv8]>;
+let ArchExtKindSpelling = "AEK_SIMD", UserVisibleName = "simd" in
+def FeatureNEON : ExtensionWithMArch<"neon", "NEON", "FEAT_AdvSIMD",
+  "Enable Advanced SIMD instructions", [FeatureFPARMv8]>;
 
-def FeatureSHA2 : Extension<
-    "sha2", "SHA2",
-    "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)", [FeatureNEON]>;
+def FeatureSHA2 : ExtensionWithMArch<"sha2", "SHA2", "FEAT_SHA1, FEAT_SHA256",
+  "Enable SHA1 and SHA256 support", [FeatureNEON]>;
 
-def FeatureAES : Extension<
-    "aes", "AES",
-    "Enable AES support (FEAT_AES, FEAT_PMULL)", [FeatureNEON]>;
+def FeatureAES : ExtensionWithMArch<"aes", "AES", "FEAT_AES, FEAT_PMULL",
+  "Enable AES support", [FeatureNEON]>;
 
 // Crypto has been split up and any combination is now valid (see the
 // crypto definitions above). Also, crypto is now context sensitive:
@@ -69,289 +85,271 @@ def FeatureAES : Extension<
 // meaning anymore. We kept the Crypto definition here for backward
 // compatibility, and now imply features SHA2 and AES, which was the
 // "traditional" meaning of Crypto.
-def FeatureCrypto : Extension<"crypto", "Crypto",
+def FeatureCrypto : ExtensionWithMArch<"crypto", "Crypto", "FEAT_Crypto",
   "Enable cryptographic instructions", [FeatureNEON, FeatureSHA2, FeatureAES]>;
 
-def FeatureCRC : Extension<"crc", "CRC",
-  "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)">;
+def FeatureCRC : ExtensionWithMArch<"crc", "CRC", "FEAT_CRC32",
+  "Enable ARMv8 CRC-32 checksum instructions">;
 
 // This SubtargetFeature is special. It controls only whether codegen will turn
 // `llvm.readcyclecounter()` into an access to a PMUv3 System Register. The
 // `FEAT_PMUv3*` system registers are always available for assembly/disassembly.
-let MArchName = "pmuv3" in
-def FeaturePerfMon : Extension<"perfmon", "PerfMon",
-  "Enable Code Generation for ARMv8 PMUv3 Performance Monitors extension (FEAT_PMUv3)">;
+let UserVisibleName = "pmuv3" in
+def FeaturePerfMon : ExtensionWithMArch<"perfmon", "PerfMon", "FEAT_PMUv3",
+  "Enable Code Generation for ARMv8 PMUv3 Performance Monitors extension">;
 
-def FeatureSpecRestrict : SubtargetFeature<"specrestrict", "HasSpecRestrict",
-  "true", "Enable architectural speculation restriction (FEAT_CSV2_2)">;
+def FeatureSpecRestrict : Extension<"specrestrict", "SpecRestrict", "FEAT_CSV2_2",
+  "Enable architectural speculation restriction">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.1 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureLSE : Extension<"lse", "LSE",
-  "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)">;
+def FeatureLSE : ExtensionWithMArch<"lse", "LSE", "FEAT_LSE",
+  "Enable ARMv8.1 Large System Extension (LSE) atomic instructions">;
 
-let MArchAlias = "rdma" in
-def FeatureRDM : Extension<"rdm", "RDM",
-  "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions (FEAT_RDM)",
+let UserVisibleAlias = "rdma" in
+def FeatureRDM : ExtensionWithMArch<"rdm", "RDM", "FEAT_RDM",
+  "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions",
   [FeatureNEON]>;
 
-def FeaturePAN : SubtargetFeature<
-    "pan", "HasPAN", "true",
-    "Enables ARM v8.1 Privileged Access-Never extension (FEAT_PAN)">;
+def FeaturePAN : Extension<"pan", "PAN", "FEAT_PAN",
+  "Enables ARM v8.1 Privileged Access-Never extension">;
 
-def FeatureLOR : SubtargetFeature<
-    "lor", "HasLOR", "true",
-    "Enables ARM v8.1 Limited Ordering Regions extension (FEAT_LOR)">;
+def FeatureLOR : Extension<"lor", "LOR", "FEAT_LOR",
+  "Enables ARM v8.1 Limited Ordering Regions extension">;
 
 def FeatureCONTEXTIDREL2 : SubtargetFeature<"CONTEXTIDREL2", "HasCONTEXTIDREL2",
-    "true", "Enable RW operand CONTEXTIDR_EL2" >;
+  "true", "Enable RW operand CONTEXTIDR_EL2">;
 
-def FeatureVH : SubtargetFeature<"vh", "HasVH", "true",
-    "Enables ARM v8.1 Virtual Host extension (FEAT_VHE)", [FeatureCONTEXTIDREL2] >;
+def FeatureVH : Extension<"vh", "VH", "FEAT_VHE",
+  "Enables ARM v8.1 Virtual Host extension", [FeatureCONTEXTIDREL2]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.2 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureSM4 : Extension<
-    "sm4", "SM4",
-    "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)", [FeatureNEON]>;
+def FeatureSM4 : ExtensionWithMArch<"sm4", "SM4", "FEAT_SM4, FEAT_SM3",
+  "Enable SM3 and SM4 support", [FeatureNEON]>;
 
-def FeatureSHA3 : Extension<
-    "sha3", "SHA3",
-    "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)", [FeatureNEON, FeatureSHA2]>;
+def FeatureSHA3 : ExtensionWithMArch<"sha3", "SHA3", "FEAT_SHA3, FEAT_SHA512",
+  "Enable SHA512 and SHA3 support", [FeatureNEON, FeatureSHA2]>;
 
-def FeatureRAS : Extension<"ras", "RAS",
-  "Enable ARMv8 Reliability, Availability and Serviceability Extensions (FEAT_RAS, FEAT_RASv1p1)">;
+def FeatureRAS : ExtensionWithMArch<"ras", "RAS", "FEAT_RAS, FEAT_RASv1p1",
+  "Enable ARMv8 Reliability, Availability and Serviceability Extensions">;
 
-let ArchExtKindSpelling = "AEK_FP16", MArchName = "fp16" in
-def FeatureFullFP16 : Extension<"fullfp16", "FullFP16",
-  "Full FP16 (FEAT_FP16)", [FeatureFPARMv8]>;
+let ArchExtKindSpelling = "AEK_FP16", UserVisibleName = "fp16" in
+def FeatureFullFP16 : ExtensionWithMArch<"fullfp16", "FullFP16", "FEAT_FP16",
+  "Full FP16", [FeatureFPARMv8]>;
 
-let ArchExtKindSpelling = "AEK_PROFILE", MArchName = "profile" in
-def FeatureSPE : Extension<"spe", "SPE",
-  "Enable Statistical Profiling extension (FEAT_SPE)">;
+let ArchExtKindSpelling = "AEK_PROFILE", UserVisibleName = "profile" in
+def FeatureSPE : ExtensionWithMArch<"spe", "SPE", "FEAT_SPE",
+  "Enable Statistical Profiling extension">;
 
-def FeaturePAN_RWV : SubtargetFeature<
-    "pan-rwv", "HasPAN_RWV", "true",
-    "Enable v8.2 PAN s1e1R and s1e1W Variants (FEAT_PAN2)",
-    [FeaturePAN]>;
+def FeaturePAN_RWV : Extension<"pan-rwv", "PAN_RWV", "FEAT_PAN2",
+  "Enable v8.2 PAN s1e1R and s1e1W Variants", [FeaturePAN]>;
 
-def FeaturePsUAO : SubtargetFeature< "uaops", "HasPsUAO", "true",
-    "Enable v8.2 UAO PState (FEAT_UAO)">;
+def FeaturePsUAO : Extension<"uaops", "PsUAO", "FEAT_UAO",
+  "Enable v8.2 UAO PState">;
 
-def FeatureCCPP : SubtargetFeature<"ccpp", "HasCCPP",
-    "true", "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)" >;
+def FeatureCCPP : Extension<"ccpp", "CCPP", "FEAT_DPB",
+  "Enable v8.2 data Cache Clean to Point of Persistence">;
 
-def FeatureSVE : Extension<"sve", "SVE",
-  "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", [FeatureFullFP16]>;
+def FeatureSVE : ExtensionWithMArch<"sve", "SVE", "FEAT_SVE",
+  "Enable Scalable Vector Extension (SVE) instructions", [FeatureFullFP16]>;
 
 let ArchExtKindSpelling = "AEK_I8MM" in
-def FeatureMatMulInt8 : Extension<"i8mm", "MatMulInt8",
-    "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)", []>;
+def FeatureMatMulInt8 : ExtensionWithMArch<"i8mm", "MatMulInt8", "FEAT_I8MM",
+  "Enable Matrix Multiply Int8 Extension">;
 
 let ArchExtKindSpelling = "AEK_F32MM" in
-def FeatureMatMulFP32 : Extension<"f32mm", "MatMulFP32",
-    "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)", [FeatureSVE]>;
+def FeatureMatMulFP32 : ExtensionWithMArch<"f32mm", "MatMulFP32", "FEAT_F32MM",
+  "Enable Matrix Multiply FP32 Extension", [FeatureSVE]>;
 
 let ArchExtKindSpelling = "AEK_F64MM" in
-def FeatureMatMulFP64 : Extension<"f64mm", "MatMulFP64",
-    "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)", [FeatureSVE]>;
+def FeatureMatMulFP64 : ExtensionWithMArch<"f64mm", "MatMulFP64", "FEAT_F64MM",
+  "Enable Matrix Multiply FP64 Extension", [FeatureSVE]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.3 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureRCPC : Extension<"rcpc", "RCPC",
-    "Enable support for RCPC extension (FEAT_LRCPC)", []>;
+def FeatureRCPC : ExtensionWithMArch<"rcpc", "RCPC", "FEAT_LRCPC",
+  "Enable support for RCPC extension">;
 
-def FeaturePAuth : Extension<
-    "pauth", "PAuth",
-    "Enable v8.3-A Pointer Authentication extension (FEAT_PAuth)">;
+def FeaturePAuth : ExtensionWithMArch<"pauth", "PAuth", "FEAT_PAuth",
+  "Enable v8.3-A Pointer Authentication extension">;
 
-let ArchExtKindSpelling = "AEK_JSCVT", MArchName = "jscvt" in
-def FeatureJS : Extension<
-    "jsconv", "JS",
-    "Enable v8.3-A JavaScript FP conversion instructions (FEAT_JSCVT)",
-    [FeatureFPARMv8]>;
+let ArchExtKindSpelling = "AEK_JSCVT", UserVisibleName = "jscvt" in
+def FeatureJS : ExtensionWithMArch<"jsconv", "JS", "FEAT_JSCVT",
+  "Enable v8.3-A JavaScript FP conversion instructions",
+  [FeatureFPARMv8]>;
 
-def FeatureCCIDX : SubtargetFeature<
-    "ccidx", "HasCCIDX", "true",
-    "Enable v8.3-A Extend of the CCSIDR number of sets (FEAT_CCIDX)">;
+def FeatureCCIDX : Extension<"ccidx", "CCIDX", "FEAT_CCIDX",
+  "Enable v8.3-A Extend of the CCSIDR number of sets">;
 
-let ArchExtKindSpelling = "AEK_FCMA", MArchName = "fcma" in
-def FeatureComplxNum : Extension<
-    "complxnum", "ComplxNum",
-    "Enable v8.3-A Floating-point complex number support (FEAT_FCMA)",
-    [FeatureNEON]>;
+let ArchExtKindSpelling = "AEK_FCMA", UserVisibleName = "fcma" in
+def FeatureComplxNum : ExtensionWithMArch<"complxnum", "ComplxNum", "FEAT_FCMA",
+  "Enable v8.3-A Floating-point complex number support",
+  [FeatureNEON]>;
 
-def FeatureNV : SubtargetFeature<
-    "nv", "HasNV", "true",
-    "Enable v8.4-A Nested Virtualization Enchancement (FEAT_NV, FEAT_NV2)">;
+def FeatureNV : Extension<"nv", "NV", "FEAT_NV, FEAT_NV2",
+  "Enable v8.4-A Nested Virtualization Enchancement">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.4 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureLSE2 : SubtargetFeature<"lse2", "HasLSE2", "true",
-  "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules (FEAT_LSE2)">;
+def FeatureLSE2 : Extension<"lse2", "LSE2", "FEAT_LSE2",
+  "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules">;
 
-def FeatureFP16FML : Extension<"fp16fml", "FP16FML",
-  "Enable FP16 FML instructions (FEAT_FHM)", [FeatureFullFP16]>;
+def FeatureFP16FML : ExtensionWithMArch<"fp16fml", "FP16FML", "FEAT_FHM",
+  "Enable FP16 FML instructions", [FeatureFullFP16]>;
 
-def FeatureDotProd : Extension<
-    "dotprod", "DotProd",
-    "Enable dot product support (FEAT_DotProd)", [FeatureNEON]>;
+def FeatureDotProd : ExtensionWithMArch<"dotprod", "DotProd", "FEAT_DotProd",
+  "Enable dot product support", [FeatureNEON]>;
 
-def FeatureMPAM : SubtargetFeature<
-    "mpam", "HasMPAM", "true",
-    "Enable v8.4-A Memory system Partitioning and Monitoring extension (FEAT_MPAM)">;
+def FeatureMPAM : Extension<"mpam", "MPAM", "FEAT_MPAM",
+  "Enable v8.4-A Memory system Partitioning and Monitoring extension">;
 
-def FeatureDIT : SubtargetFeature<
-    "dit", "HasDIT", "true",
-    "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)">;
+def FeatureDIT : ExtensionWithMArch<"dit", "DIT", "FEAT_DIT",
+  "Enable v8.4-A Data Independent Timing instructions">;
 
-def FeatureTRACEV8_4 : SubtargetFeature<
-    "tracev8.4", "HasTRACEV8_4", "true",
-    "Enable v8.4-A Trace extension (FEAT_TRF)">;
+def FeatureTRACEV8_4 : Extension<"tracev8.4", "TRACEV8_4", "FEAT_TRF",
+  "Enable v8.4-A Trace extension">;
 
-def FeatureAM : SubtargetFeature<
-    "am", "HasAM", "true",
-    "Enable v8.4-A Activity Monitors extension (FEAT_AMUv1)">;
+def FeatureAM : Extension<"am", "AM", "FEAT_AMUv1",
+  "Enable v8.4-A Activity Monitors extension">;
 
-def FeatureSEL2 : SubtargetFeature<
-    "sel2", "HasSEL2", "true",
-    "Enable v8.4-A Secure Exception Level 2 extension (FEAT_SEL2)">;
+def FeatureSEL2 : Extension<"sel2", "SEL2", "FEAT_SEL2",
+  "Enable v8.4-A Secure Exception Level 2 extension">;
 
-def FeatureTLB_RMI : SubtargetFeature<
-    "tlb-rmi", "HasTLB_RMI", "true",
-    "Enable v8.4-A TLB Range and Maintenance Instructions (FEAT_TLBIOS, FEAT_TLBIRANGE)">;
+def FeatureTLB_RMI : Extension<"tlb-rmi", "TLB_RMI",
+  "FEAT_TLBIOS, FEAT_TLBIRANGE",
+  "Enable v8.4-A TLB Range and Maintenance Instructions">;
 
-def FeatureFlagM : Extension<
-    "flagm", "FlagM",
-    "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)", []>;
+def FeatureFlagM : ExtensionWithMArch<"flagm", "FlagM", "FEAT_FlagM",
+  "Enable v8.4-A Flag Manipulation Instructions">;
 
-def FeatureRCPC_IMMO : SubtargetFeature<"rcpc-immo", "HasRCPC_IMMO", "true",
-    "Enable v8.4-A RCPC instructions with Immediate Offsets (FEAT_LRCPC2)",
-    [FeatureRCPC]>;
+def FeatureRCPC_IMMO : Extension<"rcpc-immo", "RCPC_IMMO", "FEAT_LRCPC2",
+  "Enable v8.4-A RCPC instructions with Immediate Offsets",
+  [FeatureRCPC]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.5 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureAltFPCmp : SubtargetFeature<"altnzcv", "HasAlternativeNZCV", "true",
-  "Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)">;
+def FeatureAltFPCmp : Extension<"altnzcv", "AlternativeNZCV", "FEAT_FlagM2",
+  "Enable alternative NZCV format for floating point comparisons">;
 
-def FeatureFRInt3264 : SubtargetFeature<"fptoint", "HasFRInt3264", "true",
+def FeatureFRInt3264 : Extension<"fptoint", "FRInt3264", "FEAT_FRINTTS",
   "Enable FRInt[32|64][Z|X] instructions that round a floating-point number to "
-  "an integer (in FP format) forcing it to fit into a 32- or 64-bit int (FEAT_FRINTTS)" >;
+  "an integer (in FP format) forcing it to fit into a 32- or 64-bit int">;
 
-def FeatureSB : Extension<"sb", "SB",
-  "Enable v8.5 Speculation Barrier (FEAT_SB)", []>;
+def FeatureSB : ExtensionWithMArch<"sb", "SB", "FEAT_SB",
+  "Enable v8.5 Speculation Barrier">;
 
-def FeatureSSBS : Extension<"ssbs", "SSBS",
-  "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)", []>;
+def FeatureSSBS : ExtensionWithMArch<"ssbs", "SSBS", "FEAT_SSBS, FEAT_SSBS2",
+  "Enable Speculative Store Bypass Safe bit">;
 
-def FeaturePredRes : Extension<"predres", "PredRes",
-  "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)", []>;
+def FeaturePredRes : ExtensionWithMArch<"predres", "PredRes", "FEAT_SPECRES",
+  "Enable v8.5a execution and data prediction invalidation instructions">;
 
-def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "CCDP", "true",
-    "Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)" >;
+def FeatureCacheDeepPersist : Extension<"ccdp", "CCDP", "FEAT_DPB2",
+  "Enable v8.5 Cache Clean to Point of Deep Persistence">;
 
-def FeatureBranchTargetId : SubtargetFeature<"bti", "BTI", "true",
-    "Enable Branch Target Identification (FEAT_BTI)">;
+def FeatureBranchTargetId : ExtensionWithMArch<"bti", "BTI", "FEAT_BTI",
+  "Enable Branch Target Identification">;
 
-let ArchExtKindSpelling = "AEK_RAND", MArchName = "rng" in
-def FeatureRandGen : Extension<"rand", "RandGen",
-    "Enable Random Number generation instructions (FEAT_RNG)", []>;
+let ArchExtKindSpelling = "AEK_RAND", UserVisibleName = "rng" in
+def FeatureRandGen : ExtensionWithMArch<"rand", "RandGen", "FEAT_RNG",
+  "Enable Random Number generation instructions">;
 
 // NOTE: "memtag" means FEAT_MTE + FEAT_MTE2 for -march or
 // __attribute((target(...))), but only FEAT_MTE for FMV.
-let MArchName = "memtag" in
-def FeatureMTE : Extension<"mte", "MTE",
-    "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)", []>;
+let UserVisibleName = "memtag" in
+def FeatureMTE : ExtensionWithMArch<"mte", "MTE", "FEAT_MTE, FEAT_MTE2",
+  "Enable Memory Tagging Extension">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.6 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureBF16 : Extension<"bf16", "BF16",
-    "Enable BFloat16 Extension (FEAT_BF16)">;
+def FeatureBF16 : ExtensionWithMArch<"bf16", "BF16", "FEAT_BF16",
+  "Enable BFloat16 Extension">;
 
-def FeatureAMVS : SubtargetFeature<
-    "amvs", "HasAMVS", "true",
-    "Enable v8.6-A Activity Monitors Virtualization support (FEAT_AMUv1p1)",
-    [FeatureAM]>;
+def FeatureAMVS : Extension<"amvs", "AMVS", "FEAT_AMUv1p1",
+  "Enable v8.6-A Activity Monitors Virtualization support",
+  [FeatureAM]>;
 
-def FeatureFineGrainedTraps : SubtargetFeature<"fgt", "HasFineGrainedTraps",
-    "true", "Enable fine grained virtualization traps extension (FEAT_FGT)">;
+def FeatureFineGrainedTraps : Extension<"fgt", "FineGrainedTraps", "FEAT_FGT",
+  "Enable fine grained virtualization traps extension">;
 
 def FeatureEnhancedCounterVirtualization :
-      SubtargetFeature<"ecv", "HasEnhancedCounterVirtualization",
-      "true", "Enable enhanced counter virtualization extension (FEAT_ECV)">;
+    Extension<"ecv", "EnhancedCounterVirtualization", "FEAT_ECV",
+      "Enable enhanced counter virtualization extension">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.7 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureXS : SubtargetFeature<"xs", "HasXS",
-    "true", "Enable Armv8.7-A limited-TLB-maintenance instruction (FEAT_XS)">;
+def FeatureXS : Extension<"xs", "XS", "FEAT_XS",
+  "Enable Armv8.7-A limited-TLB-maintenance instruction">;
 
-def FeatureWFxT : SubtargetFeature<"wfxt", "WFxT", "true",
-    "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)">;
+def FeatureWFxT : ExtensionWithMArch<"wfxt", "WFxT", "FEAT_WFxT",
+  "Enable Armv8.7-A WFET and WFIT instruction">;
 
-def FeatureHCX : SubtargetFeature<
-    "hcx", "HasHCX", "true", "Enable Armv8.7-A HCRX_EL2 system register (FEAT_HCX)">;
+def FeatureHCX : Extension<"hcx", "HCX", "FEAT_HCX",
+  "Enable Armv8.7-A HCRX_EL2 system register">;
 
-def FeatureLS64 : Extension<"ls64", "LS64",
-    "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)", []>;
+def FeatureLS64 : ExtensionWithMArch<"ls64", "LS64",
+  "FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA",
+  "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">;
 
-def FeatureSPE_EEF : SubtargetFeature<"spe-eef", "HasSPE_EEF",
-    "true", "Enable extra register in the Statistical Profiling Extension (FEAT_SPEv1p2)">;
+def FeatureSPE_EEF : Extension<"spe-eef", "SPE_EEF", "FEAT_SPEv1p2",
+  "Enable extra register in the Statistical Profiling Extension">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.8 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureHBC : Extension<"hbc", "HBC",
-    "Enable Armv8.8-A Hinted Conditional Branches Extension (FEAT_HBC)">;
+def FeatureHBC : ExtensionWithMArch<"hbc", "HBC", "FEAT_HBC",
+    "Enable Armv8.8-A Hinted Conditional Branches Extension">;
 
-def FeatureMOPS : Extension<"mops", "MOPS",
-    "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)", []>;
+def FeatureMOPS : ExtensionWithMArch<"mops", "MOPS", "FEAT_MOPS",
+    "Enable Armv8.8-A memcpy and memset acceleration instructions">;
 
-def FeatureNMI : SubtargetFeature<"nmi", "HasNMI",
-    "true", "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)">;
+def FeatureNMI : Extension<"nmi", "NMI", "FEAT_NMI, FEAT_GICv3_NMI",
+  "Enable Armv8.8-A Non-maskable Interrupts">;
 
 //===----------------------------------------------------------------------===//
 //  Armv8.9 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureRASv2 : Extension<"rasv2", "RASv2",
-  "Enable ARMv8.9-A Reliability, Availability and Serviceability Extensions (FEAT_RASv2)",
+def FeatureRASv2 : ExtensionWithMArch<"rasv2", "RASv2", "FEAT_RASv2",
+  "Enable ARMv8.9-A Reliability, Availability and Serviceability Extensions",
   [FeatureRAS]>;
 
-def FeatureCSSC : Extension<"cssc", "CSSC",
-  "Enable Common Short Sequence Compression (CSSC) instructions (FEAT_CSSC)">;
+def FeatureCSSC : ExtensionWithMArch<"cssc", "CSSC", "FEAT_CSSC",
+  "Enable Common Short Sequence Compression (CSSC) instructions">;
 
-def FeatureCLRBHB : SubtargetFeature<"clrbhb", "HasCLRBHB",
-    "true", "Enable Clear BHB instruction (FEAT_CLRBHB)">;
+def FeatureCLRBHB : Extension<"clrbhb", "CLRBHB", "FEAT_CLRBHB",
+  "Enable Clear BHB instruction">;
 
-def FeaturePRFM_SLC : SubtargetFeature<"prfm-slc-target", "HasPRFM_SLC",
-    "true", "Enable SLC target for PRFM instruction">;
+def FeaturePRFM_SLC : Extension<"prfm-slc-target", "PRFM_SLC", "FEAT_PRFMSLC",
+  "Enable SLC target for PRFM instruction">;
 
-let MArchName = "predres2" in
-def FeatureSPECRES2 : Extension<"specres2", "SPECRES2",
-    "Enable Speculation Restriction Instruction (FEAT_SPECRES2)",
-    [FeaturePredRes]>;
+let UserVisibleName = "predres2" in
+def FeatureSPECRES2 : ExtensionWithMArch<"specres2", "SPECRES2", "FEAT_SPECRES2",
+  "Enable Speculation Restriction Instruction",
+  [FeaturePredRes]>;
 
-def FeatureRCPC3 : Extension<"rcpc3", "RCPC3",
-    "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)",
-    [FeatureRCPC_IMMO]>;
+def FeatureRCPC3 : ExtensionWithMArch<"rcpc3", "RCPC3", "FEAT_LRCPC3",
+  "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set",
+  [FeatureRCPC_IMMO]>;
 
-def FeatureTHE : Extension<"the", "THE",
-    "Enable Armv8.9-A Translation Hardening Extension (FEAT_THE)">;
+def FeatureTHE : ExtensionWithMArch<"the", "THE", "FEAT_THE",
+  "Enable Armv8.9-A Translation Hardening Extension">;
 
 //===----------------------------------------------------------------------===//
 //  Armv9.0 Architecture Extensions
@@ -360,32 +358,32 @@ def FeatureTHE : Extension<"the", "THE",
 def FeatureUseScalarIncVL : SubtargetFeature<"use-scalar-inc-vl",
   "UseScalarIncVL", "true", "Prefer inc/dec over add+cnt">;
 
-def FeatureSVE2 : Extension<"sve2", "SVE2",
-  "Enable Scalable Vector Extension 2 (SVE2) instructions (FEAT_SVE2)",
+def FeatureSVE2 : ExtensionWithMArch<"sve2", "SVE2", "FEAT_SVE2",
+  "Enable Scalable Vector Extension 2 (SVE2) instructions",
   [FeatureSVE, FeatureUseScalarIncVL]>;
 
-def FeatureSVE2AES : Extension<"sve2-aes", "SVE2AES",
-  "Enable AES SVE2 instructions (FEAT_SVE_AES, FEAT_SVE_PMULL128)",
-  [FeatureSVE2, FeatureAES]>;
+def FeatureSVE2AES : ExtensionWithMArch<"sve2-aes", "SVE2AES",
+  "FEAT_SVE_AES, FEAT_SVE_PMULL128",
+  "Enable AES SVE2 instructions", [FeatureSVE2, FeatureAES]>;
 
-def FeatureSVE2SM4 : Extension<"sve2-sm4", "SVE2SM4",
-  "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)", [FeatureSVE2, FeatureSM4]>;
+def FeatureSVE2SM4 : ExtensionWithMArch<"sve2-sm4", "SVE2SM4", "FEAT_SVE_SM4",
+  "Enable SM4 SVE2 instructions", [FeatureSVE2, FeatureSM4]>;
 
-def FeatureSVE2SHA3 : Extension<"sve2-sha3", "SVE2SHA3",
-  "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)", [FeatureSVE2, FeatureSHA3]>;
+def FeatureSVE2SHA3 : ExtensionWithMArch<"sve2-sha3", "SVE2SHA3", "FEAT_SVE_SHA3",
+  "Enable SHA3 SVE2 instructions", [FeatureSVE2, FeatureSHA3]>;
 
-def FeatureSVE2BitPerm : Extension<"sve2-bitperm", "SVE2BitPerm",
-  "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", [FeatureSVE2]>;
+def FeatureSVE2BitPerm : ExtensionWithMArch<"sve2-bitperm", "SVE2BitPerm",
+  "FEAT_SVE_BitPerm",
+  "Enable bit permutation SVE2 instructions", [FeatureSVE2]>;
 
-def FeatureTRBE : SubtargetFeature<"trbe", "TRBE", "true",
-    "Enable Trace Buffer Extension (FEAT_TRBE)">;
+def FeatureTRBE : Extension<"trbe", "TRBE", "FEAT_TRBE",
+  "Enable Trace Buffer Extension">;
 
-def FeatureETE : SubtargetFeature<"ete", "ETE", "true",
-    "Enable Embedded Trace Extension (FEAT_ETE)",
-    [FeatureTRBE]>;
+def FeatureETE : Extension<"ete", "ETE", "FEAT_ETE",
+  "Enable Embedded Trace Extension", [FeatureTRBE]>;
 
-def FeatureTME : Extension<"tme", "TME",
-    "Enable Transactional Memory Extension (FEAT_TME)" >;
+def FeatureTME : ExtensionWithMArch<"tme", "TME", "FEAT_TME",
+  "Enable Transactional Memory Extension">;
 
 //===----------------------------------------------------------------------===//
 //  Armv9.1 Architecture Extensions
@@ -395,119 +393,119 @@ def FeatureTME : Extension<"tme", "TME",
 //  Armv9.2 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureBRBE : Extension<"brbe", "BRBE",
-    "Enable Branch Record Buffer Extension (FEAT_BRBE)">;
+def FeatureBRBE : ExtensionWithMArch<"brbe", "BRBE", "FEAT_BRBE",
+  "Enable Branch Record Buffer Extension">;
 
-def FeatureRME : SubtargetFeature<"rme", "HasRME",
-    "true", "Enable Realm Management Extension (FEAT_RME)">;
+def FeatureRME : Extension<"rme", "RME", "FEAT_RME",
+  "Enable Realm Management Extension">;
 
-def FeatureSME : Extension<"sme", "SME",
-  "Enable Scalable Matrix Extension (SME) (FEAT_SME)", [FeatureBF16, FeatureUseScalarIncVL]>;
+def FeatureSME : ExtensionWithMArch<"sme", "SME", "FEAT_SME",
+  "Enable Scalable Matrix Extension (SME)", [FeatureBF16, FeatureUseScalarIncVL]>;
 
-def FeatureSMEF64F64 : Extension<"sme-f64f64", "SMEF64F64",
-  "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)", [FeatureSME]>;
+def FeatureSMEF64F64 : ExtensionWithMArch<"sme-f64f64", "SMEF64F64", "FEAT_SME_F64F64",
+  "Enable Scalable Matrix Extension (SME) F64F64 instructions", [FeatureSME]>;
 
-def FeatureSMEI16I64 : Extension<"sme-i16i64", "SMEI16I64",
-  "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)", [FeatureSME]>;
+def FeatureSMEI16I64 : ExtensionWithMArch<"sme-i16i64", "SMEI16I64", "FEAT_SME_I16I64",
+  "Enable Scalable Matrix Extension (SME) I16I64 instructions", [FeatureSME]>;
 
-def FeatureSMEFA64 : Extension<"sme-fa64", "SMEFA64",
-  "Enable the full A64 instruction set in streaming SVE mode (FEAT_SME_FA64)", [FeatureSME, FeatureSVE2]>;
+def FeatureSMEFA64 : ExtensionWithMArch<"sme-fa64", "SMEFA64", "FEAT_SME_FA64",
+  "Enable the full A64 instruction set in streaming SVE mode", [FeatureSME, FeatureSVE2]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv9.3 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureSME2 : Extension<"sme2", "SME2",
+def FeatureSME2 : ExtensionWithMArch<"sme2", "SME2", "FEAT_SME2",
   "Enable Scalable Matrix Extension 2 (SME2) instructions", [FeatureSME]>;
 
-def FeatureMEC : SubtargetFeature<"mec", "HasMEC",
-    "true", "Enable Memory Encryption Contexts Extension", [FeatureRME]>;
+def FeatureMEC : Extension<"mec", "MEC", "FEAT_MEC",
+  "Enable Memory Encryption Contexts Extension", [FeatureRME]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv9.4 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureSVE2p1: Extension<"sve2p1", "SVE2p1",
+def FeatureSVE2p1: ExtensionWithMArch<"sve2p1", "SVE2p1", "FEAT_SVE2p1",
   "Enable Scalable Vector Extension 2.1 instructions", [FeatureSVE2]>;
 
-def FeatureB16B16 : Extension<"b16b16", "B16B16",
-  "Enable SVE2.1 or SME2.1 non-widening BFloat16 to BFloat16 instructions (FEAT_B16B16)", [FeatureBF16]>;
+def FeatureB16B16 : ExtensionWithMArch<"b16b16", "B16B16", "FEAT_SVE_B16B16",
+  "Enable SVE2.1 or SME2.1 non-widening BFloat16 to BFloat16 instructions", [FeatureBF16]>;
 
-def FeatureSMEF16F16 : Extension<"sme-f16f16", "SMEF16F16",
-  "Enable SME non-widening Float16 instructions (FEAT_SME_F16F16)", [FeatureSME2]>;
+def FeatureSMEF16F16 : ExtensionWithMArch<"sme-f16f16", "SMEF16F16", "FEAT_SME_F16F16",
+  "Enable SME non-widening Float16 instructions", [FeatureSME2]>;
 
-def FeatureSME2p1 : Extension<"sme2p1", "SME2p1",
-  "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions", [FeatureSME2]>;
+def FeatureSME2p1 : ExtensionWithMArch<"sme2p1", "SME2p1", "FEAT_SME2p1",
+  "Enable Scalable Matrix Extension 2.1 instructions", [FeatureSME2]>;
 
-def FeatureCHK : SubtargetFeature<"chk", "HasCHK",
-    "true", "Enable Armv8.0-A Check Feature Status Extension (FEAT_CHK)">;
+def FeatureCHK : Extension<"chk", "CHK", "FEAT_CHK",
+  "Enable Armv8.0-A Check Feature Status Extension">;
 
-def FeatureGCS : Extension<"gcs", "GCS",
-    "Enable Armv9.4-A Guarded Call Stack Extension", [FeatureCHK]>;
+def FeatureGCS : ExtensionWithMArch<"gcs", "GCS", "FEAT_GCS",
+  "Enable Armv9.4-A Guarded Call Stack Extension", [FeatureCHK]>;
 
-def FeatureITE : Extension<"ite", "ITE",
-    "Enable Armv9.4-A Instrumentation Extension FEAT_ITE", [FeatureETE,
-    FeatureTRBE]>;
+def FeatureITE : ExtensionWithMArch<"ite", "ITE", "FEAT_ITE",
+  "Enable Armv9.4-A Instrumentation Extension", [FeatureETE, FeatureTRBE]>;
 
-def FeatureLSE128 : Extension<"lse128", "LSE128",
-    "Enable Armv9.4-A 128-bit Atomic Instructions (FEAT_LSE128)",
-    [FeatureLSE]>;
+def FeatureLSE128 : ExtensionWithMArch<"lse128", "LSE128", "FEAT_LSE128",
+  "Enable Armv9.4-A 128-bit Atomic Instructions",
+  [FeatureLSE]>;
 
 // FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, and FEAT_SYSINSTR128 are mutually implicit.
 // Therefore group them all under a single feature flag, d128:
-def FeatureD128 : Extension<"d128", "D128",
-    "Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers "
-    "and Instructions (FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128)",
-    [FeatureLSE128]>;
+def FeatureD128 : ExtensionWithMArch<"d128", "D128",
+  "FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128",
+  "Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers "
+  "and Instructions",
+  [FeatureLSE128]>;
 
 //===----------------------------------------------------------------------===//
 //  Armv9.5 Architecture Extensions
 //===----------------------------------------------------------------------===//
 
-def FeatureFAMINMAX: Extension<"faminmax", "FAMINMAX",
-   "Enable FAMIN and FAMAX instructions (FEAT_FAMINMAX)">;
+def FeatureFAMINMAX: ExtensionWithMArch<"faminmax", "FAMINMAX", "FEAT_FAMINMAX",
+ "Enable FAMIN and FAMAX instructions">;
 
-def FeatureLUT: Extension<"lut", "LUT",
-   "Enable Lookup Table instructions (FEAT_LUT)">;
+def FeatureLUT: ExtensionWithMArch<"lut", "LUT", "FEAT_LUT",
+ "Enable Lookup Table instructions">;
    
-def FeatureFP8 : Extension<"fp8", "FP8",
-  "Enable FP8 instructions (FEAT_FP8)", [FeatureFAMINMAX, FeatureLUT, FeatureBF16]>;
+def FeatureFP8 : ExtensionWithMArch<"fp8", "FP8", "FEAT_FP8",
+  "Enable FP8 instructions", [FeatureFAMINMAX, FeatureLUT, FeatureBF16]>;
   
-def FeatureFP8FMA : Extension<"fp8fma", "FP8FMA",
-  "Enable fp8 multiply-add instructions (FEAT_FP8FMA)", [FeatureFP8]>;
+def FeatureFP8FMA : ExtensionWithMArch<"fp8fma", "FP8FMA", "FEAT_FP8FMA",
+  "Enable fp8 multiply-add instructions", [FeatureFP8]>;
 
-def FeatureSSVE_FP8FMA : Extension<"ssve-fp8fma", "SSVE_FP8FMA",
-  "Enable SVE2 fp8 multiply-add instructions (FEAT_SSVE_FP8FMA)", [FeatureSME2, FeatureFP8]>;
+def FeatureSSVE_FP8FMA : ExtensionWithMArch<"ssve-fp8fma", "SSVE_FP8FMA", "FEAT_SSVE_FP8FMA",
+  "Enable SVE2 fp8 multiply-add instructions", [FeatureSME2, FeatureFP8]>;
 
-def FeatureFP8DOT4: Extension<"fp8dot4", "FP8DOT4",
-   "Enable fp8 4-way dot instructions (FEAT_FP8DOT4)", [FeatureFP8FMA]>;
+def FeatureFP8DOT4: ExtensionWithMArch<"fp8dot4", "FP8DOT4", "FEAT_FP8DOT4",
+  "Enable fp8 4-way dot instructions", [FeatureFP8FMA]>;
   
-def FeatureFP8DOT2: Extension<"fp8dot2", "FP8DOT2",
-   "Enable fp8 2-way dot instructions (FEAT_FP8DOT2)", [FeatureFP8DOT4]>;
+def FeatureFP8DOT2: ExtensionWithMArch<"fp8dot2", "FP8DOT2", "FEAT_FP8DOT2",
+  "Enable fp8 2-way dot instructions", [FeatureFP8DOT4]>;
 
-def FeatureSSVE_FP8DOT4 : Extension<"ssve-fp8dot4", "SSVE_FP8DOT4",
-  "Enable SVE2 fp8 4-way dot product instructions (FEAT_SSVE_FP8DOT4)", [FeatureSSVE_FP8FMA]>;
+def FeatureSSVE_FP8DOT4 : ExtensionWithMArch<"ssve-fp8dot4", "SSVE_FP8DOT4", "FEAT_SSVE_FP8DOT4",
+  "Enable SVE2 fp8 4-way dot product instructions", [FeatureSSVE_FP8FMA]>;
 
-def FeatureSSVE_FP8DOT2 : Extension<"ssve-fp8dot2", "SSVE_FP8DOT2",
-  "Enable SVE2 fp8 2-way dot product instructions (FEAT_SSVE_FP8DOT2)", [FeatureSSVE_FP8DOT4]>;
+def FeatureSSVE_FP8DOT2 : ExtensionWithMArch<"ssve-fp8dot2", "SSVE_FP8DOT2", "FEAT_SSVE_FP8DOT2",
+  "Enable SVE2 fp8 2-way dot product instructions", [FeatureSSVE_FP8DOT4]>;
 
-def FeatureSME_LUTv2 : Extension<"sme-lutv2", "SME_LUTv2",
-  "Enable Scalable Matrix Extension (SME) LUTv2 instructions (FEAT_SME_LUTv2)">;
+def FeatureSME_LUTv2 : ExtensionWithMArch<"sme-lutv2", "SME_LUTv2", "FEAT_SME_LUTv2",
+  "Enable Scalable Matrix Extension (SME) LUTv2 instructions">;
 
-def FeatureSMEF8F32 : Extension<"sme-f8f32", "SMEF8F32",
-  "Enable Scalable Matrix Extension (SME) F8F32 instructions (FEAT_SME_F8F32)", [FeatureSME2, FeatureFP8]>;
+def FeatureSMEF8F32 : ExtensionWithMArch<"sme-f8f32", "SMEF8F32", "FEAT_SME_F8F32",
+  "Enable Scalable Matrix Extension (SME) F8F32 instructions", [FeatureSME2, FeatureFP8]>;
 
-def FeatureSMEF8F16 : Extension<"sme-f8f16", "SMEF8F16",
-  "Enable Scalable Matrix Extension (SME) F8F16 instructions(FEAT_SME_F8F16)", [FeatureSMEF8F32]>;
+def FeatureSMEF8F16 : ExtensionWithMArch<"sme-f8f16", "SMEF8F16", "FEAT_SME_F8F16",
+  "Enable Scalable Matrix Extension (SME) F8F16 instructions", [FeatureSMEF8F32]>;
 
-def FeatureCPA : Extension<"cpa", "CPA",
-    "Enable Armv9.5-A Checked Pointer Arithmetic (FEAT_CPA)">;
+def FeatureCPA : ExtensionWithMArch<"cpa", "CPA", "FEAT_CPA",
+  "Enable Armv9.5-A Checked Pointer Arithmetic">;
 
-def FeaturePAuthLR : Extension<"pauth-lr", "PAuthLR",
-    "Enable Armv9.5-A PAC enhancements (FEAT_PAuth_LR)">;
+def FeaturePAuthLR : ExtensionWithMArch<"pauth-lr", "PAuthLR", "FEAT_PAuth_LR",
+  "Enable Armv9.5-A PAC enhancements">;
 
-def FeatureTLBIW : Extension<"tlbiw", "TLBIW",
-  "Enable ARMv9.5-A TLBI VMALL for Dirty State (FEAT_TLBIW)">;
+def FeatureTLBIW : ExtensionWithMArch<"tlbiw", "TLBIW", "FEAT_TLBIW",
+  "Enable ARMv9.5-A TLBI VMALL for Dirty State">;
 
 //===----------------------------------------------------------------------===//
 //  Other Features
diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp
index 7986f07538df7..2dde4d2b7e2a3 100644
--- a/llvm/lib/TargetParser/AArch64TargetParser.cpp
+++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp
@@ -18,6 +18,7 @@
 #include "llvm/TargetParser/ARMTargetParserCommon.h"
 #include "llvm/TargetParser/Triple.h"
 #include <cctype>
+#include <vector>
 
 #define DEBUG_TYPE "target-parser"
 
@@ -61,8 +62,8 @@ bool AArch64::getExtensionFeatures(
     std::vector<StringRef> &Features) {
   for (const auto &E : Extensions)
     /* INVALID and NONE have no feature name. */
-    if (InputExts.test(E.ID) && !E.Feature.empty())
-      Features.push_back(E.Feature);
+    if (InputExts.test(E.ID) && !E.PosTargetFeature.empty())
+      Features.push_back(E.PosTargetFeature);
 
   return true;
 }
@@ -79,8 +80,8 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
   StringRef ArchExtBase = IsNegated ? ArchExt.drop_front(2) : ArchExt;
 
   if (auto AE = parseArchExtension(ArchExtBase)) {
-    assert(!(AE.has_value() && AE->NegFeature.empty()));
-    return IsNegated ? AE->NegFeature : AE->Feature;
+    assert(!(AE.has_value() && AE->NegTargetFeature.empty()));
+    return IsNegated ? AE->NegTargetFeature : AE->PosTargetFeature;
   }
 
   return StringRef();
@@ -115,8 +116,10 @@ const AArch64::ArchInfo *AArch64::parseArch(StringRef Arch) {
 
 std::optional<AArch64::ExtensionInfo>
 AArch64::parseArchExtension(StringRef ArchExt) {
+  if (ArchExt.empty())
+    return {};
   for (const auto &A : Extensions) {
-    if (ArchExt == A.Name || ArchExt == A.Alias)
+    if (ArchExt == A.UserVisibleName || ArchExt == A.Alias)
       return A;
   }
   return {};
@@ -137,7 +140,7 @@ std::optional<AArch64::FMVInfo> AArch64::parseFMVExtension(StringRef FMVExt) {
 std::optional<AArch64::ExtensionInfo>
 AArch64::targetFeatureToExtension(StringRef TargetFeature) {
   for (const auto &E : Extensions)
-    if (TargetFeature == E.Feature)
+    if (TargetFeature == E.PosTargetFeature)
       return E;
   return {};
 }
@@ -154,21 +157,48 @@ std::optional<AArch64::CpuInfo> AArch64::parseCpu(StringRef Name) {
   return {};
 }
 
-void AArch64::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
+void AArch64::PrintSupportedExtensions() {
   outs() << "All available -march extensions for AArch64\n\n"
          << "    " << left_justify("Name", 20)
-         << (DescMap.empty() ? "\n" : "Description\n");
+         << left_justify("Architecture Feature(s)", 55)
+         << "Description\n";
   for (const auto &Ext : Extensions) {
     // Extensions without a feature cannot be used with -march.
-    if (!Ext.Feature.empty()) {
-      std::string Description = DescMap[Ext.Name].str();
+    if (!Ext.UserVisibleName.empty() && !Ext.PosTargetFeature.empty()) {
       outs() << "    "
-             << format(Description.empty() ? "%s\n" : "%-20s%s\n",
-                       Ext.Name.str().c_str(), Description.c_str());
+             << format(Ext.Description.empty() ? "%-20s%s\n" : "%-20s%-55s%s\n",
+                       Ext.UserVisibleName.str().c_str(),
+                       Ext.ArchFeatureName.str().c_str(),
+                       Ext.Description.str().c_str());
     }
   }
 }
 
+void
+AArch64::printEnabledExtensions(std::set<StringRef> EnabledFeatureNames) {
+  outs() << "Extensions enabled for the given AArch64 target\n\n"
+         << "    " << left_justify("Architecture Feature(s)", 55)
+         << "Description\n";
+  std::vector<ExtensionInfo> EnabledExtensionsInfo;
+  for (const auto &FeatureName : EnabledFeatureNames) {
+    std::string PosFeatureName = '+' + FeatureName.str();
+    if (auto ExtInfo = targetFeatureToExtension(PosFeatureName))
+      EnabledExtensionsInfo.push_back(*ExtInfo);
+  }
+
+  std::sort(EnabledExtensionsInfo.begin(), EnabledExtensionsInfo.end(),
+            [](const ExtensionInfo &Lhs, const ExtensionInfo &Rhs) {
+              return Lhs.ArchFeatureName < Rhs.ArchFeatureName;
+            });
+
+  for (const auto &Ext : EnabledExtensionsInfo) {
+    outs() << "    "
+           << format("%-55s%s\n",
+                     Ext.ArchFeatureName.str().c_str(),
+                     Ext.Description.str().c_str());
+  }
+}
+
 const llvm::AArch64::ExtensionInfo &
 lookupExtensionByID(llvm::AArch64::ArchExtKind ExtID) {
   for (const auto &E : llvm::AArch64::Extensions)
@@ -181,7 +211,7 @@ void AArch64::ExtensionSet::enable(ArchExtKind E) {
   if (Enabled.test(E))
     return;
 
-  LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).Name << "\n");
+  LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).UserVisibleName << "\n");
 
   Touched.set(E);
   Enabled.set(E);
@@ -222,7 +252,7 @@ void AArch64::ExtensionSet::disable(ArchExtKind E) {
   if (!Enabled.test(E))
     return;
 
-  LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).Name << "\n");
+  LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).UserVisibleName << "\n");
 
   Touched.set(E);
   Enabled.reset(E);
@@ -266,7 +296,7 @@ bool AArch64::ExtensionSet::parseModifier(StringRef Modifier,
   StringRef ArchExt = Modifier.drop_front(NChars);
 
   if (auto AE = parseArchExtension(ArchExt)) {
-    if (AE->Feature.empty() || AE->NegFeature.empty())
+    if (AE->PosTargetFeature.empty() || AE->NegTargetFeature.empty())
       return false;
     if (IsNegated)
       disable(AE->ID);
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 553f5df7827e2..fe20099382859 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1130,7 +1130,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_MTE,         AArch64::AEK_SSBS,
                  AArch64::AEK_FP16,        AArch64::AEK_FP16FML,
                  AArch64::AEK_SB,          AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_AM}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a520", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1147,7 +1148,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
-                 AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PERFMON,     AArch64::AEK_AM,
+                 AArch64::AEK_ETE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a520ae", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1164,7 +1166,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
-                 AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PERFMON,     AArch64::AEK_AM,
+                 AArch64::AEK_ETE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
@@ -1279,7 +1282,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PAUTH,   AArch64::AEK_FLAGM,
                  AArch64::AEK_SB,      AArch64::AEK_I8MM,
                  AArch64::AEK_BF16,    AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a715", "armv9-a", "neon-fp-armv8",
@@ -1296,7 +1300,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PREDRES, AArch64::AEK_PROFILE,
                  AArch64::AEK_FP16FML, AArch64::AEK_FP16,
                  AArch64::AEK_FLAGM,   AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,     AArch64::AEK_TRBE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a720", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1313,7 +1318,9 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
+                 AArch64::AEK_TRBE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a720ae", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1330,7 +1337,9 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
+                 AArch64::AEK_TRBE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a725", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1347,7 +1356,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_ETE,
+                 AArch64::AEK_SPE_EEF,     AArch64::AEK_TRBE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
@@ -1364,7 +1374,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PROFILE, AArch64::AEK_RAND,
                  AArch64::AEK_FP16FML, AArch64::AEK_I8MM,
                  AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON,
+                 AArch64::AEK_CCDP}),
             "8.4-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-v2", "armv9-a", "neon-fp-armv8",
@@ -1380,7 +1391,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_FP16FML,     AArch64::AEK_I8MM,
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_RAND,
                  AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,       AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,       AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-v3", "armv9.2-a", "neon-fp-armv8",
@@ -1399,7 +1411,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PERFMON,     AArch64::AEK_RAND,
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-v3ae", "armv9.2-a", "neon-fp-armv8",
@@ -1418,7 +1431,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PERFMON,     AArch64::AEK_RAND,
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-r82", "armv8-r", "crypto-neon-fp-armv8",
@@ -1429,7 +1443,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RCPC, AArch64::AEK_LSE, AArch64::AEK_SB,
                  AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH,
                  AArch64::AEK_FLAGM, AArch64::AEK_PERFMON,
-                 AArch64::AEK_PREDRES}),
+                 AArch64::AEK_PREDRES, AArch64::AEK_CCDP}),
             "8-R"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-r82ae", "armv8-r", "crypto-neon-fp-armv8",
@@ -1440,7 +1454,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RCPC, AArch64::AEK_LSE, AArch64::AEK_SB,
                  AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH,
                  AArch64::AEK_FLAGM, AArch64::AEK_PERFMON,
-                 AArch64::AEK_PREDRES}),
+                 AArch64::AEK_PREDRES, AArch64::AEK_CCDP}),
             "8-R"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
@@ -1459,7 +1473,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
                  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
                  AArch64::AEK_PAUTH, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM,
-                 AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PERFMON, AArch64::AEK_LSE2, AArch64::AEK_RCPC_IMMO}),
             "8.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-x2", "armv9-a", "neon-fp-armv8",
@@ -1475,7 +1489,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SB,          AArch64::AEK_FP16,
                  AArch64::AEK_FP16FML,     AArch64::AEK_FLAGM,
                  AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
-                 AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PERFMON,     AArch64::AEK_AM,
+                 AArch64::AEK_ETE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-x3", "armv9-a", "neon-fp-armv8",
@@ -1492,7 +1507,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_FP16,    AArch64::AEK_FP16FML,
                  AArch64::AEK_PREDRES, AArch64::AEK_FLAGM,
                  AArch64::AEK_SSBS,    AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,    AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,     AArch64::AEK_TRBE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-x4", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1509,7 +1525,9 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
+                 AArch64::AEK_TRBE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-x925", "armv9.2-a", "crypto-neon-fp-armv8",
@@ -1526,7 +1544,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
                  AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
                  AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
-                 AArch64::AEK_FCMA}),
+                 AArch64::AEK_FCMA,        AArch64::AEK_ETE,
+                 AArch64::AEK_SPE_EEF,     AArch64::AEK_TRBE}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cyclone", "armv8-a", "crypto-neon-fp-armv8",
@@ -1557,7 +1576,8 @@ INSTANTIATE_TEST_SUITE_P(
             AArch64::ExtensionBitset({AArch64::AEK_CRC, AArch64::AEK_AES,
                                       AArch64::AEK_SHA2, AArch64::AEK_FP,
                                       AArch64::AEK_RDM, AArch64::AEK_SIMD,
-                                      AArch64::AEK_PERFMON}),
+                                      AArch64::AEK_PERFMON, AArch64::AEK_PAN,
+                                      AArch64::AEK_LOR, AArch64::AEK_VH}),
             "8-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
@@ -1617,7 +1637,9 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
                  AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON,
                  AArch64::AEK_PREDRES, AArch64::AEK_SB,
-                 AArch64::AEK_SSBS}),
+                 AArch64::AEK_SSBS,    AArch64::AEK_CCDP,
+                 AArch64::AEK_FRINT3264, AArch64::AEK_SPECRESTRICT,
+                 AArch64::AEK_ALTERNATIVENZCV}),
             "8.4-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-m1", "armv8.4-a", "crypto-neon-fp-armv8",
@@ -1632,7 +1654,9 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
                  AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON,
                  AArch64::AEK_PREDRES, AArch64::AEK_SB,
-                 AArch64::AEK_SSBS}),
+                 AArch64::AEK_SSBS,    AArch64::AEK_CCDP,
+                 AArch64::AEK_FRINT3264, AArch64::AEK_SPECRESTRICT,
+                 AArch64::AEK_ALTERNATIVENZCV}),
             "8.6-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-a15", "armv8.6-a", "crypto-neon-fp-armv8",
@@ -1665,7 +1689,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
                  AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
                  AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
             "8.4-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-m3", "armv8.6-a", "crypto-neon-fp-armv8",
@@ -1676,7 +1700,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
                  AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
                  AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
             "8.6-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-a17", "armv8.6-a", "crypto-neon-fp-armv8",
@@ -1687,7 +1711,7 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
                  AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
                  AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
             "8.6-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "apple-m4", "armv8.7-a", "crypto-neon-fp-armv8",
@@ -1771,7 +1795,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16,
                  AArch64::AEK_I8MM,        AArch64::AEK_JSCVT,
                  AArch64::AEK_FCMA,        AArch64::AEK_PAUTH,
-                 AArch64::AEK_FP16FML,     AArch64::AEK_PERFMON}),
+                 AArch64::AEK_FP16FML,     AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,         AArch64::AEK_TRBE}),
             "9-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-n3", "armv9.2-a", "neon-fp-armv8",
@@ -1789,7 +1814,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_FLAGM,   AArch64::AEK_PERFMON,
                  AArch64::AEK_RAND,    AArch64::AEK_SVE2BITPERM,
                  AArch64::AEK_FP16FML, AArch64::AEK_PROFILE,
-                 AArch64::AEK_JSCVT,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_JSCVT,   AArch64::AEK_PERFMON,
+                 AArch64::AEK_ETE,     AArch64::AEK_SPE_EEF}),
             "9.2-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "ampere1", "armv8.6-a", "crypto-neon-fp-armv8",
@@ -1824,7 +1850,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_SHA2,  AArch64::AEK_AES,   AArch64::AEK_I8MM,
                  AArch64::AEK_SSBS,  AArch64::AEK_SB,    AArch64::AEK_RAND,
                  AArch64::AEK_MTE,   AArch64::AEK_JSCVT, AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH, AArch64::AEK_CSSC,  AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH, AArch64::AEK_CSSC,  AArch64::AEK_PERFMON,
+                 AArch64::AEK_WFXT}),
             "8.7-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-512tvb", "armv8.4-a", "crypto-neon-fp-armv8",
@@ -1841,7 +1868,8 @@ INSTANTIATE_TEST_SUITE_P(
                  AArch64::AEK_PROFILE, AArch64::AEK_RAND,
                  AArch64::AEK_FP16FML, AArch64::AEK_I8MM,
                  AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
-                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
+                 AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON,
+                 AArch64::AEK_CCDP}),
             "8.4-A"),
         ARMCPUTestParams<AArch64::ExtensionBitset>(
             "thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
@@ -2352,17 +2380,11 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
 TEST(TargetParserTest, AArch64PrintSupportedExtensions) {
   std::string expected =
       "All available -march extensions for AArch64\n\n"
-      "    Name                Description\n"
-      "    aes                 This is a long dummy description\n"
-      "    b16b16\n"
-      "    bf16\n";
-
-  StringMap<StringRef> DummyMap;
-  DummyMap["aes"] = "This is a long dummy description";
+      "    Name                Architecture Feature(s)                                Description\n";
 
   outs().flush();
   testing::internal::CaptureStdout();
-  AArch64::PrintSupportedExtensions(DummyMap);
+  AArch64::PrintSupportedExtensions();
   outs().flush();
   std::string captured = testing::internal::GetCapturedStdout();
 
@@ -2378,6 +2400,23 @@ TEST(TargetParserTest, AArch64PrintSupportedExtensions) {
   EXPECT_EQ(std::string::npos, captured.find("ssbs2"));
 }
 
+TEST(TargetParserTest, AArch64PrintEnabledExtensions) {
+  // Pick a single enabled extension to validate formatting
+  std::set<StringRef> EnabledExtensions = {"crc"};
+  std::string ExpectedOutput =
+      "Extensions enabled for the given AArch64 target\n\n"
+      "    Architecture Feature(s)                                Description\n"
+      "    FEAT_CRC32                                             Enable ARMv8 CRC-32 checksum instructions\n";
+
+  outs().flush();
+  testing::internal::CaptureStdout();
+  AArch64::printEnabledExtensions(EnabledExtensions);
+  outs().flush();
+  std::string CapturedOutput = testing::internal::GetCapturedStdout();
+
+  EXPECT_EQ(CapturedOutput, ExpectedOutput);
+}
+
 struct AArch64ExtensionDependenciesBaseArchTestParams {
   const llvm::AArch64::ArchInfo &Arch;
   std::vector<StringRef> Modifiers;
diff --git a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
index e22f353b451f9..0a9370279410d 100644
--- a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
@@ -41,9 +41,9 @@ static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) {
   std::vector<Record *> SortedExtensions =
       RK.getAllDerivedDefinitions("Extension");
   auto Alphabetical = [](Record *A, Record *B) -> bool {
-    const auto MarchA = A->getValueAsString("MArchName");
-    const auto MarchB = B->getValueAsString("MArchName");
-    return MarchA.compare(MarchB) < 0; // A lexographically less than B
+    const auto NameA = A->getValueAsString("Name");
+    const auto NameB = B->getValueAsString("Name");
+    return NameA.compare(NameB) < 0; // A lexographically less than B
   };
   std::sort(SortedExtensions.begin(), SortedExtensions.end(), Alphabetical);
 
@@ -95,17 +95,19 @@ static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) {
   for (const Record *Rec : SortedExtensions) {
     auto AEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
     OS << "  ";
-    OS << "{\"" << Rec->getValueAsString("MArchName") << "\"";
-    if (auto Alias = Rec->getValueAsString("MArchAlias"); Alias.empty())
+    OS << "{\"" << Rec->getValueAsString("UserVisibleName") << "\"";
+    if (auto Alias = Rec->getValueAsString("UserVisibleAlias"); Alias.empty())
       OS << ", {}";
     else
       OS << ", \"" << Alias << "\"";
     OS << ", AArch64::" << AEK;
+    OS << ", \"" << Rec->getValueAsString("ArchFeatureName") << "\"";
+    OS << ", \"" << Rec->getValueAsString("Desc") << "\"";
     OS << ", \"+" << Rec->getValueAsString("Name") << "\""; // posfeature
     OS << ", \"-" << Rec->getValueAsString("Name") << "\""; // negfeature
     OS << "},\n";
   };
-  OS << "  {\"none\", {}, AArch64::AEK_NONE, {}, {} },\n";
+  OS << "  {\"none\", {}, AArch64::AEK_NONE, {}, {}, {}, {} },\n";
   OS << "};\n"
      << "#undef EMIT_EXTENSIONS\n"
      << "#endif // EMIT_EXTENSIONS\n"



More information about the cfe-commits mailing list