bsmith updated this revision to Diff 387212.
bsmith edited the summary of this revision.
bsmith added a comment.
Herald added a subscriber: kristof.beyls.

- Fix duplicate arch feature in unit test
- Use enum class instead of plain enum with typedef


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113776/new/

https://reviews.llvm.org/D113776

Files:
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/test/Driver/aarch64-cpus.c
  clang/test/Driver/aarch64-implied-sve-features.c
  llvm/include/llvm/Support/AArch64TargetParser.def
  llvm/unittests/Support/TargetParserTest.cpp

Index: llvm/unittests/Support/TargetParserTest.cpp
===================================================================
--- llvm/unittests/Support/TargetParserTest.cpp
+++ llvm/unittests/Support/TargetParserTest.cpp
@@ -903,11 +903,11 @@
                              AArch64::AEK_SIMD | AArch64::AEK_RAS |
                              AArch64::AEK_LSE | AArch64::AEK_RDM |
                              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_SVE2 | AArch64::AEK_BF16 |
-                             AArch64::AEK_I8MM | AArch64::AEK_SVE2BITPERM |
-                             AArch64::AEK_PAUTH | AArch64::AEK_MTE |
-                             AArch64::AEK_SSBS | AArch64::AEK_FP16FML |
-                             AArch64::AEK_SB,
+                             AArch64::AEK_BF16 | AArch64::AEK_I8MM |
+                             AArch64::AEK_SVE | AArch64::AEK_SVE2 |
+                             AArch64::AEK_SVE2BITPERM | AArch64::AEK_PAUTH |
+                             AArch64::AEK_MTE | AArch64::AEK_SSBS |
+                             AArch64::AEK_FP16FML | AArch64::AEK_SB,
                          "9-A"),
         ARMCPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
                          AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
@@ -1012,12 +1012,12 @@
                          AArch64::AEK_CRC | AArch64::AEK_FP |
                              AArch64::AEK_SIMD | AArch64::AEK_RAS |
                              AArch64::AEK_LSE | AArch64::AEK_RDM |
-                             AArch64::AEK_RCPC | AArch64::AEK_SVE2 |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_MTE |
-                             AArch64::AEK_PAUTH | AArch64::AEK_I8MM |
-                             AArch64::AEK_BF16 | AArch64::AEK_SVE2BITPERM |
-                             AArch64::AEK_SSBS | AArch64::AEK_SB |
-                             AArch64::AEK_FP16FML,
+                             AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+                             AArch64::AEK_MTE | AArch64::AEK_PAUTH |
+                             AArch64::AEK_I8MM | AArch64::AEK_BF16 |
+                             AArch64::AEK_SVE | AArch64::AEK_SVE2 |
+                             AArch64::AEK_SVE2BITPERM | AArch64::AEK_SSBS |
+                             AArch64::AEK_SB | AArch64::AEK_FP16FML,
                          "9-A"),
         ARMCPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
                          AArch64::AEK_NONE | AArch64::AEK_CRYPTO |
Index: llvm/include/llvm/Support/AArch64TargetParser.def
===================================================================
--- llvm/include/llvm/Support/AArch64TargetParser.def
+++ llvm/include/llvm/Support/AArch64TargetParser.def
@@ -145,9 +145,10 @@
 AARCH64_CPU_NAME("cortex-a55", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
                  (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC))
 AARCH64_CPU_NAME("cortex-a510", ARMV9A, FK_NEON_FP_ARMV8, false,
-                 (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2BITPERM |
+                 (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB |
                   AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS |
-                  AArch64::AEK_SB | AArch64::AEK_FP16FML))
+                  AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
+                  AArch64::AEK_FP16FML))
 AARCH64_CPU_NAME("cortex-a57", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
                  (AArch64::AEK_CRC))
 AARCH64_CPU_NAME("cortex-a65", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
@@ -184,8 +185,9 @@
                   AArch64::AEK_SSBS))
 AARCH64_CPU_NAME("cortex-x2", ARMV9A, FK_NEON_FP_ARMV8, false,
                  (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM |
-                  AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SVE2BITPERM |
-                  AArch64::AEK_SB | AArch64::AEK_FP16FML))
+                  AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB |
+                  AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
+                  AArch64::AEK_FP16FML))
 AARCH64_CPU_NAME("neoverse-e1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
                  (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_RAS |
                   AArch64::AEK_RCPC | AArch64::AEK_SSBS))
