[clang] [flang] [llvm] [AArch64][Driver] Better handling of target feature dependencies (PR #78270)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 08:00:36 PST 2024


https://github.com/ostannard updated https://github.com/llvm/llvm-project/pull/78270

>From ebd6e9a2a9b80ca492f294b9f8468c20fb30005a Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Mon, 15 Jan 2024 14:14:10 +0000
Subject: [PATCH 1/6] [AArch64][Driver] Better handling of target feature
 dependencies

Currently there are several bits of code in the AArch64 driver which
attempt to enforce dependencies between optional features in the -march=
and -mcpu= options. However, these are based on the list of feature
names being enabled/disabled, so they have a lot of logic to consider
the order in which features were turned on and off, which doesn't scale
well as dependency chains get longer.

This patch moves the code handling these dependencies to TargetParser,
and changes them to use a Bitset of enabled features. This makes it easy
to check which features are enabled, and is converted back to a list of
LLVM feature names once all of the command-line options are parsed.

The motivating example for this was the -mcpu=cortex-r82+nofp option.
Previously, the code handling the dependency between the fp16 and
fp16fml extensions did not consider the nofp modifier, so it added
+fullfp16 to the feature list. This should have been disabled by the
+nofp modifier, and also the backend did follow the dependency between
fullfp16 and fp, resulting in fp being turned back on in the backend.

Most of the dependencies added to AArch64TargetParser.h weren't known
about by clang before, I built that list by checking what the backend
thinks the dependencies between SubtargetFeatures are.
---
 clang/lib/Basic/Targets/AArch64.cpp           |   3 +-
 clang/lib/Driver/ToolChains/Arch/AArch64.cpp  | 281 +++------------
 clang/test/Driver/aarch64-bf16.c              |   2 +-
 clang/test/Driver/aarch64-cortex-a510.c       |   2 +-
 clang/test/Driver/aarch64-cortex-a710.c       |   2 +-
 clang/test/Driver/aarch64-cortex-x2.c         |   2 +-
 clang/test/Driver/aarch64-d128.c              |   3 +-
 clang/test/Driver/aarch64-fp16.c              |  50 +--
 .../Driver/aarch64-implied-sme-features.c     |  26 +-
 .../Driver/aarch64-implied-sve-features.c     |  39 +-
 clang/test/Driver/aarch64-ite.c               |   5 +-
 clang/test/Driver/aarch64-lrcpc3.c            |   9 +-
 clang/test/Driver/aarch64-ls64.c              |   3 +-
 clang/test/Driver/aarch64-lse128.c            |   3 +-
 clang/test/Driver/aarch64-march.c             |  10 +-
 .../test/Driver/aarch64-mgeneral_regs_only.c  |   1 -
 clang/test/Driver/aarch64-mte.c               |   4 +-
 clang/test/Driver/aarch64-perfmon.c           |   7 +-
 clang/test/Driver/aarch64-predres.c           |   3 +-
 clang/test/Driver/aarch64-rand.c              |   3 +-
 clang/test/Driver/aarch64-ras.c               |  13 +-
 clang/test/Driver/aarch64-rdm.c               |   6 +-
 clang/test/Driver/aarch64-ssbs.c              |   2 +-
 clang/test/Driver/aarch64-sve2.c              |   2 +-
 clang/test/Driver/aarch64-the.c               |   2 +-
 clang/test/Driver/aarch64-v81a.c              |   6 +-
 clang/test/Driver/aarch64-v82a.c              |   4 +-
 clang/test/Driver/aarch64-v83a.c              |   4 +-
 clang/test/Driver/aarch64-v84a.c              |   4 +-
 clang/test/Driver/aarch64-v85a.c              |   4 +-
 clang/test/Driver/aarch64-v86a.c              |   4 +-
 clang/test/Driver/aarch64-v87a.c              |   4 +-
 clang/test/Driver/aarch64-v88a.c              |   4 +-
 clang/test/Driver/aarch64-v89a.c              |   4 +-
 clang/test/Driver/aarch64-v91a.c              |   4 +-
 clang/test/Driver/aarch64-v92a.c              |   4 +-
 clang/test/Driver/aarch64-v93a.c              |   4 +-
 clang/test/Driver/aarch64-v94a.c              |   4 +-
 clang/test/Driver/aarch64-v95a.c              |  10 +-
 clang/test/Driver/arm-sb.c                    |   4 +-
 .../Preprocessor/aarch64-target-features.c    |  97 +++--
 .../llvm/TargetParser/AArch64TargetParser.h   | 106 +++++-
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |   4 +-
 llvm/lib/TargetParser/AArch64TargetParser.cpp | 149 +++++++-
 .../TargetParser/TargetParserTest.cpp         | 339 +++++++++++++++++-
 45 files changed, 811 insertions(+), 435 deletions(-)

diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 9ebaf4d40cd7e5..32e7a0276cd80e 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1093,8 +1093,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
       FoundArch = true;
       std::pair<StringRef, StringRef> Split =
           Feature.split("=").second.trim().split("+");
-      const std::optional<llvm::AArch64::ArchInfo> AI =
-          llvm::AArch64::parseArch(Split.first);
+      const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
 
       // Parse the architecture version, adding the required features to
       // Ret.Features.
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 912df79417ae21..5037b669da51ce 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -67,103 +67,45 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
 
 // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
 static bool DecodeAArch64Features(const Driver &D, StringRef text,
-                                  std::vector<StringRef> &Features,
-                                  const llvm::AArch64::ArchInfo &ArchInfo) {
+                                  llvm::AArch64::ExtensionSet &Extensions) {
   SmallVector<StringRef, 8> Split;
   text.split(Split, StringRef("+"), -1, false);
 
   for (StringRef Feature : Split) {
-    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
-    if (!FeatureName.empty())
-      Features.push_back(FeatureName);
-    else if (Feature == "neon" || Feature == "noneon")
+    if (Feature == "neon" || Feature == "noneon") {
       D.Diag(clang::diag::err_drv_no_neon_modifier);
-    else
-      return false;
-
-    // +sme implies +bf16.
-    // +sme-f64f64 and +sme-i16i64 both imply +sme.
-    if (Feature == "sme") {
-      Features.push_back("+bf16");
-    } else if (Feature == "nosme") {
-      Features.push_back("-sme-f64f64");
-      Features.push_back("-sme-i16i64");
-    } else if (Feature == "sme-f64f64") {
-      Features.push_back("+sme");
-      Features.push_back("+bf16");
-    } else if (Feature == "sme-i16i64") {
-      Features.push_back("+sme");
-      Features.push_back("+bf16");
-    } else if (Feature == "nobf16") {
-      Features.push_back("-sme");
-      Features.push_back("-sme-f64f64");
-      Features.push_back("-sme-i16i64");
-    }
-
-    if (Feature == "sve2")
-      Features.push_back("+sve");
-    else if (Feature == "sve2-bitperm" || Feature == "sve2-sha3" ||
-             Feature == "sve2-aes" || Feature == "sve2-sm4") {
-      Features.push_back("+sve");
-      Features.push_back("+sve2");
-    } else if (Feature == "nosve") {
-      Features.push_back("-sve2");
-      Features.push_back("-sve2-bitperm");
-      Features.push_back("-sve2-sha3");
-      Features.push_back("-sve2-aes");
-      Features.push_back("-sve2-sm4");
-    } else if (Feature == "nosve2") {
-      Features.push_back("-sve2-bitperm");
-      Features.push_back("-sve2-sha3");
-      Features.push_back("-sve2-aes");
-      Features.push_back("-sve2-sm4");
+      continue;
     }
-
-    // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
-    // It isn't the case in general that sve implies both f64mm and f32mm
-    if ((ArchInfo == llvm::AArch64::ARMV8_6A ||
-         ArchInfo == llvm::AArch64::ARMV8_7A ||
-         ArchInfo == llvm::AArch64::ARMV8_8A ||
-         ArchInfo == llvm::AArch64::ARMV8_9A ||
-         ArchInfo == llvm::AArch64::ARMV9_1A ||
-         ArchInfo == llvm::AArch64::ARMV9_2A ||
-         ArchInfo == llvm::AArch64::ARMV9_3A ||
-         ArchInfo == llvm::AArch64::ARMV9_4A) &&
-        Feature == "sve")
-      Features.push_back("+f32mm");
+    if (!Extensions.parseModifier(Feature))
+      return false;
   }
+
   return true;
 }
 
 // Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
 // decode CPU and feature.
 static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
-                              std::vector<StringRef> &Features) {
+                              llvm::AArch64::ExtensionSet &Extensions) {
   std::pair<StringRef, StringRef> Split = Mcpu.split("+");
   CPU = Split.first;
-  const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
 
   if (CPU == "native")
     CPU = llvm::sys::getHostCPUName();
 
   if (CPU == "generic") {
-    Features.push_back("+neon");
+    Extensions.enable(llvm::AArch64::AEK_SIMD);
   } else {
     const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
         llvm::AArch64::parseCpu(CPU);
     if (!CpuInfo)
       return false;
-    ArchInfo = &CpuInfo->Arch;
 
-    Features.push_back(ArchInfo->ArchFeature);
-
-    auto Extension = CpuInfo->getImpliedExtensions();
-    if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
-      return false;
+    Extensions.addCPUDefaults(*CpuInfo);
   }
 
   if (Split.second.size() &&
-      !DecodeAArch64Features(D, Split.second, Features, *ArchInfo))
+      !DecodeAArch64Features(D, Split.second, Extensions))
     return false;
 
   return true;
@@ -172,30 +114,21 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
 static bool
 getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
                                 const ArgList &Args,
-                                std::vector<StringRef> &Features) {
+                                llvm::AArch64::ExtensionSet &Extensions) {
   std::string MarchLowerCase = March.lower();
   std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
 
-  std::optional <llvm::AArch64::ArchInfo> ArchInfo =
+  const llvm::AArch64::ArchInfo *ArchInfo =
       llvm::AArch64::parseArch(Split.first);
   if (Split.first == "native")
     ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
   if (!ArchInfo)
     return false;
-  Features.push_back(ArchInfo->ArchFeature);
-
-  // Enable SVE2 by default on Armv9-A.
-  // It can still be disabled if +nosve2 is present.
-  // We must do this early so that DecodeAArch64Features has the correct state
-  if ((*ArchInfo == llvm::AArch64::ARMV9A ||
-       *ArchInfo == llvm::AArch64::ARMV9_1A ||
-       *ArchInfo == llvm::AArch64::ARMV9_2A)) {
-    Features.push_back("+sve");
-    Features.push_back("+sve2");
-  }
+
+  Extensions.addArchDefaults(*ArchInfo);
 
   if ((Split.second.size() &&
-       !DecodeAArch64Features(D, Split.second, Features, *ArchInfo)))
+       !DecodeAArch64Features(D, Split.second, Extensions)))
     return false;
 
   return true;
@@ -204,10 +137,10 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
 static bool
 getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
                                const ArgList &Args,
-                               std::vector<StringRef> &Features) {
+                               llvm::AArch64::ExtensionSet &Extensions) {
   StringRef CPU;
   std::string McpuLowerCase = Mcpu.lower();
-  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
+  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Extensions))
     return false;
 
   return true;
@@ -218,10 +151,10 @@ getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
                                      const ArgList &Args,
                                      std::vector<StringRef> &Features) {
   std::string MtuneLowerCase = Mtune.lower();
-  // Check CPU name is valid
-  std::vector<StringRef> MtuneFeatures;
+  // Check CPU name is valid, but ignore any extensions on it.
+  llvm::AArch64::ExtensionSet Extensions;
   StringRef Tune;
-  if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
+  if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, Extensions))
     return false;
 
   // Handle CPU name is 'native'.
@@ -240,7 +173,8 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
                                     const ArgList &Args,
                                     std::vector<StringRef> &Features) {
   StringRef CPU;
-  std::vector<StringRef> DecodedFeature;
+  // Check CPU name is valid, but ignore any extensions on it.
+  llvm::AArch64::ExtensionSet DecodedFeature;
   std::string McpuLowerCase = Mcpu.lower();
   if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
     return false;
@@ -255,9 +189,8 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
                                        bool ForAS) {
   Arg *A;
   bool success = true;
-  // Enable NEON by default.
-  Features.push_back("+neon");
   llvm::StringRef WaMArch;
+  llvm::AArch64::ExtensionSet Extensions;
   if (ForAS)
     for (const auto *A :
          Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
@@ -268,17 +201,17 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
   // "-Xassembler -march" is detected. Otherwise it may return false
   // and causes Clang to error out.
   if (!WaMArch.empty())
-    success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features);
+    success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Extensions);
   else if ((A = Args.getLastArg(options::OPT_march_EQ)))
-    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
+    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Extensions);
   else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
-    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
+    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions);
   else if (isCPUDeterminedByTriple(Triple))
     success = getAArch64ArchFeaturesFromMcpu(
-        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
+        D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions);
   else
     // Default to 'A' profile if the architecture is not specified.
-    success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features);
+    success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Extensions);
 
   if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
     success =
@@ -300,12 +233,23 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
       Diag << A->getSpelling() << A->getValue();
   }
 
+  // -mgeneral-regs-only disables all floating-point features.
   if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
-    Features.push_back("-fp-armv8");
-    Features.push_back("-crypto");
-    Features.push_back("-neon");
+    Extensions.disable(llvm::AArch64::AEK_FP);
+  }
+
+  // En/disable crc
+  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
+    if (A->getOption().matches(options::OPT_mcrc))
+      Extensions.enable(llvm::AArch64::AEK_CRC);
+    else
+      Extensions.disable(llvm::AArch64::AEK_CRC);
   }
 
