[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