[llvm] [LV][NFC] Add option to control debug printing of cost per lane (PR #201824)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 5 05:20:25 PDT 2026
https://github.com/david-arm created https://github.com/llvm/llvm-project/pull/201824
At the moment it's difficult to auto-generate CHECK lines for cost model output because the floating point value printed out along with "Estimated cost per lane" is fragile and can vary from target to target. See PR #201580 for an example of this. Also, I would like to start using auto-generation of cost model CHECK lines more often in tests to make life easier for developers to update them. See PR #201560 as a motivating example.
This PR introduces a new debug-only flag called
-print-cost-per-lane
which is true by default, since it still remains useful for day-to-day debugging as part of developer workflow. However, when writing tests this flag can be set to false to aid test creation and maintenance.
>From a1ee8820a8b44d9a812421c83e0296c2d551ff56 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Fri, 5 Jun 2026 12:17:14 +0000
Subject: [PATCH] [LV][NFC] Add option to control debug printing of cost per
lane
At the moment it's difficult to auto-generate CHECK lines for
cost model output because the floating point value printed
out along with "Estimated cost per lane" is fragile and can
vary from target to target. See PR #201580 for an example of
this. Also, I would like to start using auto-generation of
cost model CHECK lines more often in tests to make life
easier for developers to update them. See PR #201560 as a
motivating example.
This PR introduces a new debug-only flag called
-print-cost-per-lane
which is true by default, since it still remains useful for
day-to-day debugging as part of developer workflow. However,
when writing tests this flag can be set to false to aid test
creation and maintenance.
---
.../Transforms/Vectorize/LoopVectorize.cpp | 26 +++++++++++++------
.../force-scalable-vectorization-always.ll | 19 +++++++-------
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index fcfe11b6e9de6..3faaa4d190005 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -375,6 +375,13 @@ cl::opt<bool> llvm::VPlanPrintVectorRegionScope(
"`-vplan-print-after*` if the plan has one."));
#endif
+#if !defined(NDEBUG)
+static cl::opt<bool> PrintCostPerLane(
+ "print-cost-per-lane", cl::init(true), cl::Hidden,
+ cl::desc("If the flag is set print out debug information containing the "
+ "cost per lane for each VF."));
+#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
// -enable-vplan-native-path. -vplan-verify-hcfg can also be used to enable the
@@ -5765,14 +5772,17 @@ InstructionCost LoopVectorizationPlanner::cost(VPlan &Plan, ElementCount VF,
#ifndef NDEBUG
unsigned EstimatedWidth =
estimateElementCount(VF, Config.getVScaleForTuning());
- LLVM_DEBUG(dbgs() << "Cost for VF " << VF << ": " << Cost
- << " (Estimated cost per lane: ");
- if (Cost.isValid()) {
- double CostPerLane = double(Cost.getValue()) / EstimatedWidth;
- LLVM_DEBUG(dbgs() << format("%.1f", CostPerLane));
- } else /* No point dividing an invalid cost - it will still be invalid */
- LLVM_DEBUG(dbgs() << "Invalid");
- LLVM_DEBUG(dbgs() << ")\n");
+ LLVM_DEBUG(dbgs() << "Cost for VF " << VF << ": " << Cost);
+ if (PrintCostPerLane) {
+ LLVM_DEBUG(dbgs() << " (Estimated cost per lane: ");
+ if (Cost.isValid()) {
+ double CostPerLane = double(Cost.getValue()) / EstimatedWidth;
+ LLVM_DEBUG(dbgs() << format("%.1f", CostPerLane));
+ } else /* No point dividing an invalid cost - it will still be invalid */
+ LLVM_DEBUG(dbgs() << "Invalid");
+ LLVM_DEBUG(dbgs() << ")\n");
+ } else
+ LLVM_DEBUG(dbgs() << "\n");
#endif
return Cost;
}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/force-scalable-vectorization-always.ll b/llvm/test/Transforms/LoopVectorize/AArch64/force-scalable-vectorization-always.ll
index d3b1520cb8d25..b8f578f62a851 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/force-scalable-vectorization-always.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/force-scalable-vectorization-always.ll
@@ -1,4 +1,5 @@
-; RUN: opt -passes=loop-vectorize -enable-epilogue-vectorization=false -mattr=disable-maximize-scalable-bandwidth -scalable-vectorization=always -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost for VF" --filter "LV: Selecting VF" --filter "VPlan 'Final VPlan for VF" --version 6
+; RUN: opt -passes=loop-vectorize -enable-epilogue-vectorization=false -print-cost-per-lane=false -mattr=disable-maximize-scalable-bandwidth -scalable-vectorization=always -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck %s
; REQUIRES: asserts
target triple = "aarch64"
@@ -7,12 +8,12 @@ target triple = "aarch64"
; but that a scalable VF is still chosen (due to the `-scalable-vectorization=always` flag)
define i32 @cost_prefers_fixed_width_vf_but_force_scalable_vf(ptr noalias %dst, ptr noalias %src, i64 %n) "target-cpu"="neoverse-n2" {
; CHECK-LABEL: 'cost_prefers_fixed_width_vf_but_force_scalable_vf'
-; CHECK: Cost for VF 2: 12 (Estimated cost per lane: 6.
-; CHECK: Cost for VF 4: 8 (Estimated cost per lane: 2.
-; CHECK: Cost for VF 8: 10 (Estimated cost per lane: 1.
-; CHECK: Cost for VF vscale x 1: Invalid (Estimated cost per lane: Invalid)
-; CHECK: Cost for VF vscale x 2: 9 (Estimated cost per lane: 4.
-; CHECK: Cost for VF vscale x 4: 8 (Estimated cost per lane: 2.
+; CHECK: Cost for VF 2: 12
+; CHECK: Cost for VF 4: 8
+; CHECK: Cost for VF 8: 10
+; CHECK: Cost for VF vscale x 1: Invalid
+; CHECK: Cost for VF vscale x 2: 9
+; CHECK: Cost for VF vscale x 4: 8
; CHECK: LV: Selecting VF: vscale x 4.
; CHECK: VPlan 'Final VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={2}' {
;
@@ -39,8 +40,8 @@ exit:
; if we can't vectorize with SVE (in this case, because SVE is unavailable)
define i32 @no_sve_fallback_to_neon(ptr %src, i64 %n) "target-features"="+neon" {
; CHECK-LABEL: 'no_sve_fallback_to_neon'
-; CHECK: Cost for VF 2: 4 (Estimated cost per lane: 2.
-; CHECK: Cost for VF 4: 4 (Estimated cost per lane: 1.
+; CHECK: Cost for VF 2: 4
+; CHECK: Cost for VF 4: 4
; CHECK: LV: Selecting VF: 4.
; CHECK: VPlan 'Final VPlan for VF={2,4},UF={2}' {
;
More information about the llvm-commits
mailing list