[llvm] [VPlan] Add `-vplan-print-after=<>` option (PR #178700)

Andrei Elovikov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 29 09:15:17 PST 2026


https://github.com/eas created https://github.com/llvm/llvm-project/pull/178700

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.

>From 467c6217f64197bee69248e95c9cf3c357a9a411 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Thu, 29 Jan 2026 09:10:10 -0800
Subject: [PATCH 1/2] Build fixes from
 https://github.com/llvm/llvm-project/pull/178547

---
 llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 2 ++
 llvm/lib/Transforms/Vectorize/VPlanTransforms.h | 7 ++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 4e056ab30e2a6..9f23e09eba2ca 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -366,9 +366,11 @@ cl::opt<bool>
                           cl::Hidden,
                           cl::desc("Verfiy VPlans after VPlan transforms."));
 
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 cl::opt<bool> llvm::PrintAfterEachVPlanPass(
     "vplan-print-after-all", cl::init(false), cl::Hidden,
     cl::desc("Print after each VPlanTransforms::runPass."));
+#endif
 
 // This flag enables the stress testing of the VPlan H-CFG construction in the
 // VPlan-native vectorization path. It must be used in conjuction with
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index 451597afa73da..f33c672e9ea59 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -34,9 +34,12 @@ class VPRecipeBuilder;
 struct VFRange;
 
 LLVM_ABI_FOR_TEST extern cl::opt<bool> VerifyEachVPlan;
-LLVM_ABI_FOR_TEST extern cl::opt<bool> PrintAfterEachVPlanPass;
 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;
+#endif
+
 struct VPlanTransforms {
   /// Helper to run a VPlan pass \p Pass on \p VPlan, forwarding extra arguments
   /// to the pass. Performs verification/printing after each VPlan pass if
@@ -45,12 +48,14 @@ struct VPlanTransforms {
   static decltype(auto) runPass(StringRef PassName, PassTy &&Pass, VPlan &Plan,
                                 ArgsTy &&...Args) {
     scope_exit PostTransformActions{[&]() {
+#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) {
         dbgs() << "VPlan after " << PassName << '\n';
         dbgs() << Plan << '\n';
       }
+#endif
       if (VerifyEachVPlan && EnableVerify)
         verifyVPlanIsValid(Plan);
     }};

>From 1e7b6ef99ddd17a58626649f3bebdf7f46ddafd9 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 2/2] [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 9f23e09eba2ca..7c37ee419f79e 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 f33c672e9ea59..617d4f14a54aa 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -38,6 +38,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 {
@@ -51,7 +52,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
+}



More information about the llvm-commits mailing list