Index: clang/test/Driver/aarch64-implied-sve-features.c
===================================================================
--- /dev/null
+++ clang/test/Driver/aarch64-implied-sve-features.c
@@ -0,0 +1,65 @@
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve %s -### |& FileCheck %s --check-prefix=SVE-ONLY
+// SVE-ONLY: "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosve %s -### |& FileCheck %s --check-prefix=NOSVE
+// NOSVE: "-target-feature" "-sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve+nosve %s -### |& 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 -### |& FileCheck %s --check-prefix=SVE2-IMPLY
+// SVE2-IMPLY: "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2+nosve2 %s -### |& FileCheck %s --check-prefix=SVE2-REVERT
+// SVE2-REVERT-NOT: "-target-feature" "+sve"
+// SVE2-REVERT-NOT: "-target-feature" "-sve"
+// SVE2-REVERT: "-target-feature" "-sve2"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2+nosve %s -### |& 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"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve+sve2 %s -### |& FileCheck %s --check-prefix=SVE-SVE2
+// SVE-SVE2: "-target-feature" "+sve" "-target-feature" "+sve2"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm %s -### |& FileCheck %s --check-prefix=SVE2-BITPERM
+// SVE2-BITPERM: "-target-feature" "+sve2-bitperm" "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+nosve2-bitperm %s -### |& 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"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-bitperm %s -### |& FileCheck %s --check-prefix=SVE2-BITPERM-REVERT
+// SVE2-BITPERM-REVERT-NOT: "-target-feature" "+sve2-bitperm"
+// SVE2-BITPERM-REVERT-NOT: "-target-feature" "+sve2"
+// SVE2-BITPERM-REVERT-NOT: "-target-feature" "+sve"
+// SVE2-BITPERM-REVERT: "-target-feature" "-sve2-bitperm"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-sha3 %s -### |& FileCheck %s --check-prefix=SVE2-SHA3
+// SVE2-SHA3: "-target-feature" "+sve2-sha3" "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-aes %s -### |& FileCheck %s --check-prefix=SVE2-AES
+// SVE2-AES: "-target-feature" "+sve2-aes" "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-sm4 %s -### |& FileCheck %s --check-prefix=SVE2-SM4
+// SVE2-SM4: "-target-feature" "+sve2-sm4" "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-aes %s -### |& FileCheck %s --check-prefix=SVE2-SUBFEATURE-MIX
+// SVE2-SUBFEATURE-MIX: "-target-feature" "+sve2-bitperm" "-target-feature" "-sve2-aes" "-target-feature" "+sve2" "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2 %s -### |& FileCheck %s --check-prefix=SVE2-SUBFEATURE-CONFLICT
+// SVE2-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve2-sm4"
+// SVE2-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve2"
+// SVE2-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a+sve2-aes+nosve %s -### |& FileCheck %s --check-prefix=SVE-SUBFEATURE-CONFLICT
+// SVE-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve2-aes"
+// SVE-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve2"
+// SVE-SUBFEATURE-CONFLICT-NOT: "-target-feature" "+sve"
+
+// RUN: %clang -target aarch64-linux-gnu -mcpu=neoverse-n2+nosve2 %s -### |& FileCheck %s --check-prefix=SVE-MCPU-FEATURES
+// SVE-MCPU-FEATURES-NOT: "-target-feature" "+sve2-bitperm"
+// SVE-MCPU-FEATURES-NOT: "-target-feature" "+sve2"
+// SVE-MCPU-FEATURES: "-target-feature" "+sve"
Index: clang/test/Driver/aarch64-cpus.c
===================================================================
--- clang/test/Driver/aarch64-cpus.c
+++ clang/test/Driver/aarch64-cpus.c
@@ -800,7 +800,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" "+sve2"
+// GENERICV9A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // SVE2 is enabled by default on Armv9-A but it can be disabled
 // RUN: %clang -target aarch64 -march=armv9a+nosve2 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV9A-NOSVE2 %s
