[llvm] [VPlan] Add `-vplan-print-after=` option (PR #178700)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 10 07:31:57 PST 2026
https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/178700
>From 7dcf2f64c8ccc92c227bdf63c3cea5d40b3049c2 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Tue, 27 Jan 2026 16:19:36 -0800
Subject: [PATCH 1/3] [VPlan] Add `-vplan-print-after=<>` option
Builds on top of https://github.com/llvm/llvm-project/pull/178547.
Next step would be to add UpdateTestChecks support for
VPlan-output-based tests, to be done in a separate PR.
---
.../Transforms/Vectorize/LoopVectorize.cpp | 5 ++++
.../Transforms/Vectorize/VPlanTransforms.h | 7 ++++-
.../LoopVectorize/vplan-print-after.ll | 29 +++++++++++++++++++
3 files changed, 40 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/LoopVectorize/vplan-print-after.ll
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index db2c84d78fb15..f8cc72daf22ef 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -370,6 +370,11 @@ cl::opt<bool>
cl::opt<bool> llvm::PrintAfterEachVPlanPass(
"vplan-print-after-all", cl::init(false), cl::Hidden,
cl::desc("Print after each VPlanTransforms::runPass."));
+
+cl::list<std::string> llvm::PrintAfterVPlanPasses(
+ "vplan-print-after", cl::Hidden,
+ cl::desc("Print after specified VPlan transformations (substring match "
+ "suffices)."));
#endif
// This flag enables the stress testing of the VPlan H-CFG construction in the
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index 0ef521e057fc8..9ff85823b65e4 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -39,6 +39,7 @@ LLVM_ABI_FOR_TEST extern cl::opt<bool> EnableWideActiveLaneMask;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_ABI_FOR_TEST extern cl::opt<bool> PrintAfterEachVPlanPass;
+LLVM_ABI_FOR_TEST extern cl::list<std::string> PrintAfterVPlanPasses;
#endif
struct VPlanTransforms {
@@ -52,7 +53,11 @@ struct VPlanTransforms {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
// Make sure to print before verification, so that output is more useful
// in case of failures:
- if (PrintAfterEachVPlanPass) {
+ if (PrintAfterEachVPlanPass ||
+ (PrintAfterVPlanPasses.getNumOccurrences() > 0 &&
+ any_of(PrintAfterVPlanPasses, [PassName](StringRef Entry) {
+ return PassName.contains(Entry);
+ }))) {
dbgs() << "VPlan after " << PassName << '\n';
dbgs() << Plan << '\n';
}
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-print-after.ll b/llvm/test/Transforms/LoopVectorize/vplan-print-after.ll
new file mode 100644
index 0000000000000..8014a4e480d65
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/vplan-print-after.ll
@@ -0,0 +1,29 @@
+; RUN: opt -passes=loop-vectorize -disable-output -force-vector-width=4 < %s \
+; RUN: -vplan-print-after=simplify -vplan-print-after=printFinalVPlan \
+; RUN: 2>&1 | FileCheck %s --implicit-check-not "VPlan after"
+; REQUIRES: asserts
+
+; CHECK: VPlan after simplifyRecipes
+; CHECK-NEXT: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK: VPlan after simplifyBlends
+; CHECK-NEXT: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK: VPlan after simplifyRecipes
+; CHECK-NEXT: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK: VPlan after printFinalVPlan
+; CHECK-NEXT: VPlan 'Final VPlan for VF={4},UF={1}' {
+
+define void @foo(ptr %ptr, i64 %n) {
+entry:
+ br label %header
+
+header:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %header ]
+ %gep = getelementptr i64, ptr %ptr, i64 %iv
+ store i64 %iv, ptr %gep
+ %iv.next = add nsw i64 %iv, 1
+ %exitcond = icmp slt i64 %iv.next, %n
+ br i1 %exitcond, label %header, label %exit
+
+exit:
+ ret void
+}
>From d75ab8ff7ce292bcf899206aa94df681d44dd389 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 6 Feb 2026 12:19:09 -0800
Subject: [PATCH 2/3] Make `-vplan-print-after=<>` a regexp match (to handle
"optimize$")
---
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 3 +--
llvm/lib/Transforms/Vectorize/VPlanTransforms.h | 3 ++-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index f8cc72daf22ef..f6bd54675c1c4 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -373,8 +373,7 @@ cl::opt<bool> llvm::PrintAfterEachVPlanPass(
cl::list<std::string> llvm::PrintAfterVPlanPasses(
"vplan-print-after", cl::Hidden,
- cl::desc("Print after specified VPlan transformations (substring match "
- "suffices)."));
+ cl::desc("Print after specified VPlan transformations (regexp)."));
#endif
// This flag enables the stress testing of the VPlan H-CFG construction in the
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index 9ff85823b65e4..f3acc3a19bd9c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Regex.h"
namespace llvm {
@@ -56,7 +57,7 @@ struct VPlanTransforms {
if (PrintAfterEachVPlanPass ||
(PrintAfterVPlanPasses.getNumOccurrences() > 0 &&
any_of(PrintAfterVPlanPasses, [PassName](StringRef Entry) {
- return PassName.contains(Entry);
+ return Regex(Entry).match(PassName);
}))) {
dbgs() << "VPlan after " << PassName << '\n';
dbgs() << Plan << '\n';
>From bbb9cf6216eb5973b0fb6951a36c051e4ddfba82 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 9 Feb 2026 08:38:21 -0800
Subject: [PATCH 3/3] Rename options/update comments per code-review feedback
---
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 8 ++++----
llvm/lib/Transforms/Vectorize/VPlanTransforms.h | 10 +++++-----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index f6bd54675c1c4..8404249594ef4 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -367,13 +367,13 @@ cl::opt<bool>
cl::desc("Verfiy VPlans after VPlan transforms."));
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-cl::opt<bool> llvm::PrintAfterEachVPlanPass(
+cl::opt<bool> llvm::VPlanPrintAfterAll(
"vplan-print-after-all", cl::init(false), cl::Hidden,
- cl::desc("Print after each VPlanTransforms::runPass."));
+ cl::desc("Print VPlans after all VPlan transformations."));
-cl::list<std::string> llvm::PrintAfterVPlanPasses(
+cl::list<std::string> llvm::VPlanPrintAfterPasses(
"vplan-print-after", cl::Hidden,
- cl::desc("Print after specified VPlan transformations (regexp)."));
+ cl::desc("Print VPlans after specified VPlan transformations (regexp)."));
#endif
// This flag enables the stress testing of the VPlan H-CFG construction in the
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index f3acc3a19bd9c..e36a156b6f927 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -39,8 +39,8 @@ LLVM_ABI_FOR_TEST extern cl::opt<bool> VerifyEachVPlan;
LLVM_ABI_FOR_TEST extern cl::opt<bool> EnableWideActiveLaneMask;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_ABI_FOR_TEST extern cl::opt<bool> PrintAfterEachVPlanPass;
-LLVM_ABI_FOR_TEST extern cl::list<std::string> PrintAfterVPlanPasses;
+LLVM_ABI_FOR_TEST extern cl::opt<bool> VPlanPrintAfterAll;
+LLVM_ABI_FOR_TEST extern cl::list<std::string> VPlanPrintAfterPasses;
#endif
struct VPlanTransforms {
@@ -54,9 +54,9 @@ struct VPlanTransforms {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
// Make sure to print before verification, so that output is more useful
// in case of failures:
- if (PrintAfterEachVPlanPass ||
- (PrintAfterVPlanPasses.getNumOccurrences() > 0 &&
- any_of(PrintAfterVPlanPasses, [PassName](StringRef Entry) {
+ if (VPlanPrintAfterAll ||
+ (VPlanPrintAfterPasses.getNumOccurrences() > 0 &&
+ any_of(VPlanPrintAfterPasses, [PassName](StringRef Entry) {
return Regex(Entry).match(PassName);
}))) {
dbgs() << "VPlan after " << PassName << '\n';
More information about the llvm-commits
mailing list