[llvm] [llvm] Add format check for MCSubtargetFeatures (PR #180943)

Georgiy Samoylov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 06:25:14 PDT 2026


https://github.com/sga-sc updated https://github.com/llvm/llvm-project/pull/180943

>From 46cacc4b5414b069ffdee6121746d35740ffcd8d Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <Ignitor21838 at gmail.com>
Date: Wed, 11 Feb 2026 16:50:34 +0300
Subject: [PATCH 1/3] [MC] Add format check for MCSubtargetFeatures

---
 llvm/include/llvm/MC/TargetRegistry.h | 6 ++++++
 llvm/lib/MC/TargetRegistry.cpp        | 9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 4451dfa72a5f4..ae4774cbc045f 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -452,6 +452,8 @@ class Target {
                                          StringRef Features) const {
     if (!MCSubtargetInfoCtorFn)
       return nullptr;
+    if (!isValidFeatureListFormat(Features))
+      return nullptr;
     return MCSubtargetInfoCtorFn(TheTriple, CPU, Features);
   }
 
@@ -630,6 +632,10 @@ class Target {
     return nullptr;
   }
 
+  /// isValidFeatureListFormat - check that FeatureString
+  /// has valid format.
+  static bool isValidFeatureListFormat(StringRef FeaturesString);
+
   /// @}
 };
 
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 9263dda65a8b0..219359ae50d45 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -15,6 +15,7 @@
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCObjectStreamer.h"
 #include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/Regex.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <vector>
@@ -23,6 +24,14 @@ using namespace llvm;
 // Clients are responsible for avoid race conditions in registration.
 static Target *FirstTarget = nullptr;
 
+bool Target::isValidFeatureListFormat(StringRef Features) {
+  if (Features.empty())
+    return true;
+
+  static const llvm::Regex pattern("^([+-][^,]+)(,[+-][^,]+)*,?$");
+  return pattern.match(Features);
+}
+
 MCStreamer *Target::createMCObjectStreamer(
     const Triple &T, MCContext &Ctx, std::unique_ptr<MCAsmBackend> TAB,
     std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,

>From 7d809354a7ccb08b9f2d928081036999348519f3 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <Ignitor21838 at gmail.com>
Date: Wed, 25 Feb 2026 13:39:19 +0300
Subject: [PATCH 2/3] [MC][unittest] Add unit-test for feature list format

---
 llvm/unittests/MC/TargetRegistry.cpp | 45 ++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/llvm/unittests/MC/TargetRegistry.cpp b/llvm/unittests/MC/TargetRegistry.cpp
index cc464b7681ce1..4a41629f29b87 100644
--- a/llvm/unittests/MC/TargetRegistry.cpp
+++ b/llvm/unittests/MC/TargetRegistry.cpp
@@ -42,4 +42,49 @@ TEST(TargetRegistry, TargetHasArchType) {
   ASSERT_NE(Count, 0);
 }
 
+TEST(TargetRegistry, IsValidFeatureListFormat) {
+  // Valid strings
+
+  // Empty string is a valid feature string
+  EXPECT_TRUE(Target::isValidFeatureListFormat(""));
+
+  EXPECT_TRUE(Target::isValidFeatureListFormat("+some_feature"));
+  EXPECT_TRUE(Target::isValidFeatureListFormat("-some_feature"));
+  EXPECT_TRUE(
+      Target::isValidFeatureListFormat("+feature1,-feature2,+feature3"));
+  EXPECT_TRUE(Target::isValidFeatureListFormat("+123"));
+  EXPECT_TRUE(Target::isValidFeatureListFormat("-feature,"));
+  EXPECT_TRUE(
+      Target::isValidFeatureListFormat("-feature1,+feature2,+feature3,"));
+
+  // Invalid strings
+
+  // Feature don't start with '+' or '-'
+  EXPECT_FALSE(Target::isValidFeatureListFormat("invalid_string"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat("+good,bad"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat("bad,+good"));
+
+  // String has spaces
+  EXPECT_FALSE(Target::isValidFeatureListFormat(" "));
+  EXPECT_FALSE(Target::isValidFeatureListFormat(", "));
+  EXPECT_FALSE(Target::isValidFeatureListFormat(" avx"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat("+avx, -sse"));
+
+  // Redundant commas
+  EXPECT_FALSE(Target::isValidFeatureListFormat("+feature1,,+feature2"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat(",+feature"));
+  EXPECT_FALSE(
+      Target::isValidFeatureListFormat("+feature1,,,+feature2,,+feature3"));
+
+  // Feature consists only of '+' or '-'
+  EXPECT_FALSE(Target::isValidFeatureListFormat("+"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat("-"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat("+avx,-"));
+
+  // Only commas
+  EXPECT_FALSE(Target::isValidFeatureListFormat(","));
+  EXPECT_FALSE(Target::isValidFeatureListFormat(",,"));
+  EXPECT_FALSE(Target::isValidFeatureListFormat(",,,"));
+}
+
 } // end namespace

>From ef57c55d1547ff1a4133e5f5e53b7bd205a4af22 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <g.samoylov at syntacore.com>
Date: Thu, 5 Mar 2026 18:01:49 +0300
Subject: [PATCH 3/3] [lldb] Add more comments

---
 llvm/include/llvm/MC/TargetRegistry.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index ae4774cbc045f..a86b32f65e9ea 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -633,7 +633,17 @@ class Target {
   }
 
   /// isValidFeatureListFormat - check that FeatureString
-  /// has valid format.
+  /// has next format:
+  ///   "+attr1,+attr2,-attr3,...,+attrN"
+  /// A comma separates each feature from the next (all lowercase).
+  /// Each of the remaining features is prefixed with '+' or '-' indicating
+  /// whether that feature should be enabled or disabled contrary to the cpu
+  /// specification.
+  /// The string must match exactly that format otherwise
+  /// MCSubtargetInfo::ApplyFeatureFlag will fail.
+  /// For example feature string "+a,+m,c" is accepted, and results in feature
+  /// list {"+a", "+m", "c"}. Later in ApplyFeatureFlag, it asserts
+  /// that all features must start with '+' or '-' and assert is failed.
   static bool isValidFeatureListFormat(StringRef FeaturesString);
 
   /// @}



More information about the llvm-commits mailing list