@@ -809,7 +809,7 @@
 // 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" "-sve2"
+// GENERICV9A-NOSVE2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-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
@@ -817,7 +817,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" "+sve2"
+// GENERICV9A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang -target aarch64 -march=armv9.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A %s
 // RUN: %clang -target aarch64 -march=armv9.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV91A %s
@@ -825,7 +825,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" "+sve2"
+// GENERICV91A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.1a" "-target-feature" "+i8mm" "-target-feature" "+bf16" "-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
@@ -833,7 +833,7 @@
 // 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" "+sve2"
+// GENERICV91A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.1a" "-target-feature" "+i8mm" "-target-feature" "+bf16" "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // RUN: %clang -target aarch64 -march=armv9.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A %s
 // RUN: %clang -target aarch64 -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A %s
@@ -841,7 +841,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" "+sve2"
+// GENERICV92A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.2a" "-target-feature" "+i8mm" "-target-feature" "+bf16" "-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
@@ -849,7 +849,7 @@
 // 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" "+sve2"
+// GENERICV92A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.2a" "-target-feature" "+i8mm" "-target-feature" "+bf16" "-target-feature" "+sve" "-target-feature" "+sve2"
 
 // fullfp16 is off by default for v8a, feature must not be mentioned
 // RUN: %clang -target aarch64 -march=armv8a  -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERIC %s
Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -63,12 +63,39 @@
   return "generic";
 }
 
+enum class OptState { Unset, True, False };
+bool isUnset(OptState State) { return State == OptState::Unset; }
+bool isTrue(OptState State) { return State == OptState::True; }
+bool isFalse(OptState State) { return State == OptState::False; }
+
 // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
 static bool DecodeAArch64Features(const Driver &D, StringRef text,
                                   std::vector<StringRef> &Features,
                                   llvm::AArch64::ArchKind ArchKind) {
   SmallVector<StringRef, 8> Split;
   text.split(Split, StringRef("+"), -1, false);
+  OptState SVE = OptState::Unset;
+  OptState SVE2 = OptState::Unset;
+  OptState SVE2Bit = OptState::Unset;
+  OptState SVE2SHA3 = OptState::Unset;
+  OptState SVE2AES = OptState::Unset;
+  OptState SVE2SM4 = OptState::Unset;
+
+  // Parse existing CPU features to setup initial state
+  for (auto Feature : Features) {
+    if (Feature == "+sve")
+      SVE = OptState::True;
+    else if (Feature == "+sve2")
+      SVE2 = OptState::True;
+    else if (Feature == "+sve2-bitperm")
+      SVE2Bit = OptState::True;
+    else if (Feature == "+sve2-sha3")
+      SVE2SHA3 = OptState::True;
+    else if (Feature == "+sve2-aes")
+      SVE2AES = OptState::True;
+    else if (Feature == "+sve2-sm4")
+      SVE2SM4 = OptState::True;
+  }
 
   for (StringRef Feature : Split) {
     StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
@@ -79,6 +106,31 @@
     else
       return false;
 
+    if (Feature == "sve")
+      SVE = OptState::True;
+    else if (Feature == "nosve")
+      SVE = OptState::False;
+    else if (Feature == "sve2")
+      SVE2 = OptState::True;
+    else if (Feature == "nosve2")
+      SVE2 = OptState::False;
+    else if (Feature == "sve2-bitperm")
+      SVE2Bit = OptState::True;
+    else if (Feature == "nosve2-bitperm")
+      SVE2Bit = OptState::False;
+    else if (Feature == "sve2-sha3")
+      SVE2SHA3 = OptState::True;
+    else if (Feature == "nosve2-sha3")
+      SVE2SHA3 = OptState::False;
+    else if (Feature == "sve2-aes")
+      SVE2AES = OptState::True;
+    else if (Feature == "nosve2-aes")
+      SVE2AES = OptState::False;
+    else if (Feature == "sve2-sm4")
+      SVE2SM4 = OptState::True;
+    else if (Feature == "nosve2-sm4")
+      SVE2SM4 = OptState::False;
+
     // +sve implies +f32mm if the base architecture is v8.6A, v8.7A, v9.1A or
     // v9.2A. It isn't the case in general that sve implies both f64mm and f32mm
     if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A ||
@@ -88,6 +140,40 @@
         Feature == "sve")
       Features.push_back("+f32mm");
   }
