[clang] 13e977d - [AArch64][Driver] Better handling of target feature dependencies (#78270)

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


Author: ostannard
Date: 2024-01-17T16:20:34Z
New Revision: 13e977d1738261487d8157918f14497517d75821

URL: https://github.com/llvm/llvm-project/commit/13e977d1738261487d8157918f14497517d75821
DIFF: https://github.com/llvm/llvm-project/commit/13e977d1738261487d8157918f14497517d75821.diff

LOG: [AArch64][Driver] Better handling of target feature dependencies (#78270)

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.

Added: 
    

Modified: 
    clang/lib/Basic/Targets/AArch64.cpp
    clang/lib/Driver/ToolChains/Arch/AArch64.cpp
    clang/test/Driver/aarch64-bf16.c
    clang/test/Driver/aarch64-cortex-a510.c
    clang/test/Driver/aarch64-cortex-a710.c
    clang/test/Driver/aarch64-cortex-x2.c
    clang/test/Driver/aarch64-d128.c
    clang/test/Driver/aarch64-fp16.c
    clang/test/Driver/aarch64-implied-sme-features.c
    clang/test/Driver/aarch64-implied-sve-features.c
    clang/test/Driver/aarch64-ite.c
    clang/test/Driver/aarch64-lrcpc3.c
    clang/test/Driver/aarch64-ls64.c
    clang/test/Driver/aarch64-lse128.c
    clang/test/Driver/aarch64-march.c
    clang/test/Driver/aarch64-mgeneral_regs_only.c
    clang/test/Driver/aarch64-mte.c
    clang/test/Driver/aarch64-perfmon.c
    clang/test/Driver/aarch64-predres.c
    clang/test/Driver/aarch64-rand.c
    clang/test/Driver/aarch64-ras.c
    clang/test/Driver/aarch64-rdm.c
    clang/test/Driver/aarch64-ssbs.c
    clang/test/Driver/aarch64-sve2.c
    clang/test/Driver/aarch64-the.c
    clang/test/Driver/aarch64-v81a.c
    clang/test/Driver/aarch64-v82a.c
    clang/test/Driver/aarch64-v83a.c
    clang/test/Driver/aarch64-v84a.c
    clang/test/Driver/aarch64-v85a.c
    clang/test/Driver/aarch64-v86a.c
    clang/test/Driver/aarch64-v87a.c
    clang/test/Driver/aarch64-v88a.c
    clang/test/Driver/aarch64-v89a.c
    clang/test/Driver/aarch64-v91a.c
    clang/test/Driver/aarch64-v92a.c
    clang/test/Driver/aarch64-v93a.c
    clang/test/Driver/aarch64-v94a.c
    clang/test/Driver/aarch64-v95a.c
    clang/test/Driver/arm-sb.c
    clang/test/Preprocessor/aarch64-target-features.c
    flang/test/Driver/target-cpu-features.f90
    llvm/include/llvm/TargetParser/AArch64TargetParser.h
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/TargetParser/AArch64TargetParser.cpp
    llvm/unittests/TargetParser/TargetParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index da6846cdbffb9a..d47181bfca4fc8 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1087,8 +1087,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..85f053dc8b6eab 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");
+      continue;
     }
-
-    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");
-    }
-
-    // +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,19 @@ 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 +235,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 +313,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/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

diff  --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 87ba7aca1df7dd..ddf5ab4d2df36c 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,107 @@ 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. 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. 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. 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. 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
+  // 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;
+};
+
+// 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},
+  {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},
+};
+// clang-format on
+
 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
 
 // Information about a specific architecture, e.g. V8.1-A
@@ -329,9 +434,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 +456,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 +822,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 fe051922061a91..b90e2a4984c0ad 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) {
@@ -97,7 +100,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 {};
@@ -105,7 +108,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 {};
 }
@@ -144,3 +147,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..f41b856da7c189 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -8,9 +8,10 @@
 
 #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"
 #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


        


More information about the cfe-commits mailing list