+  // At this point all hardware features are decided, so convert the extensions
+  // set to a feature list.
+  Extensions.toLLVMFeatureList(Features);
+
   if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
     StringRef Mtp = A->getValue();
     if (Mtp == "el3" || Mtp == "tpidr_el3")
@@ -367,147 +311,6 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
     }
   }
 
-  // En/disable crc
-  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
-    if (A->getOption().matches(options::OPT_mcrc))
-      Features.push_back("+crc");
-    else
-      Features.push_back("-crc");
-  }
-
-  int V8Version = -1;
-  int V9Version = -1;
-  bool HasNoSM4 = false;
-  bool HasNoSHA3 = false;
-  bool HasNoSHA2 = false;
-  bool HasNoAES = false;
-  bool HasSM4 = false;
-  bool HasSHA3 = false;
-  bool HasSHA2 = false;
-  bool HasAES = false;
-  bool HasCrypto = false;
-  bool HasNoCrypto = false;
-  int FullFP16Pos = -1;
-  int NoFullFP16Pos = -1;
-  int FP16FMLPos = -1;
-  int NoFP16FMLPos = -1;
-  int ArchFeatPos = -1;
-
-  for (auto I = Features.begin(), E = Features.end(); I != E; I++) {
-    if (*I == "+v8a")   V8Version = 0;
-    else if (*I == "+v8.1a") V8Version = 1;
-    else if (*I == "+v8.2a") V8Version = 2;
-    else if (*I == "+v8.3a") V8Version = 3;
-    else if (*I == "+v8.4a") V8Version = 4;
-    else if (*I == "+v8.5a") V8Version = 5;
-    else if (*I == "+v8.6a") V8Version = 6;
-    else if (*I == "+v8.7a") V8Version = 7;
-    else if (*I == "+v8.8a") V8Version = 8;
-    else if (*I == "+v8.9a") V8Version = 9;
-    else if (*I == "+v9a")   V9Version = 0;
-    else if (*I == "+v9.1a") V9Version = 1;
-    else if (*I == "+v9.2a") V9Version = 2;
-    else if (*I == "+v9.3a") V9Version = 3;
-    else if (*I == "+v9.4a") V9Version = 4;
-    else if (*I == "+v9.5a") V9Version = 5;
-    else if (*I == "+sm4")  HasSM4 = true;
-    else if (*I == "+sha3") HasSHA3 = true;
-    else if (*I == "+sha2") HasSHA2 = true;
-    else if (*I == "+aes")  HasAES = true;
-    else if (*I == "-sm4")  HasNoSM4 = true;
-    else if (*I == "-sha3") HasNoSHA3 = true;
-    else if (*I == "-sha2") HasNoSHA2 = true;
-    else if (*I == "-aes")  HasNoAES = true;
-    else if (*I == "+fp16fml")  FP16FMLPos = I - Features.begin();
-    else if (*I == "-fp16fml")  NoFP16FMLPos = I - Features.begin();
-    else if (*I == "-fullfp16") NoFullFP16Pos = I - Features.begin();
-    else if (*I == "+fullfp16") FullFP16Pos = I - Features.begin();
-    // Whichever option comes after (right-most option) will win
-    else if (*I == "+crypto") {
-      HasCrypto = true;
-      HasNoCrypto = false;
-    } else if (*I == "-crypto" || *I == "-neon") {
-      HasCrypto = false;
-      HasNoCrypto = true;
-      HasSM4 = HasSHA2 = HasSHA3 = HasAES = false;
-    }
-    // Register the iterator position if this is an architecture feature
-    if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1))
-      ArchFeatPos = I - Features.begin();
-  }
-
-  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
-  // FIXME: this fp16fml option handling will be reimplemented after the
-  // TargetParser rewrite.
-  if (V8Version >= 4) {
-    // "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" "-fp16fml" = "+fp16fml"
-    if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos && FullFP16Pos > NoFP16FMLPos)
-      // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
-      // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
-      Features.push_back("+fp16fml");
-    else
-      goto fp16_fml_fallthrough;
-  } else {
-fp16_fml_fallthrough:
-    // In both of these cases, putting the 'other' feature on the end of the vector will
-    // result in the same effect as placing it immediately after the current feature.
-    // "+fp16fml"  "-fullfp16" = "-fp16fml"
-    if (NoFullFP16Pos > FP16FMLPos)
-      Features.push_back("-fp16fml");
-    // "-fullfp16" "+fp16fml" = "+fullfp16"
-    else if (NoFullFP16Pos < FP16FMLPos)
-      Features.push_back("+fullfp16");
-  }
-
-  // FIXME: this needs reimplementation too after the TargetParser rewrite
-  //
-  // Context sensitive meaning of Crypto:
-  // 1) For Arch >= ARMv8.4a:  crypto = sm4 + sha3 + sha2 + aes
-  // 2) For Arch <= ARMv8.3a:  crypto = sha2 + aes
-  if (V8Version >= 4 || V9Version >= 0) {
-    if (HasCrypto && !HasNoCrypto) {
-      // Check if we have NOT disabled an algorithm with something like:
-      //   +crypto, -algorithm
-      // And if "-algorithm" does not occur, we enable that crypto algorithm.
-      if (!HasNoSM4)
-        Features.push_back("+sm4");
-      if (!HasNoSHA3)
-        Features.push_back("+sha3");
-      if (!HasNoSHA2)
-        Features.push_back("+sha2");
-      if (!HasNoAES)
-        Features.push_back("+aes");
-    } else if (HasNoCrypto) {
-      // Check if we have NOT enabled a crypto algorithm with something like:
-      //   -crypto, +algorithm
-      // And if "+algorithm" does not occur, we disable that crypto algorithm.
-      if (!HasSM4)
-        Features.push_back("-sm4");
-      if (!HasSHA3)
-        Features.push_back("-sha3");
-      if (!HasSHA2)
-        Features.push_back("-sha2");
-      if (!HasAES)
-        Features.push_back("-aes");
-    }
-  } else {
-    if (HasCrypto && !HasNoCrypto) {
-      if (!HasNoSHA2)
-        Features.push_back("+sha2");
-      if (!HasNoAES)
-        Features.push_back("+aes");
-    } else if (HasNoCrypto) {
-      if (!HasSHA2)
-        Features.push_back("-sha2");
-      if (!HasAES)
-        Features.push_back("-aes");
-      if (V8Version == 2 || V8Version == 3) {
-        Features.push_back("-sm4");
-        Features.push_back("-sha3");
-      }
-    }
-  }
-
   if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
                                options::OPT_munaligned_access)) {
     if (A->getOption().matches(options::OPT_mno_unaligned_access))
diff --git a/clang/test/Driver/aarch64-bf16.c b/clang/test/Driver/aarch64-bf16.c
index ae6b9faa95d711..c32bd5878c640e 100644
--- a/clang/test/Driver/aarch64-bf16.c
+++ b/clang/test/Driver/aarch64-bf16.c
@@ -5,4 +5,4 @@
 // RUN: %clang --target=aarch64 -march=armv8.5a+bf16+nobf16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BF16-NO-BF16 %s
 // GENERICV85A-BF16-NO-BF16: "-target-feature" "-bf16"
 // RUN: %clang --target=aarch64 -march=armv8.5a+bf16+sve -### -c %s 2>&1 | FileCheck -check-prefixes=GENERICV85A-BF16-SVE %s
-// GENERICV85A-BF16-SVE: "-target-feature" "+bf16" "-target-feature" "+sve"
+// GENERICV85A-BF16-SVE: "-target-feature" "+bf16"{{.*}} "-target-feature" "+sve"
diff --git a/clang/test/Driver/aarch64-cortex-a510.c b/clang/test/Driver/aarch64-cortex-a510.c
index 85c40c5fade31a..0d8659c46a8943 100644
--- a/clang/test/Driver/aarch64-cortex-a510.c
+++ b/clang/test/Driver/aarch64-cortex-a510.c
@@ -5,4 +5,4 @@
 // CORTEX-A510-NOT: "-target-feature" "{{[+-]}}aes"
 // CORTEX-A510-SAME: {{$}}
 // RUN: %clang --target=aarch64 -mcpu=cortex-a510+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A510-CRYPTO %s
-// CORTEX-A510-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CORTEX-A510-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+aes"{{.*}} "-target-feature" "+sha2"{{.*}} "-target-feature" "+sha3"{{.*}} "-target-feature" "+sm4"
diff --git a/clang/test/Driver/aarch64-cortex-a710.c b/clang/test/Driver/aarch64-cortex-a710.c
index d84b5b2ee7e524..b5a6ff93e0767d 100644
--- a/clang/test/Driver/aarch64-cortex-a710.c
+++ b/clang/test/Driver/aarch64-cortex-a710.c
@@ -5,4 +5,4 @@
 // CORTEX-A710-NOT: "-target-feature" "{{[+-]}}aes"
 // CORTEX-A710-SAME: {{$}}
 // RUN: %clang --target=aarch64 -mcpu=cortex-a710+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A710-CRYPTO %s
-// CORTEX-A710-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CORTEX-A710-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64"{{.*}} "-target-feature" "+aes"{{.*}} "-target-feature" "+sha2" "-target-feature" "+sha3"{{.*}} "-target-feature" "+sm4"
diff --git a/clang/test/Driver/aarch64-cortex-x2.c b/clang/test/Driver/aarch64-cortex-x2.c
index 9c6153e5beb48f..2833029ba55e3d 100644
--- a/clang/test/Driver/aarch64-cortex-x2.c
+++ b/clang/test/Driver/aarch64-cortex-x2.c
@@ -5,4 +5,4 @@
 // CORTEX-X2-NOT: "-target-feature" "{{[+-]}}aes"
 // CORTEX-X2-SAME: {{$}}
 // RUN: %clang --target=aarch64 -mcpu=cortex-x2+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-X2-CRYPTO %s
-// CORTEX-X2-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CORTEX-X2-CRYPTO: "-cc1"{{.*}} "-triple" "aarch64"{{.*}} "-target-feature" "+aes"{{.*}} "-target-feature" "+sha2" "-target-feature" "+sha3"{{.*}} "-target-feature" "+sm4"
diff --git a/clang/test/Driver/aarch64-d128.c b/clang/test/Driver/aarch64-d128.c
index e2a87444d54755..5d112c0aad67ff 100644
--- a/clang/test/Driver/aarch64-d128.c
+++ b/clang/test/Driver/aarch64-d128.c
@@ -3,8 +3,7 @@
 // FEAT_D128 is optional (off by default) for v9.4a and older, and can be enabled using +d128
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a        %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+d128   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+nod128 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+nod128 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 
 // ENABLED: "-target-feature" "+d128"
 // NOT_ENABLED-NOT: "-target-feature" "+d128"
-// DISABLED: "-target-feature" "-d128"
diff --git a/clang/test/Driver/aarch64-fp16.c b/clang/test/Driver/aarch64-fp16.c
index 451cb6162ee667..4da1834cf68765 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV8A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -30,36 +30,36 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16 %s
-// GENERICV82A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a" "-target-feature" "+fullfp16"
+// GENERICV82A-FP16: "-cc1"{{.*}} "-triple" "aarch64"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+fullfp16"{{.*}} "-target-feature" "+neon"
 // GENERICV82A-FP16-NOT: "-target-feature" "{{[+-]}}fp16fml"
 // 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" "+neon" "-target-feature" "+v8.2a" "-target-feature" "+spe"
+// GENERICV82A-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+spe"{{.*}} "-target-feature" "+neon"
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV82A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
-// GENERICV82A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV82A-FP16-NO-FP16FML: "-target-feature" "+fullfp16"
 
 // RUN: %clang --target=aarch64 -march=armv8.2a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-NO-FP16FML-FP16 %s
-// GENERICV82A-NO-FP16FML-FP16: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
+// GENERICV82A-NO-FP16FML-FP16: "-target-feature" "+fullfp16"
 
 // 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" "-fullfp16"{{.*}} "-target-feature" "-fp16fml"
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV82A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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" "+neon" "-target-feature" "+v8.2a" "-target-feature" "+fullfp16" "-target-feature" "+spe"
+// 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-NOT:  "-target-feature" "{{[+-]}}fp16fml"
 // GENERICV82A-FP16-SPE-SAME: {{$}}
 
@@ -70,19 +70,21 @@
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16 %s
-// GENERICV83A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.3a" "-target-feature" "+fullfp16"
+// GENERICV83A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.3a"{{.*}} "-target-feature" "+fullfp16"{{.*}} "-target-feature" "+neon"
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV83A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
-// GENERICV83A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+// GENERICV83A-FP16-NO-FP16FML: "-target-feature" "+fullfp16"
+// GENERICV83A-FP16-NO-FP16FML-NOT: fp16fml
 
 // RUN: %clang --target=aarch64 -march=armv8.3a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-NO-FP16FML-FP16 %s
 // RUN: %clang --target=aarch64 -march=armv8.3-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-NO-FP16FML-FP16 %s
-// GENERICV83A-NO-FP16FML-FP16: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
+// GENERICV83A-NO-FP16FML-FP16: "-target-feature" "+fullfp16"
+// GENERICV83A-NO-FP16FML-FP16-NOT: fp16fml
 
 // 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
@@ -90,7 +92,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV83A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -103,7 +105,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV84A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -119,7 +121,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV84A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -132,7 +134,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV85A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -148,7 +150,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV85A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -161,7 +163,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV86A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -177,7 +179,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV86A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -190,7 +192,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV87A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -206,7 +208,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV87A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -219,7 +221,7 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV88A-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
 
 // 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
@@ -235,4 +237,4 @@
 
 // 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" "+fp16fml" "-target-feature" "+fullfp16"
+// GENERICV88A-NO-FP16-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
diff --git a/clang/test/Driver/aarch64-implied-sme-features.c b/clang/test/Driver/aarch64-implied-sme-features.c
index 2277aceb881d73..67836f42f2c027 100644
--- a/clang/test/Driver/aarch64-implied-sme-features.c
+++ b/clang/test/Driver/aarch64-implied-sme-features.c
@@ -1,44 +1,46 @@
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme %s -### 2>&1 | FileCheck %s --check-prefix=SME-IMPLY
-// SME-IMPLY: "-target-feature" "+sme" "-target-feature" "+bf16"
+// SME-IMPLY: "-target-feature" "+bf16"{{.*}} "-target-feature" "+sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosme %s -### 2>&1 | FileCheck %s --check-prefix=NOSME
-// NOSME: "-target-feature" "-sme"
+// NOSME-NOT: "-target-feature" "{{\+|-}}sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme+nosme %s -### 2>&1 | FileCheck %s --check-prefix=SME-REVERT
 // SME-REVERT-NOT: "-target-feature" "+sme"
-// SME-REVERT: "-target-feature" "+bf16" "-target-feature" "-sme" "-target-feature" "-sme-f64f64" "-target-feature" "-sme-i16i64"
+// SME-REVERT: "-target-feature" "+bf16"{{.*}} "-target-feature" "-sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme+nobf16 %s -### 2>&1 | FileCheck %s --check-prefix=SME-CONFLICT
 // SME-CONFLICT-NOT: "-target-feature" "+sme"
 // SME-CONFLICT-NOT: "-target-feature" "+bf16"
-// SME-CONFLICT: "-target-feature" "-bf16" "-target-feature" "-sme" "-target-feature" "-sme-f64f64" "-target-feature" "-sme-i16i64"
+// SME-CONFLICT: "-target-feature" "-bf16"{{.*}} "-target-feature" "-sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-i16i64 %s -### 2>&1 | FileCheck %s --check-prefix=SME-I16I64
-// SME-I16I64: "-target-feature" "+sme-i16i64" "-target-feature" "+sme" "-target-feature" "+bf16"
+// SME-I16I64: "-target-feature" "+bf16"{{.*}} "-target-feature" "+sme-i16i64" "-target-feature" "+sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosme-i16i64 %s -### 2>&1 | FileCheck %s --check-prefix=NOSME-I16I64
 // NOSME-I16I64-NOT: "-target-feature" "+sme-i16i64"
 // NOSME-I16I64-NOT: "-target-feature" "+sme"
 // NOSME-I16I64-NOT: "-target-feature" "+bf16"
-// NOSME-I16I64:     "-target-feature" "-sme-i16i64"
+// NOSME-I16I64-NOT: sme-i16i64"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-i16i64+nosme-i16i64 %s -### 2>&1 | FileCheck %s --check-prefix=SME-I16I64-REVERT
-// SME-I16I64-REVERT: "-target-feature" "+sme" "-target-feature" "+bf16" "-target-feature" "-sme-i16i64"
+// SME-I16I64-REVERT: "-target-feature" "+bf16"{{.*}} "-target-feature" "-sme-i16i64" "-target-feature" "+sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosme-f64f64 %s -### 2>&1 | FileCheck %s --check-prefix=NOSME-F64F64
 // NOSME-F64F64-NOT: "-target-feature" "+sme-f64f64"
 // NOSME-F64F64-NOT: "-target-feature" "+sme"
 // NOSME-F64F64-NOT: "-target-feature" "+bf16"
-// NOSME-F64F64:     "-target-feature" "-sme-f64f64"
+// NOSME-F64F64-NOT: sme-f64f64"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-f64f64+nosme-f64f64 %s -### 2>&1 | FileCheck %s --check-prefix=SME-F64F64-REVERT
-// SME-F64F64-REVERT: "-target-feature" "+sme" "-target-feature" "+bf16" "-target-feature" "-sme-f64f64"
+// SME-F64F64-REVERT: "-target-feature" "+bf16"{{.*}} "-target-feature" "-sme-f64f64" "-target-feature" "+sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-f64f64+nosme-i16i64 %s -### 2>&1 | FileCheck %s --check-prefix=SME-SUBFEATURE-MIX
-// SME-SUBFEATURE-MIX: "-target-feature" "+sme-f64f64" "-target-feature" "+sme" "-target-feature" "+bf16" "-target-feature" "-sme-i16i64"
+// SME-SUBFEATURE-MIX-NOT: "+sme-i16i64"
+// SME-SUBFEATURE-MIX: "-target-feature" "+bf16"{{.*}} "-target-feature" "+sme-f64f64" "-target-feature" "+sme"
+// SME-SUBFEATURE-MIX-NOT: "+sme-i16i64"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-i16i64+nosme %s -### 2>&1 | FileCheck %s --check-prefix=SME-SUBFEATURE-CONFLICT1
-// SME-SUBFEATURE-CONFLICT1: "-target-feature" "+bf16" "-target-feature" "-sme" "-target-feature" "-sme-f64f64" "-target-feature" "-sme-i16i64"
+// SME-SUBFEATURE-CONFLICT1: "-target-feature" "+bf16"{{.*}} "-target-feature" "-sme-i16i64" "-target-feature" "-sme"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sme-f64f64+nobf16 %s -### 2>&1 | FileCheck %s --check-prefix=SME-SUBFEATURE-CONFLICT2
 // SME-SUBFEATURE-CONFLICT2-NOT: "-target-feature" "+bf16"
@@ -46,4 +48,4 @@
 // SME-SUBFEATURE-CONFLICT2-NOT: "-target-feature" "+sme-f64f64"
 
 // RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosme+sme-i16i64 %s -### 2>&1 | FileCheck %s --check-prefix=SME-SUBFEATURE-CONFLICT-REV
-// SME-SUBFEATURE-CONFLICT-REV: "-target-feature" "-sme-f64f64" "-target-feature" "+sme-i16i64" "-target-feature" "+sme" "-target-feature" "+bf16"
+// SME-SUBFEATURE-CONFLICT-REV: "-target-feature" "+bf16"{{.*}} "-target-feature" "+sme-i16i64" "-target-feature" "+sme"
diff --git a/clang/test/Driver/aarch64-implied-sve-features.c b/clang/test/Driver/aarch64-implied-sve-features.c
index 02d9cb5b594265..9227cd4981c2e2 100644
--- a/clang/test/Driver/aarch64-implied-sve-features.c
+++ b/clang/test/Driver/aarch64-implied-sve-features.c
@@ -2,62 +2,63 @@
 // SVE-ONLY: "-target-feature" "+sve"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+nosve %s -### 2>&1 | FileCheck %s --check-prefix=NOSVE
-// NOSVE: "-target-feature" "-sve"
+// NOSVE-NOT: sve"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve+nosve %s -### 2>&1 | FileCheck %s --check-prefix=SVE-REVERT
 // SVE-REVERT-NOT: "-target-feature" "+sve"
 // SVE-REVERT: "-target-feature" "-sve"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-IMPLY
-// SVE2-IMPLY: "-target-feature" "+sve2" "-target-feature" "+sve"
+// SVE2-IMPLY: "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2+nosve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-REVERT
-// SVE2-REVERT: "-target-feature" "+sve" "-target-feature" "-sve2"
+// SVE2-REVERT: "-target-feature" "+sve"{{.*}} "-target-feature" "-sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2+nosve %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-CONFLICT
-// SVE2-CONFLICT: "-target-feature" "-sve" "-target-feature" "-sve2" "-target-feature" "-sve2-bitperm" "-target-feature" "-sve2-sha3" "-target-feature" "-sve2-aes" "-target-feature" "-sve2-sm4"
+// SVE2-CONFLICT: "-target-feature" "-sve" "-target-feature" "-sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+nosve+sve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-CONFLICT-REV
-// SVE2-CONFLICT-REV: "-target-feature" "+sve2" "-target-feature" "+sve"
+// SVE2-CONFLICT-REV: "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve+sve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE-SVE2
-// SVE-SVE2: "-target-feature" "+sve2" "-target-feature" "+sve"
+// SVE-SVE2: "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-bitperm %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-BITPERM
-// SVE2-BITPERM: "-target-feature" "+sve2-bitperm" "-target-feature" "+sve" "-target-feature" "+sve2"
+// SVE2-BITPERM: "-target-feature" "+sve" "-target-feature" "+sve2-bitperm" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+nosve2-bitperm %s -### 2>&1 | FileCheck %s --check-prefix=NOSVE2-BITPERM
 // NOSVE2-BITPERM-NOT: "-target-feature" "+sve2-bitperm"
 // NOSVE2-BITPERM-NOT: "-target-feature" "+sve2"
 // NOSVE2-BITPERM-NOT: "-target-feature" "+sve"
-// NOSVE2-BITPERM: "-target-feature" "-sve2-bitperm"
+// NOSVE2-BITPERM-NOT: sve2-bitperm"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-bitperm %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-BITPERM-REVERT
-// SVE2-BITPERM-REVERT: "-target-feature" "+sve" "-target-feature" "+sve2" "-target-feature" "-sve2-bitperm"
+// SVE2-BITPERM-REVERT: "-target-feature" "+sve" "-target-feature" "-sve2-bitperm" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-aes+nosve2-aes %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-AES-REVERT
-// SVE2-AES-REVERT: "-target-feature" "+sve" "-target-feature" "+sve2" "-target-feature" "-sve2-aes"
+// SVE2-AES-REVERT: "-target-feature" "+sve" "-target-feature" "-sve2-aes" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-sha3+nosve2-sha3 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SHA3-REVERT
-// SVE2-SHA3-REVERT: "-target-feature" "+sve" "-target-feature" "+sve2" "-target-feature" "-sve2-sha3"
+// SVE2-SHA3-REVERT: "-target-feature" "+sve" "-target-feature" "-sve2-sha3" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2-sm4 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SM4-REVERT
-// SVE2-SM4-REVERT: "-target-feature" "+sve" "-target-feature" "+sve2" "-target-feature" "-sve2-sm4"
+// SVE2-SM4-REVERT: "-target-feature" "+sve" "-target-feature" "-sve2-sm4" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-sha3 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SHA3
-// SVE2-SHA3: "-target-feature" "+sve2-sha3" "-target-feature" "+sve" "-target-feature" "+sve2"
+// SVE2-SHA3: "-target-feature" "+sve" "-target-feature" "+sve2-sha3" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-aes %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-AES
-// SVE2-AES: "-target-feature" "+sve2-aes" "-target-feature" "+sve" "-target-feature" "+sve2"
+// SVE2-AES: "-target-feature" "+sve" "-target-feature" "+sve2-aes" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-sm4 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SM4
-// SVE2-SM4: "-target-feature" "+sve2-sm4" "-target-feature" "+sve" "-target-feature" "+sve2"
+// SVE2-SM4: "-target-feature" "+sve" "-target-feature" "+sve2-sm4" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-aes %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SUBFEATURE-MIX
-// SVE2-SUBFEATURE-MIX: "-target-feature" "+sve2-bitperm" "-target-feature" "+sve" "-target-feature" "+sve2" "-target-feature" "-sve2-aes"
+// SVE2-SUBFEATURE-MIX: "-target-feature" "+sve" "-target-feature" "+sve2-bitperm" "-target-feature" "+sve2"
+// SVE2-SUBFEATURE-NOT: sve2-aes
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE2-SUBFEATURE-CONFLICT
-// SVE2-SUBFEATURE-CONFLICT: "-target-feature" "+sve" "-target-feature" "-sve2" "-target-feature" "-sve2-bitperm" "-target-feature" "-sve2-sha3" "-target-feature" "-sve2-aes" "-target-feature" "-sve2-sm4"
+// SVE2-SUBFEATURE-CONFLICT: "-target-feature" "+sve" "-target-feature" "-sve2-sm4" "-target-feature" "-sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-aes+nosve %s -### 2>&1 | FileCheck %s --check-prefix=SVE-SUBFEATURE-CONFLICT
 // SVE-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve2-aes"
@@ -65,7 +66,7 @@
 // SVE-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve"
 
 // RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+nosve+sve2-aes %s -### 2>&1 | FileCheck %s --check-prefix=SVE-SUBFEATURE-CONFLICT-REV
-// SVE-SUBFEATURE-CONFLICT-REV: "-target-feature" "-sve2-bitperm" "-target-feature" "-sve2-sha3" "-target-feature" "-sve2-sm4" "-target-feature" "+sve2-aes" "-target-feature" "+sve" "-target-feature" "+sve2"
+// SVE-SUBFEATURE-CONFLICT-REV: "-target-feature" "+sve" "-target-feature" "+sve2-aes" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64-linux-gnu -mcpu=neoverse-n2+nosve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE-MCPU-FEATURES
 // SVE-MCPU-FEATURES-NOT: "-target-feature" "+sve2-bitperm"
@@ -74,5 +75,5 @@
 
 // RUN: %clang --target=aarch64-linux-gnu -mcpu=neoverse-n2+nosve+sve2 %s -### 2>&1 | FileCheck %s --check-prefix=SVE-MCPU-FEATURES-CONFLICT
 // SVE-MCPU-FEATURES-CONFLICT-NOT: "-target-feature" "+sve2-bitperm"
-// SVE-MCPU-FEATURES-CONFLICT: "-target-feature" "+sve2"
 // SVE-MCPU-FEATURES-CONFLICT: "-target-feature" "+sve"
+// SVE-MCPU-FEATURES-CONFLICT-SAME: "-target-feature" "+sve2"
diff --git a/clang/test/Driver/aarch64-ite.c b/clang/test/Driver/aarch64-ite.c
index cc1f700ce0cbfa..dde2535872dfd0 100644
--- a/clang/test/Driver/aarch64-ite.c
+++ b/clang/test/Driver/aarch64-ite.c
@@ -3,10 +3,10 @@
 // FEAT_ITE is optional (off by default) for v8.9a/9.4a and older, and can be enabled using +ite
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.8-a       %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.8-a+ite   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.8-a+noite %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.8-a+noite %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.3-a       %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.3-a+ite   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv9.3-a+noite %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv9.3-a+noite %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 
 // FEAT_ITE is invalid before v8
 // RUN: not %clang -### --target=arm-none-none-eabi -march=armv7-a+ite     %s 2>&1 | FileCheck %s --check-prefix=INVALID
@@ -14,4 +14,3 @@
 // INVALID: error: unsupported argument 'armv7-a+ite' to option '-march='
 // ENABLED: "-target-feature" "+ite"
 // NOT_ENABLED-NOT: "-target-feature" "+ite"
-// DISABLED: "-target-feature" "-ite"
diff --git a/clang/test/Driver/aarch64-lrcpc3.c b/clang/test/Driver/aarch64-lrcpc3.c
index eeec0b137e0281..755d6a823ce5fe 100644
--- a/clang/test/Driver/aarch64-lrcpc3.c
+++ b/clang/test/Driver/aarch64-lrcpc3.c
@@ -3,18 +3,18 @@
 // FEAT_RCPC3 is optional for v8.2a onwards, and can be enabled with +rcpc3
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.9-a         %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.9-a+rcpc3   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a         %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+rcpc3   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 
 // FEAT_RCPC3 is optional (off by default) for v8.8a/9.3a and older, and can be enabled using +rcpc3
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.2-a         %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.2-a+rcpc3   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.2-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.2-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9-a         %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9-a+rcpc3   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 
 // FEAT_RCPC3 is invalid before v8
 // RUN: not %clang -### --target=arm-none-none-eabi -march=armv7-a+rcpc3         %s 2>&1 | FileCheck %s --check-prefix=INVALID
@@ -22,5 +22,4 @@
 // INVALID: error: unsupported argument 'armv7-a+rcpc3' to option '-march='
 // ENABLED: "-target-feature" "+rcpc3"
 // NOT_ENABLED-NOT: "-target-feature" "+rcpc3"
-// DISABLED: "-target-feature" "-rcpc3"
 
diff --git a/clang/test/Driver/aarch64-ls64.c b/clang/test/Driver/aarch64-ls64.c
index f9781563a4ab46..7d828a22c60fd8 100644
--- a/clang/test/Driver/aarch64-ls64.c
+++ b/clang/test/Driver/aarch64-ls64.c
@@ -3,8 +3,7 @@
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.7-a+ls64 %s 2>&1 | FileCheck %s
 // CHECK: "-target-feature" "+ls64"
 
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.7-a+nols64 %s 2>&1 | FileCheck %s --check-prefix=NO_LS64
-// NO_LS64: "-target-feature" "-ls64"
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.7-a+nols64 %s 2>&1 | FileCheck %s --check-prefix=ABSENT_LS64
 
 // The LD64B/ST64B accelerator extension is disabled by default.
 // RUN: %clang -### --target=aarch64-none-elf                  %s 2>&1 | FileCheck %s --check-prefix=ABSENT_LS64
diff --git a/clang/test/Driver/aarch64-lse128.c b/clang/test/Driver/aarch64-lse128.c
index d0bf31e49c9656..612df87f21b35b 100644
--- a/clang/test/Driver/aarch64-lse128.c
+++ b/clang/test/Driver/aarch64-lse128.c
@@ -3,8 +3,7 @@
 // FEAT_LSE128 is optional (off by default) for v9.4a and older, and can be enabled using +lse128
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a          %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 // RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+lse128   %s 2>&1 | FileCheck %s --check-prefix=ENABLED
-// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+nolse128 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### --target=aarch64-none-elf -march=armv9.4-a+nolse128 %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
 
 // ENABLED: "-target-feature" "+lse128"
 // NOT_ENABLED-NOT: "-target-feature" "+lse128"
-// DISABLED: "-target-feature" "-lse128"
diff --git a/clang/test/Driver/aarch64-march.c b/clang/test/Driver/aarch64-march.c
index 59be5836b39dc3..132cea0e2c6240 100644
--- a/clang/test/Driver/aarch64-march.c
+++ b/clang/test/Driver/aarch64-march.c
@@ -1,9 +1,9 @@
 // RUN: %clang --target=aarch64 -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-V8A %s
 // RUN: %clang --target=aarch64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-V8A %s
-// GENERIC-V8A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8a"
+// GENERIC-V8A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+v8a"
 
 // RUN: %clang --target=aarch64 -march=armv8-r -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-V8R %s
-// GENERIC-V8R: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8r"
+// GENERIC-V8R: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+v8r"
 
 // 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
@@ -11,7 +11,7 @@
 // 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" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// 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
@@ -19,7 +19,7 @@
 // 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" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// GENERICV9A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // ================== Check whether -march accepts mixed-case values.
 // RUN: %clang --target=aarch64_be -march=ARMV8.1A -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
@@ -28,4 +28,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=Armv8.1-A -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=ARMv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=ARMV8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
-// GENERICV81A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a"
+// GENERICV81A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.1a"
diff --git a/clang/test/Driver/aarch64-mgeneral_regs_only.c b/clang/test/Driver/aarch64-mgeneral_regs_only.c
index 07e837f94975ff..17da9c614a8a1b 100644
--- a/clang/test/Driver/aarch64-mgeneral_regs_only.c
+++ b/clang/test/Driver/aarch64-mgeneral_regs_only.c
@@ -5,5 +5,4 @@
 // RUN: %clang --target=arm64-linux-eabi -mgeneral-regs-only %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
 // CHECK-NO-FP: "-target-feature" "-fp-armv8"
-// CHECK-NO-FP: "-target-feature" "-crypto"
 // CHECK-NO-FP: "-target-feature" "-neon"
diff --git a/clang/test/Driver/aarch64-mte.c b/clang/test/Driver/aarch64-mte.c
index 7e8112734603f8..435ffe0defc4b2 100644
--- a/clang/test/Driver/aarch64-mte.c
+++ b/clang/test/Driver/aarch64-mte.c
@@ -1,9 +1,9 @@
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a+memtag %s 2>&1 | FileCheck %s
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.5a+memtag %s 2>&1 | FileCheck %s
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-a510 %s 2>&1 | FileCheck %s
 // CHECK: "-target-feature" "+mte"
 
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a+nomemtag %s 2>&1 | FileCheck %s --check-prefix=NOMTE
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.5a+nomemtag %s 2>&1 | FileCheck %s --check-prefix=NOMTE
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-a510+nomemtag %s 2>&1 | FileCheck %s --check-prefix=NOMTE
 // NOMTE: "-target-feature" "-mte"
 
 // RUN: %clang -### --target=aarch64-none-elf                 %s 2>&1 | FileCheck %s --check-prefix=ABSENTMTE
diff --git a/clang/test/Driver/aarch64-perfmon.c b/clang/test/Driver/aarch64-perfmon.c
index 1c421a4c3f73e8..071be278497e0c 100644
--- a/clang/test/Driver/aarch64-perfmon.c
+++ b/clang/test/Driver/aarch64-perfmon.c
@@ -2,12 +2,13 @@
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.2a+pmuv3 %s 2>&1 | FileCheck --check-prefix=CHECK-PERFMON %s
 // CHECK-PERFMON: "-target-feature" "+perfmon"
 
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a+nopmuv3 %s 2>&1 | FileCheck --check-prefix=CHECK-NOPERFMON %s
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.2a+nopmuv3 %s 2>&1 | FileCheck --check-prefix=CHECK-NOPERFMON %s
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-a520+nopmuv3 %s 2>&1 | FileCheck --check-prefix=CHECK-NOPERFMON %s
 // CHECK-NOPERFMON: "-target-feature" "-perfmon"
 
 // RUN: %clang -### --target=aarch64-none-elf                 %s 2>&1 | FileCheck %s --check-prefix=ABSENTPERFMON
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a %s 2>&1 | FileCheck %s --check-prefix=ABSENTPERFMON
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.2a %s 2>&1 | FileCheck %s --check-prefix=ABSENTPERFMON
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a+nopmuv3 %s 2>&1 | FileCheck --check-prefix=ABSENTPERFMON %s
+// RUN: %clang -### --target=aarch64-none-elf -march=armv8.2a+nopmuv3 %s 2>&1 | FileCheck --check-prefix=ABSENTPERFMON %s
 // ABSENTPERFMON-NOT: "-target-feature" "+perfmon"
-// ABSENTPERFMON-NOT: "-target-feature" "-perfmon"
\ No newline at end of file
+// ABSENTPERFMON-NOT: "-target-feature" "-perfmon"
diff --git a/clang/test/Driver/aarch64-predres.c b/clang/test/Driver/aarch64-predres.c
index 4ed832f29a5c99..afa0830df7dd45 100644
--- a/clang/test/Driver/aarch64-predres.c
+++ b/clang/test/Driver/aarch64-predres.c
@@ -1,8 +1,9 @@
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8a+predres     %s 2>&1 | FileCheck %s
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-a520         %s 2>&1 | FileCheck %s
 // CHECK: "-target-feature" "+predres"
 // CHECK-NOT: "-target-feature" "-predres"
 
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.5a+nopredres %s 2>&1 | FileCheck %s --check-prefix=NOPR
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-a520+nopredres %s 2>&1 | FileCheck %s --check-prefix=NOPR
 // NOPR: "-target-feature" "-predres"
 // NOPR-NOT: "-target-feature" "+predres"
 
diff --git a/clang/test/Driver/aarch64-rand.c b/clang/test/Driver/aarch64-rand.c
index 924ff638458c64..80891ec3f54828 100644
--- a/clang/test/Driver/aarch64-rand.c
+++ b/clang/test/Driver/aarch64-rand.c
@@ -2,8 +2,7 @@
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8.5a+rng %s 2>&1 | FileCheck %s
 // CHECK: "-target-feature" "+rand"
 
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.4a+norng %s 2>&1 | FileCheck %s --check-prefix=NORAND
-// RUN: %clang -### --target=aarch64-none-elf -march=armv8.5a+norng %s 2>&1 | FileCheck %s --check-prefix=NORAND
+// RUN: %clang -### --target=aarch64-none-elf -mcpu=neoverse-v1+norng %s 2>&1 | FileCheck %s --check-prefix=NORAND
 // NORAND: "-target-feature" "-rand"
 
 // RUN: %clang -### --target=aarch64-none-elf                 %s 2>&1 | FileCheck %s --check-prefix=ABSENTRAND
diff --git a/clang/test/Driver/aarch64-ras.c b/clang/test/Driver/aarch64-ras.c
index f72fa211ff886b..c1e1f1b85a1714 100644
--- a/clang/test/Driver/aarch64-ras.c
+++ b/clang/test/Driver/aarch64-ras.c
@@ -1,20 +1,21 @@
 // RAS is off by default for v8a, but can be enabled by +ras (this is not architecturally valid)
 // RUN: %clang --target=aarch64-none-elf -march=armv8a+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
+// RUN: %clang --target=aarch64-none-elf -march=armv8.2a+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
 // RUN: %clang --target=aarch64-none-elf -march=armv8-a+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
 // RUN: %clang --target=aarch64-none-elf -mcpu=generic+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
 // RUN: %clang --target=aarch64-none-elf -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
 // RUN: %clang --target=aarch64-none-elf -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
 // CHECK-RAS: "-target-feature" "+ras"
 
-// RUN: %clang --target=aarch64-none-elf -march=armv8a+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORAS %s
-// RUN: %clang --target=aarch64-none-elf -mcpu=generic+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORAS %s
-// CHECK-NORAS: "-target-feature" "-ras"
+// RUN: %clang --target=aarch64-none-elf -march=armv8a+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ABSENT %s
+// RUN: %clang --target=aarch64-none-elf -mcpu=generic+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ABSENT %s
+// CHECK-ABSENT-NOT: "-target-feature" ++ras"
 
 // RAS is on by default for v8.2a, but can be disabled by +noras
-// FIXME: in the current implementation, RAS is not on by default at all for v8.2a (the test says it all...)
-// RUN: %clang --target=aarch64 -march=armv8.2a  -### -c %s 2>&1 | FileCheck -check-prefix=V82ARAS %s
-// RUN: %clang --target=aarch64 -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=V82ARAS %s
+// RUN: %clang --target=aarch64 -march=armv8.2a  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-RAS %s
+// RUN: %clang --target=aarch64 -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-RAS %s
 // V82ARAS-NOT: "-target-feature" "+ras"
 // V82ARAS-NOT: "-target-feature" "-ras"
 // RUN: %clang --target=aarch64 -march=armv8.2a+noras  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NORAS %s
 // RUN: %clang --target=aarch64 -march=armv8.2-a+noras -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NORAS %s
+// CHECK-NORAS: "-target-feature" "-ras"
diff --git a/clang/test/Driver/aarch64-rdm.c b/clang/test/Driver/aarch64-rdm.c
index 5cad9a9973a174..f2542b381e7c26 100644
--- a/clang/test/Driver/aarch64-rdm.c
+++ b/clang/test/Driver/aarch64-rdm.c
@@ -6,4 +6,8 @@
 
 // RUN: %clang --target=aarch64-none-elf -march=armv8a+nordm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORDM %s
 // RUN: %clang --target=aarch64-none-elf -mcpu=generic+nordm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORDM %s
-// CHECK-NORDM: "-target-feature" "-rdm"
+// CHECK-NORDM-NOT: "-target-feature" "+rdm"
+//
+// RUN: %clang --target=aarch64-none-elf -march=armv8.1a -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RDM %s
+// RUN: %clang --target=aarch64-none-elf -march=armv8.1a+nordm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORDM-DEFAULT %s
+// CHECK-NORDM-DEFAULT: "-target-feature" "-rdm"
diff --git a/clang/test/Driver/aarch64-ssbs.c b/clang/test/Driver/aarch64-ssbs.c
index 033e3a6471713f..62b603a096bc40 100644
--- a/clang/test/Driver/aarch64-ssbs.c
+++ b/clang/test/Driver/aarch64-ssbs.c
@@ -6,7 +6,7 @@
 
 // RUN: %clang -### --target=aarch64-none-elf -march=armv8a+nossbs %s 2>&1 | FileCheck %s --check-prefix=NOSSBS
 // RUN: %clang -### --target=aarch64-none-elf -mcpu=cortex-x1c+nossbs %s 2>&1 | FileCheck %s --check-prefix=NOSSBS
-// NOSSBS: "-target-feature" "-ssbs"
+// NOSSBS-NOT: "-target-feature" "+ssbs"
 
 // RUN: %clang -### --target=aarch64-none-elf                      %s 2>&1 | FileCheck %s --check-prefix=ABSENTSSBS
 // ABSENTSSBS-NOT: "-target-feature" "+ssbs"
diff --git a/clang/test/Driver/aarch64-sve2.c b/clang/test/Driver/aarch64-sve2.c
index 224c89dc3ce113..c801f44d3cb842 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" "+neon" "-target-feature" "+v9a" "-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-the.c b/clang/test/Driver/aarch64-the.c
index dcaeae115d2ea8..c776cfeb044b3a 100644
--- a/clang/test/Driver/aarch64-the.c
+++ b/clang/test/Driver/aarch64-the.c
@@ -22,5 +22,5 @@
 // INVALID: error: unsupported argument 'armv7-a+the' to option '-march='
 // ENABLED: "-target-feature" "+the"
 // NOT_ENABLED-NOT: "-target-feature" "+the"
-// DISABLED: "-target-feature" "-the"
+// DISABLED-NOT: "-target-feature" "{{[-+]}}the"
 
diff --git a/clang/test/Driver/aarch64-v81a.c b/clang/test/Driver/aarch64-v81a.c
index 1f8a707b116eeb..e84652ec7f11e1 100644
--- a/clang/test/Driver/aarch64-v81a.c
+++ b/clang/test/Driver/aarch64-v81a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
 // RUN: %clang --target=aarch64_be -mbig-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
-// GENERICV81A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a"
+// GENERICV81A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.1a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
 // RUN: %clang --target=aarch64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
@@ -12,10 +12,10 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
-// GENERICV81A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.1a"
+// GENERICV81A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.1a"{{.*}} "-target-feature" "+neon"{{.*}}
 
 // RUN: %clang --target=arm64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s
 // RUN: %clang --target=arm64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERICV81A %s
 // 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" "+neon" "-target-feature" "+v8.1a"
+// ARM64-GENERICV81A: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"{{.*}} "-target-feature" "+v8.1a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v82a.c b/clang/test/Driver/aarch64-v82a.c
index ae70255e6a2307..9dd355934c1059 100644
--- a/clang/test/Driver/aarch64-v82a.c
+++ b/clang/test/Driver/aarch64-v82a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A %s
-// GENERICV82A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a"
+// GENERICV82A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
 // 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" "+neon" "-target-feature" "+v8.2a"
+// GENERICV82A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v83a.c b/clang/test/Driver/aarch64-v83a.c
index 63c47e39f78c2d..b0ff9fb3abc24c 100644
--- a/clang/test/Driver/aarch64-v83a.c
+++ b/clang/test/Driver/aarch64-v83a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
-// GENERICV83A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.3a"
+// GENERICV83A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+v8.3a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
 // 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" "+neon" "-target-feature" "+v8.3a"
+// GENERICV83A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.3a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v84a.c b/clang/test/Driver/aarch64-v84a.c
index f6a573bb028313..030990bfe5131c 100644
--- a/clang/test/Driver/aarch64-v84a.c
+++ b/clang/test/Driver/aarch64-v84a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
-// GENERICV84A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.4a"
+// GENERICV84A: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" "-target-feature" "+v8.4a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
 // 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" "+neon" "-target-feature" "+v8.4a"
+// GENERICV84A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.4a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v85a.c b/clang/test/Driver/aarch64-v85a.c
index 4ee76faf48c418..3e1e921dcc0133 100644
--- a/clang/test/Driver/aarch64-v85a.c
+++ b/clang/test/Driver/aarch64-v85a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A %s
-// GENERICV85A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.5a"
+// GENERICV85A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.5a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-BE %s
 // 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" "+neon" "-target-feature" "+v8.5a"
+// GENERICV85A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.5a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v86a.c b/clang/test/Driver/aarch64-v86a.c
index 970e21c69ce8eb..ba2b57979b5187 100644
--- a/clang/test/Driver/aarch64-v86a.c
+++ b/clang/test/Driver/aarch64-v86a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A %s
-// GENERICV86A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.6a"
+// GENERICV86A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.6a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV86A-BE %s
 // 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" "+neon" "-target-feature" "+v8.6a"
+// GENERICV86A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.6a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v87a.c b/clang/test/Driver/aarch64-v87a.c
index 4e1d403faada7c..ee4b68882739a8 100644
--- a/clang/test/Driver/aarch64-v87a.c
+++ b/clang/test/Driver/aarch64-v87a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s
-// GENERICV87A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.7a"
+// GENERICV87A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.7a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s
 // 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" "+neon" "-target-feature" "+v8.7a"
+// GENERICV87A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.7a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v88a.c b/clang/test/Driver/aarch64-v88a.c
index 19db5fb862cba2..b680c1f567134d 100644
--- a/clang/test/Driver/aarch64-v88a.c
+++ b/clang/test/Driver/aarch64-v88a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A %s
-// GENERICV88A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.8a"
+// GENERICV88A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.8a"{{.*}} "-target-feature" "+neon"
 
 // RUN: %clang --target=aarch64_be -march=armv8.8a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.8-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV88A-BE %s
 // 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" "+neon" "-target-feature" "+v8.8a"
+// GENERICV88A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.8a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v89a.c b/clang/test/Driver/aarch64-v89a.c
index d803dff269920b..903b793d046ba6 100644
--- a/clang/test/Driver/aarch64-v89a.c
+++ b/clang/test/Driver/aarch64-v89a.c
@@ -4,11 +4,11 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv8.9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv8.9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A %s
-// GENERICV89A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.9a"
+// GENERICV89A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.9a"{{.*}} "-target-feature" "+neon"
 // RUN: %clang --target=aarch64_be -march=armv8.9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv8.9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.9a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv8.9-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV89A-BE %s
 // 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" "+neon" "-target-feature" "+v8.9a"
+// GENERICV89A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.9a"{{.*}} "-target-feature" "+neon"
diff --git a/clang/test/Driver/aarch64-v91a.c b/clang/test/Driver/aarch64-v91a.c
index a9e3833c5af9f4..80853a59d01537 100644
--- a/clang/test/Driver/aarch64-v91a.c
+++ b/clang/test/Driver/aarch64-v91a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A %s
-// GENERICV91A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.1a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// GENERICV91A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.1a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64_be -march=armv9.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A-BE %s
 // 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" "+neon" "-target-feature" "+v9.1a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// GENERICV91A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.1a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
diff --git a/clang/test/Driver/aarch64-v92a.c b/clang/test/Driver/aarch64-v92a.c
index c9eab8475155d5..ee644cc6f3c620 100644
--- a/clang/test/Driver/aarch64-v92a.c
+++ b/clang/test/Driver/aarch64-v92a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A %s
-// GENERICV92A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.2a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// GENERICV92A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.2a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang --target=aarch64_be -march=armv9.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
 // 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" "+neon" "-target-feature" "+v9.2a" "-target-feature" "+sve" "-target-feature" "+sve2"
+// GENERICV92A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.2a"{{.*}} "-target-feature" "+sve" "-target-feature" "+sve2"
diff --git a/clang/test/Driver/aarch64-v93a.c b/clang/test/Driver/aarch64-v93a.c
index 9d6e715f3aac22..817559e28ccf47 100644
--- a/clang/test/Driver/aarch64-v93a.c
+++ b/clang/test/Driver/aarch64-v93a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
-// GENERICV93A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.3a"
+// GENERICV93A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.3a"
 
 // RUN: %clang --target=aarch64_be -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s
 // 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" "+neon" "-target-feature" "+v9.3a"
+// GENERICV93A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.3a"
diff --git a/clang/test/Driver/aarch64-v94a.c b/clang/test/Driver/aarch64-v94a.c
index 49659ac949b4e6..9998cc8a4a2160 100644
--- a/clang/test/Driver/aarch64-v94a.c
+++ b/clang/test/Driver/aarch64-v94a.c
@@ -4,7 +4,7 @@
 // RUN: %clang --target=aarch64 -mlittle-endian -march=armv9.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A %s
 // RUN: %clang --target=aarch64_be -mlittle-endian -march=armv9.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A %s
-// GENERICV94A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.4a"
+// GENERICV94A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.4a"
 
 // RUN: %clang --target=aarch64_be -march=armv9.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A-BE %s
 // RUN: %clang --target=aarch64_be -march=armv9.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A-BE %s
@@ -12,4 +12,4 @@
 // RUN: %clang --target=aarch64 -mbig-endian -march=armv9.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV94A-BE %s
 // 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" "+neon" "-target-feature" "+v9.4a"
+// GENERICV94A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.4a"
diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 13069c04c8d1c8..1037da65c8cb5c 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -6,7 +6,7 @@
 // RUN: %clang -target aarch64 -mlittle-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s
 // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s
 // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s
-// GENERICV95A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
+// GENERICV95A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"
 
 // RUN: %clang -target aarch64_be -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // RUN: %clang -target aarch64_be -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
@@ -14,18 +14,18 @@
 // RUN: %clang -target aarch64 -mbig-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
-// GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
+// GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"
 
 // ===== Features supported on aarch64 =====
 
 // RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s
 // RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s
-// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+cpa"
 
 // RUN: %clang -target aarch64 -march=armv9.5a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s
 // RUN: %clang -target aarch64 -march=armv9.5-a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s
-// V95A-PAUTHLR: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+pauth-lr"
+// V95A-PAUTHLR: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+pauth-lr"
 
 // 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" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+tlbiw"
+// V95A-TLBIW: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+tlbiw"
diff --git a/clang/test/Driver/arm-sb.c b/clang/test/Driver/arm-sb.c
index 9c2bf082d5b029..f2704f33c27111 100644
--- a/clang/test/Driver/arm-sb.c
+++ b/clang/test/Driver/arm-sb.c
@@ -1,14 +1,16 @@
 // RUN: %clang -### -target arm-none-none-eabi -march=armv8a+sb %s 2>&1 | FileCheck %s
 // RUN: %clang -### -target aarch64-none-elf -march=armv8a+sb %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-elf -mcpu=cortex-a510 %s 2>&1 | FileCheck %s
 // CHECK: "-target-feature" "+sb"
 // CHECK-NOT: "-target-feature" "-sb"
 
 // RUN: %clang -### -target arm-none-none-eabi -march=armv8.5a+nosb %s 2>&1 | FileCheck %s --check-prefix=NOSB
-// RUN: %clang -### -target aarch64-none-elf -march=armv8.5a+nosb %s 2>&1 | FileCheck %s --check-prefix=NOSB
+// RUN: %clang -### -target aarch64-none-elf -mcpu=cortex-a510+nosb %s 2>&1 | FileCheck %s --check-prefix=NOSB
 // NOSB: "-target-feature" "-sb"
 // NOSB-NOT: "-target-feature" "+sb"
 
 // RUN: %clang -### -target arm-none-none-eabi %s 2>&1 | FileCheck %s --check-prefix=ABSENT
 // RUN: %clang -### -target aarch64-none-elf %s 2>&1 | FileCheck %s --check-prefix=ABSENT
+// RUN: %clang -### -target aarch64-none-elf -march=armv8.5a+nosb %s 2>&1 | FileCheck %s --check-prefix=ABSENT
 // ABSENT-NOT: "-target-feature" "+sb"
 // ABSENT-NOT: "-target-feature" "-sb"
diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c
index 39d79bcfe4cd52..15879da04fcf0e 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -285,7 +285,7 @@
 
 // ================== Check whether -mtune accepts mixed-case features.
 // RUN: %clang -target aarch64 -mtune=CYCLONE -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MTUNE-CYCLONE %s
-// CHECK-MTUNE-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8a" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// CHECK-MTUNE-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8a"
 
 // RUN: %clang -target aarch64 -mcpu=apple-a7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-APPLE-A7 %s
 // RUN: %clang -target aarch64 -mcpu=apple-a8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-APPLE-A7 %s
@@ -311,18 +311,18 @@
 // 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" "+v8a" "-target-feature" "+aes" "-target-feature" "+fp-armv8" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
-// CHECK-MCPU-APPLE-A10: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
-// CHECK-MCPU-APPLE-A11: "-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" "-target-feature" "+zcm" "-target-feature"
-// CHECK-MCPU-APPLE-A12: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-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" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// 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" "+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" "+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" "+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" "+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" "+sha2" "-target-feature" "+neon"
-// CHECK-MCPU-APPLE-A13: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm"  "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16"
+// 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" "+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" "+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" "+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" "+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" "+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" "+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" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+neon" "-target-feature" "+ssbs" "-target-feature" "+fullfp16"
+// CHECK-MCPU-CORTEX-R82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8r" "-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" "+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" "+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" "+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" "+sha2" "-target-feature" "+neon"
@@ -331,18 +331,18 @@
 // 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"
 
 // 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" "+v8.5a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16"
+// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.5a" "-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" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon"
 
 // 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" "+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" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// 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" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon"
 
 // 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 -### -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 -### -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" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
-// CHECK-MARCH-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-fp-armv8" "-target-feature" "-neon" "-target-feature" "-crc" "-target-feature" "-crypto"
+// 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-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-fp-armv8"{{.*}} "-target-feature" "-neon"
 // CHECK-MARCH-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-neon"
 
 // While we're checking +nofp, also make sure it stops defining __ARM_FP
@@ -352,42 +352,42 @@
 // Check +sm4:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+sm4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-SM4 %s
-// CHECK-SM4:  "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+sm4"
+// CHECK-SM4:  "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+sm4"
 //
 // Check +sha3:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+sha3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-SHA3 %s
-// CHECK-SHA3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+sha3"
+// CHECK-SHA3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a"{{.*}} "-target-feature" "+sha3"
 //
 // Check +sha2:
 //
 // RUN: %clang -target aarch64 -march=armv8.3a+sha2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-SHA2 %s
-// CHECK-SHA2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.{{.}}a" "-target-feature" "+sha2"
+// CHECK-SHA2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.{{.}}a"{{.*}} "-target-feature" "+sha2"
 //
 // Check +aes:
 //
 // RUN: %clang -target aarch64 -march=armv8.3a+aes -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-AES %s
-// CHECK-AES: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.{{.}}a" "-target-feature" "+aes"
+// CHECK-AES: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.{{.}}a"{{.*}} "-target-feature" "+aes"
 //
 // Check -sm4:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+noSM4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SM4 %s
-// CHECK-NO-SM4:  "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "-sm4"
+// CHECK-NO-SM4-NOT: "-target-feature" "+sm4"
 //
 // Check -sha3:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+noSHA3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SHA3 %s
-// CHECK-NO-SHA3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "-sha3"
+// CHECK-NO-SHA3-NOT: "-target-feature" "+sha3"
 //
 // Check -sha2:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+noSHA2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SHA2 %s
-// CHECK-NO-SHA2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "-sha2"
+// CHECK-NO-SHA2-NOT: "-target-feature" "+sha2"
 //
 // Check -aes:
 //
 // RUN: %clang -target aarch64 -march=armv8.2a+noAES -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NO-AES %s
-// CHECK-NO-AES: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "-aes"
+// CHECK-NO-AES-NOT: "-target-feature" "+aes"
 //
 //
 // Arch <= ARMv8.3:  crypto = sha2 + aes
@@ -400,19 +400,19 @@
 // RUN: %clang -target aarch64 -march=armv8.2a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO83 %s
 // RUN: %clang -target aarch64 -march=armv8.3a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO83 %s
 // RUN: %clang -target aarch64 -march=armv8a+crypto+nocrypto+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO83 %s
-// CHECK-CRYPTO83: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crypto" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-CRYPTO83: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+aes"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2"
 //
 // Check -crypto:
 //
 // RUN: %clang -target aarch64 -march=armv8a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO8A %s
-// RUN: %clang -target aarch64 -march=armv8.1a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO81 %s
-// RUN: %clang -target aarch64 -march=armv8.2a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO82 %s
-// RUN: %clang -target aarch64 -march=armv8.3a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO82 %s
-// RUN: %clang -target aarch64 -march=armv8.3a+nocrypto+crypto+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO82 %s
+// RUN: %clang -target aarch64 -march=armv8.1a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO8A %s
+// RUN: %clang -target aarch64 -march=armv8.2a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO8A %s
+// RUN: %clang -target aarch64 -march=armv8.3a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO8A %s
+// RUN: %clang -target aarch64 -march=armv8.3a+nocrypto+crypto+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO8A %s
 
-// CHECK-NOCRYPTO8A: "-target-feature" "+neon" "-target-feature" "+v8a" "-target-feature" "-crypto" "-target-feature" "-sha2" "-target-feature" "-aes" "-target-abi" "aapcs"
-// CHECK-NOCRYPTO81: "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "-crypto" "-target-feature" "-sha2" "-target-feature" "-aes" "-target-abi" "aapcs"
-// CHECK-NOCRYPTO82: "-target-feature" "+neon" "-target-feature" "+v8.{{.}}a" "-target-feature" "-crypto" "-target-feature" "-sha2" "-target-feature" "-aes" "-target-feature" "-sm4" "-target-feature" "-sha3" "-target-abi" "aapcs"
+// CHECK-NOCRYPTO8A-NOT: "-target-feature" "+crypto"
+// CHECK-NOCRYPTO8A-NOT: "-target-feature" "+aes"
+// CHECK-NOCRYPTO8A-NOT: "-target-feature" "+sha2"
 //
 // Check +crypto -sha2 -aes:
 //
@@ -422,7 +422,7 @@
 // Check -crypto +sha2 +aes:
 //
 // RUN: %clang -target aarch64 -march=armv8.1a+nocrypto+sha2+aes -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO83-SHA2-AES %s
-// CHECK-NOCRYPTO83-SHA2-AES: "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-NOCRYPTO83-SHA2-AES: "-target-feature" "+aes"{{.*}} "-target-feature" "+sha2"
 //
 //
 // Arch >= ARMv8.4:  crypto = sm4 + sha3 + sha2 + aes
@@ -430,14 +430,11 @@
 //
 // Check +crypto:
 //
-// RUN: %clang -target aarch64 -march=armv8.4a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO84 %s
-// RUN: %clang -target aarch64 -march=armv8.5a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO85 %s
-// RUN: %clang -target aarch64 -march=armv8.6a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO86 %s
-// RUN: %clang -target aarch64 -march=armv8.7a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO87 %s
-// CHECK-CRYPTO84: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a"{{.*}} "-target-feature" "+crypto" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
-// CHECK-CRYPTO85: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.5a"{{.*}} "-target-feature" "+crypto" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
-// CHECK-CRYPTO86: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.6a"{{.*}} "-target-feature" "+crypto" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
-// CHECK-CRYPTO87: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.7a"{{.*}} "-target-feature" "+crypto" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// RUN: %clang -target aarch64 -march=armv8.4a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO8_4567 %s
+// RUN: %clang -target aarch64 -march=armv8.5a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO8_4567 %s
+// RUN: %clang -target aarch64 -march=armv8.6a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO8_4567 %s
+// RUN: %clang -target aarch64 -march=armv8.7a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO8_4567 %s
+// CHECK-CRYPTO8_4567: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.{{[4567]}}a"{{.*}} "-target-feature" "+aes"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2"{{.*}} "-target-feature" "+sha3"{{.*}} "-target-feature" "+sm4"
 //
 // Check -crypto:
 //
@@ -447,7 +444,7 @@
 // Check +crypto -sm4 -sha3:
 //
 // RUN: %clang -target aarch64 -march=armv8.4a+crypto+sm4+nosm4+sha3+nosha3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO84-NOSMSHA %s
-// CHECK-CRYPTO84-NOSMSHA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a" "-target-feature" "+crypto" "-target-feature" "-sm4" "-target-feature" "-sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-CRYPTO84-NOSMSHA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a"{{.*}} "-target-feature" "+aes"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2"{{.*}} "-target-feature" "-sha3"{{.*}} "-target-feature" "-sm4"
 //
 
 // RUN: %clang -target aarch64 -mcpu=cyclone+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-1 %s
@@ -461,20 +458,22 @@
 // RUN: %clang -target aarch64 -mcpu=generic+Crc -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-2 %s
 // 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" "+v8a" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "-crypto" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "-sha2" "-target-feature" "-aes"
-// CHECK-MCPU-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc"
-// CHECK-MCPU-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "-neon" "-target-feature" "-sha2" "-target-feature" "-aes"
+// 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" "-sha2" "-target-feature" "-neon"
 
 // 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
-// CHECK-MCPU-MARCH: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8a" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// CHECK-MCPU-MARCH-NOT: "-target-feature" "+aes"
+// CHECK-MCPU-MARCH-NOT: "-target-feature" "+sha2"
+// CHECK-MCPU-MARCH-NOT: "-target-feature" "+crypto"
 
-// RUN: %clang -target aarch64 -mcpu=cortex-a53 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cyclone -mcpu=cortex-a53  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
+// RUN: %clang -target aarch64 -mcpu=cortex-a53 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE --ignore-case %s
+// RUN: %clang -target aarch64 -mtune=cyclone -mcpu=cortex-a53  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE --ignore-case %s
 // ================== Check whether -mtune accepts mixed-case features.
-// RUN: %clang -target aarch64 -mcpu=cortex-a53 -mtune=CYCLONE -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=CyclonE -mcpu=cortex-a53  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
-// CHECK-MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// RUN: %clang -target aarch64 -mcpu=cortex-a53 -mtune=CYCLONE -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE --ignore-case %s
+// RUN: %clang -target aarch64 -mtune=CyclonE -mcpu=cortex-a53  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE --ignore-case %s
+// CHECK-MCPU-MTUNE: "-tune-cpu" "cyclone"
 
 // RUN: not %clang -target aarch64 -mcpu=generic+neon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
 // RUN: not %clang -target aarch64 -mcpu=generic+noneon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
@@ -489,9 +488,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" "+neon" "-target-feature" "+v8.1a" "-target-feature" "+crypto"
-// CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "-crypto"
-// CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-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" "+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 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/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 87ba7aca1df7dd..0ab218f15d7df9 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -27,6 +27,10 @@ namespace llvm {
 class Triple;
 
 namespace AArch64 {
+
+struct ArchInfo;
+struct CpuInfo;
+
 // Function Multi Versioning CPU features. They must be kept in sync with
 // compiler-rt enum CPUFeatures in lib/builtins/cpu_model.c with FEAT_MAX as
 // sentinel.
@@ -308,6 +312,92 @@ inline constexpr ExtensionInfo Extensions[] = {
 };
 // clang-format on
 
+struct ExtensionSet {
+  // Set of extensions which are currently enabled.
+  ExtensionBitset Enabled;
+  // Set of extensions which have been enabled or disabled at any point. Used
+  // to avoid cluttering the cc1 command-line with lots of unneeded features.
+  ExtensionBitset Touched;
+  // Base architecture version, which we need to know because some feature
+  // dependencies change depending on this.
+  const ArchInfo *BaseArch;
+
+  ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {}
+
+  // Enable the given architecture extension, and any other extensions it
+  // depends on.
+  void enable(ArchExtKind E);
+  // Disable the given architecture extension, and any other extensions which
+  // depend on it.
+  void disable(ArchExtKind E);
+
+  // Add default extensions for the given CPU.
+  void addCPUDefaults(const CpuInfo &CPU);
+  // Add default extensions for the given architecture version.
+  void addArchDefaults(const ArchInfo &Arch);
+
+  // Add or remove a feature based on a modifier string. The string must be of
+  // the form "<name>" to enable a feature or "no<name>" to disable it. This
+  // will also enable or disable any features as required by the dependencies
+  // between them.
+  bool parseModifier(StringRef Modifier);
+
+  // Convert the set of enabled extension to an LLVM feature list, appending
+  // them to Features.
+  void toLLVMFeatureList(std::vector<StringRef> &Features) const;
+};
+
+struct ExtensionDependency {
+  ArchExtKind Earlier;
+  ArchExtKind Later;
+};
+
+inline constexpr ExtensionDependency ExtensionDependencies[] = {
+  {AEK_FP, AEK_FP16},
+  {AEK_FP, AEK_SIMD},
+  {AEK_FP, AEK_JSCVT},
+  {AEK_FP, AEK_FP8},
+  {AEK_SIMD, AEK_CRYPTO},
+  {AEK_SIMD, AEK_AES},
+  {AEK_SIMD, AEK_SHA2},
+  {AEK_SIMD, AEK_SHA3},
+  {AEK_SIMD, AEK_SM4},
+  {AEK_SIMD, AEK_RDM},
+  {AEK_SIMD, AEK_DOTPROD},
+  {AEK_SIMD, AEK_FCMA},
+  {AEK_FP16, AEK_FP16FML},
+  {AEK_FP16, AEK_SVE},
+  {AEK_BF16, AEK_SME},
+  {AEK_BF16, AEK_B16B16},
+  {AEK_SVE, AEK_SVE2},
+  {AEK_SVE, AEK_F32MM},
+  {AEK_SVE, AEK_F64MM},
+  {AEK_SVE2, AEK_SVE2p1},
+  {AEK_SVE2, AEK_SVE2BITPERM},
+  {AEK_SVE2, AEK_SVE2AES},
+  {AEK_SVE2, AEK_SVE2SHA3},
+  {AEK_SVE2, AEK_SVE2SM4},
+  {AEK_SVE2, AEK_SMEFA64},
+  {AEK_SVE2, AEK_SMEFA64},
+  {AEK_SME, AEK_SME2},
+  {AEK_SME, AEK_SMEF16F16},
+  {AEK_SME, AEK_SMEF64F64},
+  {AEK_SME, AEK_SMEI16I64},
+  {AEK_SME, AEK_SMEFA64},
+  {AEK_SME2, AEK_SME2p1},
+  {AEK_SME2, AEK_SSVE_FP8FMA},
+  {AEK_SME2, AEK_SSVE_FP8DOT2},
+  {AEK_SME2, AEK_SSVE_FP8DOT4},
+  {AEK_SME2, AEK_SMEF8F16},
+  {AEK_SME2, AEK_SMEF8F32},
+  {AEK_FP8, AEK_SMEF8F16},
+  {AEK_FP8, AEK_SMEF8F32},
+  {AEK_LSE, AEK_LSE128},
+  {AEK_PREDRES, AEK_SPECRES2},
+  {AEK_RAS, AEK_RASv2},
+  {AEK_RCPC, AEK_RCPC3},
+};
+
 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
 
 // Information about a specific architecture, e.g. V8.1-A
@@ -329,9 +419,9 @@ struct ArchInfo {
   // Defines the following partial order, indicating when an architecture is
   // a superset of another:
   //
-  //     v9.4a > v9.3a > v9.3a > v9.3a > v9a;
-  //       v       v       v       v       v
-  //     v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
+  //   v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a;
+  //             v       v       v       v       v
+  //           v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
   //
   // v8r has no relation to anything. This is used to determine which
   // features to enable for a given architecture. See
@@ -351,6 +441,12 @@ struct ArchInfo {
     return false;
   }
 
+  // True if this architecture is a superset of Other (including being equal to
+  // it).
+  bool is_superset(const ArchInfo &Other) const {
+    return (*this == Other) || implies(Other);
+  }
+
   // Return ArchFeature without the leading "+".
   StringRef getSubArch() const { return ArchFeature.substr(1); }
 
@@ -711,10 +807,10 @@ StringRef getArchExtFeature(StringRef ArchExt);
 StringRef resolveCPUAlias(StringRef CPU);
 
 // Information by Name
-std::optional<ArchInfo> getArchForCpu(StringRef CPU);
+const ArchInfo *getArchForCpu(StringRef CPU);
 
 // Parser
-std::optional<ArchInfo> parseArch(StringRef Arch);
+const ArchInfo *parseArch(StringRef Arch);
 std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
 // Given the name of a CPU or alias, return the correponding CpuInfo.
 std::optional<CpuInfo> parseCpu(StringRef Name);
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index c1cb096bb66dea..4198ac6c1c0390 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -6868,7 +6868,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
   std::tie(Arch, ExtensionString) =
       getParser().parseStringToEndOfStatement().trim().split('+');
 
-  std::optional<AArch64::ArchInfo> ArchInfo = AArch64::parseArch(Arch);
+  const AArch64::ArchInfo *ArchInfo = AArch64::parseArch(Arch);
   if (!ArchInfo)
     return Error(ArchLoc, "unknown arch name");
 
@@ -6970,7 +6970,7 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
   if (!ExtensionString.empty())
     ExtensionString.split(RequestedExtensions, '+');
 
-  const std::optional<llvm::AArch64::ArchInfo> CpuArch = llvm::AArch64::getArchForCpu(CPU);
+  const llvm::AArch64::ArchInfo *CpuArch = llvm::AArch64::getArchForCpu(CPU);
   if (!CpuArch) {
     Error(CurLoc, "unknown CPU name");
     return false;
diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp
index d3c72497c41cbe..8da5084c9efb63 100644
--- a/llvm/lib/TargetParser/AArch64TargetParser.cpp
+++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp
@@ -12,12 +12,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/TargetParser/AArch64TargetParser.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/ARMTargetParserCommon.h"
 #include "llvm/TargetParser/Triple.h"
 #include <cctype>
 
+#define DEBUG_TYPE "target-parser"
+
 using namespace llvm;
 
 static unsigned checkArchVersion(llvm::StringRef Arch) {
@@ -26,15 +29,15 @@ static unsigned checkArchVersion(llvm::StringRef Arch) {
   return 0;
 }
 
-std::optional<AArch64::ArchInfo> AArch64::getArchForCpu(StringRef CPU) {
+const AArch64::ArchInfo *AArch64::getArchForCpu(StringRef CPU) {
   if (CPU == "generic")
-    return ARMV8A;
+    return &ARMV8A;
 
   // Note: this now takes cpu aliases into account
   std::optional<CpuInfo> Cpu = parseCpu(CPU);
   if (!Cpu)
-    return {};
-  return Cpu->Arch;
+    return nullptr;
+  return &Cpu->Arch;
 }
 
 std::optional<AArch64::ArchInfo> AArch64::ArchInfo::findBySubArch(StringRef SubArch) {
@@ -103,7 +106,7 @@ bool AArch64::isX18ReservedByDefault(const Triple &TT) {
 }
 
 // Allows partial match, ex. "v8a" matches "armv8a".
-std::optional<AArch64::ArchInfo> AArch64::parseArch(StringRef Arch) {
+const AArch64::ArchInfo *AArch64::parseArch(StringRef Arch) {
   Arch = llvm::ARM::getCanonicalArchName(Arch);
   if (checkArchVersion(Arch) < 8)
     return {};
@@ -111,7 +114,7 @@ std::optional<AArch64::ArchInfo> AArch64::parseArch(StringRef Arch) {
   StringRef Syn = llvm::ARM::getArchSynonym(Arch);
   for (const auto *A : ArchInfos) {
     if (A->Name.ends_with(Syn))
-      return *A;
+      return A;
   }
   return {};
 }
@@ -150,3 +153,137 @@ void AArch64::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
     }
   }
 }
+
+const llvm::AArch64::ExtensionInfo &
+lookupExtensionByID(llvm::AArch64::ArchExtKind ExtID) {
+  for (const auto &E : llvm::AArch64::Extensions)
+    if (E.ID == ExtID)
+      return E;
+  assert(false && "Invalid extension ID");
+}
+
+void AArch64::ExtensionSet::enable(ArchExtKind E) {
+  if (Enabled.test(E))
+    return;
+
+  LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).Name << "\n");
+
+  Touched.set(E);
+  Enabled.set(E);
+
+  // Recursively enable all features that this one depends on. This handles all
+  // of the simple cases, where the behaviour doesn't depend on the base
+  // architecture version.
+  for (auto Dep : ExtensionDependencies)
+    if (E == Dep.Later)
+      enable(Dep.Earlier);
+
+  // Special cases for dependencies which vary depending on the base
+  // architecture version.
+  if (BaseArch) {
+    // +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+
+    // It isn't the case in general that sve implies both f64mm and f32mm
+    if (E == AEK_SVE && BaseArch->is_superset(ARMV8_6A))
+      enable(AEK_F32MM);
+
+    // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
+    if (E == AEK_FP16 && BaseArch->is_superset(ARMV8_4A) &&
+        !BaseArch->is_superset(ARMV9A))
+      enable(AEK_FP16FML);
+
+    // For all architectures, +crypto enables +aes and +sha2.
+    if (E == AEK_CRYPTO) {
+      enable(AEK_AES);
+      enable(AEK_SHA2);
+    }
+
+    // For v8.4A+ and v9.0A+, +crypto also enables +sha3 and +sm4.
+    if (E == AEK_CRYPTO && BaseArch->is_superset(ARMV8_4A)) {
+      enable(AEK_SHA3);
+      enable(AEK_SM4);
+    }
+  }
+}
+
+void AArch64::ExtensionSet::disable(ArchExtKind E) {
+  // -crypto always disables aes, sha2, sha3 and sm4, even for architectures
+  // where the latter two would not be enabled by +crypto.
+  if (E == AEK_CRYPTO) {
+    disable(AEK_AES);
+    disable(AEK_SHA2);
+    disable(AEK_SHA3);
+    disable(AEK_SM4);
+  }
+
+  if (!Enabled.test(E))
+    return;
+
+  LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).Name << "\n");
+
+  Touched.set(E);
+  Enabled.reset(E);
+
+  // Recursively disable all features that depends on this one.
+  for (auto Dep : ExtensionDependencies)
+    if (E == Dep.Earlier)
+      disable(Dep.Later);
+}
+
+void AArch64::ExtensionSet::toLLVMFeatureList(
+    std::vector<StringRef> &Features) const {
+  if (BaseArch && !BaseArch->ArchFeature.empty())
+    Features.push_back(BaseArch->ArchFeature);
+
+  for (const auto &E : Extensions) {
+    if (E.Feature.empty() || !Touched.test(E.ID))
+      continue;
+    if (Enabled.test(E.ID))
+      Features.push_back(E.Feature);
+    else
+      Features.push_back(E.NegFeature);
+  }
+}
+
+void AArch64::ExtensionSet::addCPUDefaults(const CpuInfo &CPU) {
+  LLVM_DEBUG(llvm::dbgs() << "addCPUDefaults(" << CPU.Name << ")\n");
+  BaseArch = &CPU.Arch;
+
+  AArch64::ExtensionBitset CPUExtensions = CPU.getImpliedExtensions();
+  for (const auto &E : Extensions)
+    if (CPUExtensions.test(E.ID))
+      enable(E.ID);
+}
+
+void AArch64::ExtensionSet::addArchDefaults(const ArchInfo &Arch) {
+  LLVM_DEBUG(llvm::dbgs() << "addArchDefaults(" << Arch.Name << ")\n");
+  BaseArch = &Arch;
+
+  for (const auto &E : Extensions)
+    if (Arch.DefaultExts.test(E.ID))
+      enable(E.ID);
+}
+
+bool AArch64::ExtensionSet::parseModifier(StringRef Modifier) {
+  LLVM_DEBUG(llvm::dbgs() << "parseModifier(" << Modifier << ")\n");
+
+  // Negative modifiers, with the syntax "no<feat>"
+  if (Modifier.starts_with("no")) {
+    StringRef ModifierBase(Modifier.substr(2));
+    for (const auto &AE : Extensions) {
+      if (!AE.NegFeature.empty() && ModifierBase == AE.Name) {
+        disable(AE.ID);
+        return true;
+      }
+    }
+  }
+
+  // Positive modifiers
+  for (const auto &AE : Extensions) {
+    if (!AE.Feature.empty() && Modifier == AE.Name) {
+      enable(AE.ID);
+      return true;
+    }
+  }
+
+  return false;
+}
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 63b43bc39e6a0d..af0302a7bf5707 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -11,6 +11,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/TargetParser/AArch64TargetParser.h"
 #include "llvm/TargetParser/ARMTargetParser.h"
@@ -24,6 +25,9 @@
 
 using namespace llvm;
 
+using ::testing::Contains;
+using ::testing::StrEq;
+
 namespace {
 const char *ARMArch[] = {
     "armv4",        "armv4t",      "armv5",          "armv5t",      "armv5e",
@@ -1659,8 +1663,8 @@ TEST(TargetParserTest, testAArch64CPUArchList) {
 
 bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
                      unsigned ArchAttr) {
-  const std::optional<AArch64::ArchInfo> AI = AArch64::parseArch(Arch);
-  return AI.has_value();
+  const AArch64::ArchInfo *AI = AArch64::parseArch(Arch);
+  return AI != nullptr;
 }
 
 TEST(TargetParserTest, testAArch64Arch) {
@@ -2099,4 +2103,335 @@ TEST(TargetParserTest, AArch64PrintSupportedExtensions) {
   EXPECT_EQ(std::string::npos, captured.find("ssbs2"));
 }
 
+struct AArch64ExtensionDependenciesBaseArchTestParams {
+  const llvm::AArch64::ArchInfo &Arch;
+  std::vector<StringRef> Modifiers;
+  std::vector<StringRef> ExpectedPos;
+  std::vector<StringRef> ExpectedNeg;
+};
+
+class AArch64ExtensionDependenciesBaseArchTestFixture
+    : public ::testing::TestWithParam<
+          AArch64ExtensionDependenciesBaseArchTestParams> {};
+
+struct AArch64ExtensionDependenciesBaseCPUTestParams {
+  StringRef CPUName;
+  std::vector<StringRef> Modifiers;
+  std::vector<StringRef> ExpectedPos;
+  std::vector<StringRef> ExpectedNeg;
+};
+
+class AArch64ExtensionDependenciesBaseCPUTestFixture
+    : public ::testing::TestWithParam<
+          AArch64ExtensionDependenciesBaseCPUTestParams> {};
+
+TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture,
+       AArch64ExtensionDependenciesBaseArch) {
+  auto Params = GetParam();
+
+  llvm::AArch64::ExtensionSet Extensions;
+  Extensions.addArchDefaults(Params.Arch);
+  for (auto M : Params.Modifiers) {
+    bool success = Extensions.parseModifier(M);
+    EXPECT_TRUE(success);
+  }
+  std::vector<StringRef> Features;
+  Extensions.toLLVMFeatureList(Features);
+
+  for (auto E : Params.ExpectedPos) {
+    std::string PosString = "+";
+    PosString += E;
+    std::string NegString = "-";
+    NegString += E;
+    ASSERT_THAT(Features, Contains(StrEq(PosString)));
+    ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
+  }
+
+  for (auto E : Params.ExpectedNeg) {
+    std::string PosString = "+";
+    PosString += E;
+    ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
+    // Features default to off, so the negative string is not expected in many
+    // cases.
+  }
+}
+
+TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture,
+       AArch64ExtensionDependenciesBaseCPU) {
+  auto Params = GetParam();
+
+  llvm::AArch64::ExtensionSet Extensions;
+  const std::optional<llvm::AArch64::CpuInfo> CPU =
+      llvm::AArch64::parseCpu(Params.CPUName);
+  EXPECT_TRUE(CPU);
+  Extensions.addCPUDefaults(*CPU);
+  for (auto M : Params.Modifiers) {
+    bool success = Extensions.parseModifier(M);
+    EXPECT_TRUE(success);
+  }
+  std::vector<StringRef> Features;
+  Extensions.toLLVMFeatureList(Features);
+
+  for (auto E : Params.ExpectedPos) {
+    std::string PosString = "+";
+    PosString += E;
+    std::string NegString = "-";
+    NegString += E;
+    ASSERT_THAT(Features, Contains(StrEq(PosString)));
+    ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
+  }
+
+  for (auto E : Params.ExpectedNeg) {
+    std::string PosString = "+";
+    PosString += E;
+    ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
+    // Features default to off, so the negative string is not expected in many
+    // cases.
+  }
+}
+
+AArch64ExtensionDependenciesBaseArchTestParams
+    AArch64ExtensionDependenciesArchData[] = {
+        // Base architecture features
+        {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},
+        {AArch64::ARMV8_1A,
+         {},
+         {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
+         {}},
+        {AArch64::ARMV9_5A, {}, {"v9.5a", "sve", "sve2", "mops", "cpa"}, {}},
+
+        // Positive modifiers
+        {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}},
+        {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}},
+
+        // Negative modifiers
+        {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},
+
+        // Mixed modifiers
+        {AArch64::ARMV8A,
+         {"fp16", "nofp16"},
+         {"v8a", "fp-armv8", "neon"},
+         {"fullfp16"}},
+        {AArch64::ARMV8A,
+         {"fp16", "nofp"},
+         {"v8a"},
+         {"fp-armv8", "neon", "fullfp16"}},
+
+        // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
+        {AArch64::ARMV8A,
+         {"nofp", "sve2-bitperm"},
+         {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
+         {}},
+        {AArch64::ARMV8A,
+         {"sve2-bitperm", "nofp16"},
+         {"fp-armv8"},
+         {"full-fp16", "sve", "sve2", "sve2-bitperm"}},
+
+        // Meaning of +crypto varies with base architecture.
+        {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}},
+        {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
+        {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
+
+        // -crypto always disables all crypto features, even if it wouldn't
+        // enable them.
+        {AArch64::ARMV8A,
+         {"aes", "sha2", "sha3", "sm4", "nocrypto"},
+         {},
+         {"aes", "sha2", "sha3", "sm4"}},
+        {AArch64::ARMV8_4A,
+         {"aes", "sha2", "sha3", "sm4", "nocrypto"},
+         {},
+         {"aes", "sha2", "sha3", "sm4"}},
+
+        // +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+, but
+        // not earlier architectures.
+        {AArch64::ARMV8_5A, {"sve"}, {"sve"}, {"f32mm"}},
+        {AArch64::ARMV9A, {"sve"}, {"sve"}, {"f32mm"}},
+        {AArch64::ARMV8_6A, {"sve"}, {"sve", "f32mm"}, {}},
+        {AArch64::ARMV9_1A, {"sve"}, {"sve", "f32mm"}, {}},
+
+        // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
+        {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
+        {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
+        {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}},
+
+        // fp -> fp16
+        {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
+        {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
+
+        // fp -> simd
+        {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
+        {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
+
+        // fp -> jscvt
+        {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
+        {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
+
+        // simd -> {aes, sha2, sha3, sm4}
+        {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}},
+        {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}},
+        {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
+        {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},
+        {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},
+        {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},
+        {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},
+        {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},
+
+        // simd -> {rdm, dotprod, fcma}
+        {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},
+        {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},
+        {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},
+        {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},
+        {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
+        {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
+
+        // fp16 -> {fp16fml, sve}
+        {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
+        {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
+        {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
+        {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
+
+        // bf16 -> {sme, b16b16}
+        {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
+        {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
+        {AArch64::ARMV8A, {"nobf16", "b16b16"}, {"bf16", "b16b16"}, {}},
+        {AArch64::ARMV8A, {"b16b16", "nobf16"}, {}, {"bf16", "b16b16"}},
+
+        // sve -> {sve2, f32mm, f64mm}
+        {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
+        {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
+        {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
+        {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},
+        {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},
+        {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},
+
+        // sve2 -> {sve2p1, sve2-bitperm, sve2-aes, sve2-sha3, sve2-sm4}
+        {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},
+        {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},
+        {AArch64::ARMV8A,
+         {"nosve2", "sve2-bitperm"},
+         {"sve2", "sve2-bitperm"},
+         {}},
+        {AArch64::ARMV8A,
+         {"sve2-bitperm", "nosve2"},
+         {},
+         {"sve2", "sve2-bitperm"}},
+        {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},
+        {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},
+        {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},
+        {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},
+        {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},
+        {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},
+
+        // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
+        {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
+        {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
+        {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},
+        {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},
+        {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},
+        {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},
+        {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},
+        {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},
+        {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},
+        {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
+
+        // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
+        // sme-f8f32}
+        {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
+        {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
+        {AArch64::ARMV8A,
+         {"nosme2", "ssve-fp8fma"},
+         {"sme2", "ssve-fp8fma"},
+         {}},
+        {AArch64::ARMV8A,
+         {"ssve-fp8fma", "nosme2"},
+         {},
+         {"sme2", "ssve-fp8fma"}},
+        {AArch64::ARMV8A,
+         {"nosme2", "ssve-fp8dot2"},
+         {"sme2", "ssve-fp8dot2"},
+         {}},
+        {AArch64::ARMV8A,
+         {"ssve-fp8dot2", "nosme2"},
+         {},
+         {"sme2", "ssve-fp8dot2"}},
+        {AArch64::ARMV8A,
+         {"nosme2", "ssve-fp8dot4"},
+         {"sme2", "ssve-fp8dot4"},
+         {}},
+        {AArch64::ARMV8A,
+         {"ssve-fp8dot4", "nosme2"},
+         {},
+         {"sme2", "ssve-fp8dot4"}},
+        {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},
+        {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},
+        {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},
+        {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
+
+        // fp8 -> {sme-f8f16, sme-f8f32}
+        {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
+        {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
+        {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
+        {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
+
+        // lse -> lse128
+        {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
+        {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
+
+        // predres -> predres2
+        {AArch64::ARMV8A,
+         {"nopredres", "predres2"},
+         {"predres", "specres2"},
+         {}},
+        {AArch64::ARMV8A,
+         {"predres2", "nopredres"},
+         {},
+         {"predres", "specres2"}},
+
+        // ras -> ras2
+        {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
+        {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
+
+        // rcpc -> rcpc3
+        {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
+        {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    AArch64ExtensionDependenciesBaseArch,
+    AArch64ExtensionDependenciesBaseArchTestFixture,
+    ::testing::ValuesIn(AArch64ExtensionDependenciesArchData));
+
+AArch64ExtensionDependenciesBaseCPUTestParams
+    AArch64ExtensionDependenciesCPUData[] = {
+        // Base CPU features
+        {"cortex-a57",
+         {},
+         {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
+         {}},
+        {"cortex-r82",
+         {},
+         {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
+          "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
+         {}},
+        {"cortex-a520",
+         {},
+         {"v9.2a",    "bf16",     "crc",     "dotprod", "f32mm",        "flagm",
+          "fp-armv8", "fullfp16", "fp16fml", "i8mm",    "lse",          "mte",
+          "pauth",    "perfmon",  "predres", "ras",     "rcpc",         "rdm",
+          "sb",       "neon",     "ssbs",    "sve",     "sve2-bitperm", "sve2"},
+         {}},
+
+        // Negative modifiers
+        {"cortex-r82",
+         {"nofp"},
+         {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},
+         {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    AArch64ExtensionDependenciesBaseCPU,
+    AArch64ExtensionDependenciesBaseCPUTestFixture,
+    ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));
+
 } // namespace

>From b52130a89d3e17c8b66574771c6174c66dd70114 Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Tue, 16 Jan 2024 13:12:23 +0000
Subject: [PATCH 2/6] clang-format

---
 clang/lib/Driver/ToolChains/Arch/AArch64.cpp         | 6 ++++--
 llvm/include/llvm/TargetParser/AArch64TargetParser.h | 2 ++
 llvm/unittests/TargetParser/TargetParserTest.cpp     | 2 +-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 5037b669da51ce..85f053dc8b6eab 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -203,9 +203,11 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
   if (!WaMArch.empty())
     success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Extensions);
   else if ((A = Args.getLastArg(options::OPT_march_EQ)))
-    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Extensions);
+    success =
+        getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Extensions);
   else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
-    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions);
+    success =
+        getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions);
   else if (isCPUDeterminedByTriple(Triple))
     success = getAArch64ArchFeaturesFromMcpu(
         D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions);
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 0ab218f15d7df9..712041158636e4 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -352,6 +352,7 @@ struct ExtensionDependency {
   ArchExtKind Later;
 };
 
+// clang-format off
 inline constexpr ExtensionDependency ExtensionDependencies[] = {
   {AEK_FP, AEK_FP16},
   {AEK_FP, AEK_SIMD},
@@ -397,6 +398,7 @@ inline constexpr ExtensionDependency ExtensionDependencies[] = {
   {AEK_RAS, AEK_RASv2},
   {AEK_RCPC, AEK_RCPC3},
 };
+// clang-format on
 
 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
 
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index af0302a7bf5707..f41b856da7c189 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -8,8 +8,8 @@
 
 #include "llvm/TargetParser/TargetParser.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FormatVariadic.h"

>From 60962106e065f2b7582a424b251b4f06dfe22552 Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Tue, 16 Jan 2024 13:41:33 +0000
Subject: [PATCH 3/6] Fix flang test

---
 flang/test/Driver/target-cpu-features.f90 | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/flang/test/Driver/target-cpu-features.f90 b/flang/test/Driver/target-cpu-features.f90
index f950872d5f6ce2..eaaa064807ecbf 100644
--- a/flang/test/Driver/target-cpu-features.f90
+++ b/flang/test/Driver/target-cpu-features.f90
@@ -36,7 +36,10 @@
 ! CHECK-A76-SAME: "-target-cpu" "cortex-a76" "-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" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+ssbs"
 
 ! CHECK-ARMV9: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
-! CHECK-ARMV9-SAME: "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
+! CHECK-ARMV9-SAME: "-target-cpu" "generic"
+! CHECK-ARMV9-SAME: "-target-feature" "+v9a"
+! CHECK-ARMV9-SAME: "-target-feature" "+sve"
+! CHECK-ARMV9-SAME: "-target-feature" "+sve2"
 
 ! CHECK-NO-A57: "-fc1" "-triple" "x86_64-unknown-linux-gnu"
 ! CHECK-NO-A57-NOT: cortex-a57

>From ea9b779d4ba292e8c1d8aaaf22d4cfe94e2d9646 Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Wed, 17 Jan 2024 14:38:17 +0000
Subject: [PATCH 4/6] Expand comments

---
 .../llvm/TargetParser/AArch64TargetParser.h   | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 712041158636e4..0dd46bd9bc6804 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -325,15 +325,22 @@ struct ExtensionSet {
   ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {}
 
   // Enable the given architecture extension, and any other extensions it
-  // depends on.
+  // depends on. Does not change the base architecture, or follow dependencies
+  // between features which are only related by required arcitecture versions.
   void enable(ArchExtKind E);
+
   // Disable the given architecture extension, and any other extensions which
-  // depend on it.
+  // depend on it. Does not change the base architecture, or follow
+  // dependencies between features which are only related by required
+  // arcitecture versions.
   void disable(ArchExtKind E);
 
-  // Add default extensions for the given CPU.
+  // Add default extensions for the given CPU. Records the base architecture,
+  // to later resolve dependencies which depend on it.
   void addCPUDefaults(const CpuInfo &CPU);
-  // Add default extensions for the given architecture version.
+
+  // Add default extensions for the given architecture version. Records the
+  // base architecture, to later resolve dependencies which depend on it.
   void addArchDefaults(const ArchInfo &Arch);
 
   // Add or remove a feature based on a modifier string. The string must be of
@@ -347,6 +354,10 @@ struct ExtensionSet {
   void toLLVMFeatureList(std::vector<StringRef> &Features) const;
 };
 
+
+// Represents a dependency between two architecture extensions. If Later is
+// enabled, then Earlier must also be enabled. If Earlier is disabled, then
+// Later must also be disabled.
 struct ExtensionDependency {
   ArchExtKind Earlier;
   ArchExtKind Later;

>From f66989fa868b72c7375b061b683034ae605eab4a Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Wed, 17 Jan 2024 14:48:16 +0000
Subject: [PATCH 5/6] clang-format

---
 llvm/include/llvm/TargetParser/AArch64TargetParser.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 0dd46bd9bc6804..f90da823d62e3d 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -354,7 +354,6 @@ struct ExtensionSet {
   void toLLVMFeatureList(std::vector<StringRef> &Features) const;
 };
 
-
 // Represents a dependency between two architecture extensions. If Later is
 // enabled, then Earlier must also be enabled. If Earlier is disabled, then
 // Later must also be disabled.

>From 2e2ffda5cbbdd898a87a24a2581f22a082c3a3cd Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Wed, 17 Jan 2024 15:59:13 +0000
Subject: [PATCH 6/6] comments

---
 llvm/include/llvm/TargetParser/AArch64TargetParser.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index f90da823d62e3d..ddf5ab4d2df36c 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -354,15 +354,18 @@ struct ExtensionSet {
   void toLLVMFeatureList(std::vector<StringRef> &Features) const;
 };
 
-// Represents a dependency between two architecture extensions. If Later is
-// enabled, then Earlier must also be enabled. If Earlier is disabled, then
-// Later must also be disabled.
+// Represents a dependency between two architecture extensions. Later is the
+// feature which was added to the architecture after Earlier, and expands the
+// functionality provided by it. If Later is enabled, then Earlier will also be
+// enabled. If Earlier is disabled, then Later will also be disabled.
 struct ExtensionDependency {
   ArchExtKind Earlier;
   ArchExtKind Later;
 };
 
 // clang-format off
+// Each entry here is a link in the dependency chain starting from the
+// extension that was added to the architecture first.
 inline constexpr ExtensionDependency ExtensionDependencies[] = {
   {AEK_FP, AEK_FP16},
   {AEK_FP, AEK_SIMD},



More information about the cfe-commits mailing list