Skip to content

Conversation

davemgreen
Copy link
Collaborator

It can be useful for debugging and tuning to be able to alter the VScaleForTuning. This adds a quick option to the vectorizer for it. It overrides the VScaleForTuning in the vectorizer even when the vscale is known, as the options is a "force".

@llvmbot
Copy link
Member

llvmbot commented Sep 4, 2025

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-transforms

Author: David Green (davemgreen)

Changes

It can be useful for debugging and tuning to be able to alter the VScaleForTuning. This adds a quick option to the vectorizer for it. It overrides the VScaleForTuning in the vectorizer even when the vscale is known, as the options is a "force".


Full diff: https://github.com/llvm/llvm-project/pull/156916.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+9)
  • (modified) llvm/test/Transforms/LoopVectorize/AArch64/scalable-vectorization-cost-tuning.ll (+4)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 3fbeef1211954..bf84a571e679e 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -303,6 +303,10 @@ static cl::opt<bool> ForceTargetSupportsScalableVectors(
         "Pretend that scalable vectors are supported, even if the target does "
         "not support them. This flag should only be used for testing."));
 
+static cl::opt<unsigned>
+    VScaleForTuningOpt("force-vscale-for-tuning", cl::Hidden,
+                       cl::desc("Force a vscale for tuning factor in the loop vectorizer"));
+
 static cl::opt<unsigned> SmallLoopCost(
     "small-loop-cost", cl::init(20), cl::Hidden,
     cl::desc(
@@ -1473,6 +1477,11 @@ class LoopVectorizationCostModel {
   /// vscale_range.min == vscale_range.max then return vscale_range.max, else
   /// return the value returned by the corresponding TTI method.
   void initializeVScaleForTuning() {
+    if (VScaleForTuningOpt.getNumOccurrences()) {
+      VScaleForTuning = VScaleForTuningOpt;
+      return;
+    }
+
     const Function *Fn = TheLoop->getHeader()->getParent();
     if (Fn->hasFnAttribute(Attribute::VScaleRange)) {
       auto Attr = Fn->getFnAttribute(Attribute::VScaleRange);
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/scalable-vectorization-cost-tuning.ll b/llvm/test/Transforms/LoopVectorize/AArch64/scalable-vectorization-cost-tuning.ll
index c4aee69db70b3..16d3786681ffa 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/scalable-vectorization-cost-tuning.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/scalable-vectorization-cost-tuning.ll
@@ -7,6 +7,10 @@
 ; RUN:     -force-target-instruction-cost=1 -passes=loop-vectorize -S -debug-only=loop-vectorize --disable-output < %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefixes=VSCALEFORTUNING1
 
+; RUN: opt -mtriple=aarch64 -mattr=+sve -mcpu=generic -force-vscale-for-tuning=2 \
+; RUN:     -force-target-instruction-cost=1 -passes=loop-vectorize -S -debug-only=loop-vectorize --disable-output < %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefixes=VSCALEFORTUNING2
+
 ; RUN: opt -mtriple=aarch64 -mcpu=neoverse-v1 \
 ; RUN:     -force-target-instruction-cost=1 -passes=loop-vectorize -S -debug-only=loop-vectorize --disable-output < %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefixes=VSCALEFORTUNING2

Copy link

github-actions bot commented Sep 4, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

It can be useful for debugging and tuning to be able to alter the
VScaleForTuning. This adds a quick option to the vectorizer for it
@davemgreen davemgreen force-pushed the gh-lv-vscalefortuningopt branch from bc701eb to 23ced2e Compare September 4, 2025 15:53
@@ -1473,6 +1477,11 @@ class LoopVectorizationCostModel {
/// vscale_range.min == vscale_range.max then return vscale_range.max, else
/// return the value returned by the corresponding TTI method.
void initializeVScaleForTuning() {
if (VScaleForTuningOpt.getNumOccurrences()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I like the idea of having a flag to force the choice of vscale, but should this be sanitised according to vscale_range on the function or at least emit a warning that it's architecturally unsupported? For example, if the function has the vscale_range(1, 16) attribute then only power-of-2 vscale values are permitted leading to choices of 1,2,4,8 or 16.

Comment on lines +1480 to +1483
if (VScaleForTuningOpt.getNumOccurrences()) {
VScaleForTuning = VScaleForTuningOpt;
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the purpose of the option to deliberately override the function attribute?

Does this have to be LV specific? Could this be handled in getVScaleForTuning?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants