[llvm-branch-commits] [llvm] [FileCheck] Add --filter-label to drop CHECKs outside selected CHECK-LABEL sections (PR #200618)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat May 30 18:33:24 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-testing-tools
Author: jofrn
<details>
<summary>Changes</summary>
[FileCheck] Add --filter-label to drop CHECKs outside selected CHECK-LABEL sections
---
Full diff: https://github.com/llvm/llvm-project/pull/200618.diff
5 Files Affected:
- (modified) llvm/include/llvm/FileCheck/FileCheck.h (+5)
- (modified) llvm/lib/FileCheck/FileCheck.cpp (+24)
- (modified) llvm/lib/FileCheck/FileCheckImpl.h (+5)
- (added) llvm/test/FileCheck/filter-label.txt (+51)
- (modified) llvm/utils/FileCheck/FileCheck.cpp (+14)
``````````diff
diff --git a/llvm/include/llvm/FileCheck/FileCheck.h b/llvm/include/llvm/FileCheck/FileCheck.h
index b000f5b0dac73..fbca647672e9e 100644
--- a/llvm/include/llvm/FileCheck/FileCheck.h
+++ b/llvm/include/llvm/FileCheck/FileCheck.h
@@ -13,6 +13,7 @@
#ifndef LLVM_FILECHECK_FILECHECK_H
#define LLVM_FILECHECK_FILECHECK_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -502,6 +503,10 @@ class FileCheck {
LLVM_ABI StringRef CanonicalizeFile(MemoryBuffer &MB,
SmallVectorImpl<char> &OutputBuffer);
+ /// Drops CHECKs whose CHECK-LABEL section's literal text doesn't match any
+ /// of \p Names. CHECKs before the first label are dropped. Nop if empty.
+ LLVM_ABI void filterByLabel(ArrayRef<StringRef> Names);
+
/// Checks the input to FileCheck provided in the \p Buffer against the
/// expected strings read from the check file and record diagnostics emitted
/// in \p Diags. Errors are recorded against \p SM.
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index ae25a078713e7..6a4f9c5a8343b 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -2531,6 +2531,30 @@ static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes,
return true;
}
+void FileCheck::filterByLabel(ArrayRef<StringRef> Names) {
+ if (Names.empty())
+ return;
+
+ // (name1|name2|...) bracketed by non-chars (or string ends).
+ std::string Alts;
+ for (StringRef Name : Names) {
+ if (!Alts.empty())
+ Alts += '|';
+ Alts += Regex::escape(Name);
+ }
+ Regex Re("(^|[^[:alnum:]_])(" + Alts + ")([^[:alnum:]_]|$)");
+
+ std::vector<FileCheckString> Filtered;
+ bool Keeping = false;
+ for (auto &CS : CheckStrings) {
+ if (CS.Pat.getCheckTy() == Check::CheckLabel)
+ Keeping = Re.match(CS.Pat.getFixedStr());
+ if (Keeping)
+ Filtered.push_back(std::move(CS));
+ }
+ CheckStrings = std::move(Filtered);
+}
+
bool FileCheck::ValidateCheckPrefixes() {
StringSet<> UniquePrefixes;
// Add default prefixes to catch user-supplied duplicates of them below.
diff --git a/llvm/lib/FileCheck/FileCheckImpl.h b/llvm/lib/FileCheck/FileCheckImpl.h
index 5393650020a30..b156daaf40ab1 100644
--- a/llvm/lib/FileCheck/FileCheckImpl.h
+++ b/llvm/lib/FileCheck/FileCheckImpl.h
@@ -745,6 +745,11 @@ class Pattern {
Check::FileCheckType getCheckTy() const { return CheckTy; }
+ /// \returns the literal pattern text, or an empty StringRef if the pattern
+ /// requires a regex match. Used by FileCheck::filterByLabel to identify
+ /// CHECK-LABEL sections by their literal text.
+ StringRef getFixedStr() const { return FixedStr; }
+
int getCount() const { return CheckTy.getCount(); }
private:
diff --git a/llvm/test/FileCheck/filter-label.txt b/llvm/test/FileCheck/filter-label.txt
new file mode 100644
index 0000000000000..db5d5e3df3671
--- /dev/null
+++ b/llvm/test/FileCheck/filter-label.txt
@@ -0,0 +1,51 @@
+; Verify --filter-label drops CHECKs whose CHECK-LABEL section's literal text
+; doesn't match any of the given names.
+
+; RUN: FileCheck --filter-label=foo -input-file %s %s -check-prefix=ALL
+; RUN: FileCheck --filter-label=bar -input-file %s %s -check-prefix=ALL
+; RUN: FileCheck --filter-label=foo,bar -input-file %s %s -check-prefix=ALL
+; RUN: FileCheck --filter-label=bar,foo -input-file %s %s -check-prefix=ALL
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck --filter-label=foobar -input-file %s %s -check-prefix=ALL 2>&1 \
+; RUN: | FileCheck %s -check-prefix=FAIL-ERR
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -input-file %s %s -check-prefix=ALL 2>&1 \
+; RUN: | FileCheck %s -check-prefix=FAIL-ERR
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck --filter-label=baz -input-file %s %s -check-prefix=BAZ 2>&1 \
+; RUN: | FileCheck %s -check-prefix=FAIL-ERR
+
+
+ at foo:
+a
+b
+
+ at bar:
+c
+d
+
+ at foobar:
+e
+f
+
+ at baz:
+g
+h
+
+; ALL-LABEL: @foo:
+; ALL: {{^}}a
+; ALL: {{^}}b
+; ALL-LABEL: @bar:
+; ALL: {{^}}c
+; ALL: {{^}}d
+; ALL-LABEL: @foobar:
+; ALL: {{^}}e
+; ALL: {{^}}MISMATCH
+; BAZ-LABEL: @baz:
+; BAZ: {{^}}g
+; BAZ: {{^}}i
+
+; FAIL-ERR: expected string not found in input
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 63b745469b8ee..82c71b0975534 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -143,6 +143,14 @@ enum DumpInputFilterValue {
DumpInputFilterAll
};
+static cl::list<std::string> FilterLabel(
+ "filter-label", cl::CommaSeparated,
+ cl::desc("Drop CHECKs whose enclosing CHECK-LABEL section's literal text\n"
+ "doesn't word-match any of the given labels. CHECKs before the\n"
+ "first label are dropped. Useful for narrowing checks to a subset\n"
+ "of functions."),
+ cl::value_desc("name"));
+
static cl::list<DumpInputFilterValue> DumpInputFilters(
"dump-input-filter",
cl::desc("In the dump requested by -dump-input, print only input lines of\n"
@@ -868,6 +876,12 @@ int main(int argc, char **argv) {
if (FC.readCheckFile(SM, CheckFileText, &ImpPatBufferIDRange))
return 2;
+ if (!FilterLabel.empty()) {
+ SmallVector<StringRef, 4> FilterLabelRefs(FilterLabel.begin(),
+ FilterLabel.end());
+ FC.filterByLabel(FilterLabelRefs);
+ }
+
// Open the file to check and add it to SourceMgr.
ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);
``````````
</details>
https://github.com/llvm/llvm-project/pull/200618
More information about the llvm-branch-commits
mailing list