[llvm] [VPlan] Unify inner and outer loop paths (NFCI). (PR #192868)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 03:36:14 PDT 2026


================
@@ -2972,8 +2972,60 @@ void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
   Uniforms[VF].insert_range(Worklist);
 }
 
+// This function will select a scalable VF if the target supports scalable
+// vectors and a fixed one otherwise.
+// TODO: we could return a pair of values that specify the max VF and
+// min VF, to be used in `buildVPlans(MinVF, MaxVF)` instead of
+// `buildVPlans(VF, VF)`. We cannot do it because VPLAN at the moment
+// doesn't have a cost model that can choose which plan to execute if
+// more than one is generated.
+static ElementCount determineVPlanVF(const TargetTransformInfo &TTI,
+                                     VFSelectionContext &Config) {
+  auto [_, WidestType] = Config.getSmallestAndWidestTypes();
+
+  auto RegKind = TTI.enableScalableVectorization()
+                     ? TargetTransformInfo::RGK_ScalableVector
+                     : TargetTransformInfo::RGK_FixedWidthVector;
+
+  TypeSize RegSize = TTI.getRegisterBitWidth(RegKind);
+  unsigned N = RegSize.getKnownMinValue() / WidestType;
+  return ElementCount::get(N, RegSize.isScalable());
+}
+
 FixedScalableVFPair
 LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
+  // For outer loops, use simple type-based heuristic VF. No cost model or
+  // memory dependence analysis is available.
+  if (!TheLoop->isInnermost()) {
+    ElementCount VF = UserVF;
+    if (VF.isZero()) {
+      VF = determineVPlanVF(TTI, Config);
+      LLVM_DEBUG(dbgs() << "LV: VPlan computed VF " << VF << ".\n");
+
+      // Make sure we have a VF > 1 for stress testing.
+      if (VPlanBuildStressTest && VF.isScalar()) {
+        LLVM_DEBUG(dbgs() << "LV: VPlan stress testing: "
+                          << "overriding computed VF.\n");
+        VF = ElementCount::getFixed(4);
+      }
+    } else if (VF.isScalable() && !Config.supportsScalableVectors()) {
+      reportVectorizationFailure(
+          "Scalable vectorization requested but not supported by the target",
+          "the scalable user-specified vectorization width for outer-loop "
+          "vectorization cannot be used because the target does not support "
+          "scalable vectors.",
+          "ScalableVFUnfeasible", ORE, TheLoop);
+      return FixedScalableVFPair::getNone();
+    }
+    assert(isPowerOf2_32(VF.getKnownMinValue()) &&
+           "VF needs to be a power of two");
+    if (VF.isScalar())
+      return FixedScalableVFPair::getNone();
+    LLVM_DEBUG(dbgs() << "LV: Using " << (!UserVF.isZero() ? "user " : "")
+                      << "VF " << VF << " to build VPlans.\n");
+    return FixedScalableVFPair(VF);
----------------
fhahn wrote:

Done, also moved to VFSelectionContext, thanks

https://github.com/llvm/llvm-project/pull/192868


More information about the llvm-commits mailing list