+
+  // Check for conflicts where a user has requested an SVE feature but
+  // explicitly blocked a feature that the first one depends on. If we find one,
+  // then disable all the dependent features.
+  if (isFalse(SVE) && (isTrue(SVE2) || isTrue(SVE2Bit) || isTrue(SVE2SHA3) ||
+                       isTrue(SVE2AES) || isTrue(SVE2SM4))) {
+    Features.push_back("-sve2");
+    Features.push_back("-sve2-bitperm");
+    Features.push_back("-sve2-sha3");
+    Features.push_back("-sve2-aes");
+    Features.push_back("-sve2-sm4");
+    return true;
+  }
+
+  if (isFalse(SVE2) && (isTrue(SVE2Bit) || isTrue(SVE2SHA3) ||
+                        isTrue(SVE2AES) || isTrue(SVE2SM4))) {
+    Features.push_back("-sve2-bitperm");
+    Features.push_back("-sve2-sha3");
+    Features.push_back("-sve2-aes");
+    Features.push_back("-sve2-sm4");
+    return true;
+  }
+
+  // Handle sve implied features; if the user requested a later feature
+  // without specifying the base feature(s), then add the base feature(s).
+  if (isUnset(SVE2) && (isTrue(SVE2Bit) || isTrue(SVE2SHA3) ||
+                        isTrue(SVE2AES) || isTrue(SVE2SM4))) {
+    SVE2 = OptState::True;
+    Features.push_back("+sve2");
+  }
+
+  if (isTrue(SVE2) && isUnset(SVE))
+    Features.push_back("+sve");
+
   return true;
 }
 
@@ -130,8 +216,20 @@
 
   llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first);
   if (ArchKind == llvm::AArch64::ArchKind::INVALID ||
-      !llvm::AArch64::getArchFeatures(ArchKind, Features) ||
-      (Split.second.size() &&
+      !llvm::AArch64::getArchFeatures(ArchKind, Features))
+    return false;
+
+  // 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 ((ArchKind == llvm::AArch64::ArchKind::ARMV9A ||
+       ArchKind == llvm::AArch64::ArchKind::ARMV9_1A ||
+       ArchKind == llvm::AArch64::ArchKind::ARMV9_2A)) {
+    Features.push_back("+sve");
+    Features.push_back("+sve2");
+  }
+
+  if ((Split.second.size() &&
        !DecodeAArch64Features(D, Split.second, Features, ArchKind)))
     return false;
 
@@ -419,14 +517,6 @@
   if (Pos != std::end(Features))
     Pos = Features.insert(std::next(Pos), {"+i8mm", "+bf16"});
 
-  // Enable SVE2 by default on Armv9-A.
-  // It can still be disabled if +nosve2 is present.
-  const char *SVE2Archs[] = {"+v9a", "+v9.1a", "+v9.2a"};
-  Pos = std::find_first_of(Features.begin(), Features.end(),
-                           std::begin(SVE2Archs), std::end(SVE2Archs));
-  if (Pos != Features.end())
-    Features.insert(++Pos, "+sve2");
-
   if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
                                options::OPT_munaligned_access)) {
     if (A->getOption().matches(options::OPT_mno_unaligned_access))
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to