[llvm] [LV] Move isCandidateForEpilogueVec to LoopVectorizationPlanner.cpp (NFC). (PR #195268)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 07:20:23 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

isCandidateForEpilogueVectorization (together with its file-static helper hasUnsupportedHeaderPhiRecipe) does not depend on anything in LoopVectorize.cpp, move it to LoopVectorizationPlanner.cpp.

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


2 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp (+59) 
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (-58) 


``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
index 98e4da75b04fe..1f9e08cada58f 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "LoopVectorizationPlanner.h"
+#include "VPlanUtils.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/Analysis/ScalarEvolution.h"
@@ -618,3 +619,61 @@ void VFSelectionContext::collectInLoopReductions() {
                       << " reduction for phi: " << *Phi << "\n");
   }
 }
+
+/// Returns true if the VPlan contains header phi recipes that are not currently
+/// supported for epilogue vectorization.
+static bool hasUnsupportedHeaderPhiRecipe(VPlan &Plan) {
+  return any_of(
+      Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis(),
+      [](VPRecipeBase &R) {
+        switch (R.getVPRecipeID()) {
+        case VPRecipeBase::VPFirstOrderRecurrencePHISC:
+          // TODO: Add support for fixed-order recurrences.
+          return true;
+        case VPRecipeBase::VPWidenIntOrFpInductionSC:
+          return !cast<VPWidenIntOrFpInductionRecipe>(&R)->getPHINode();
+        case VPRecipeBase::VPReductionPHISC: {
+          auto *RedPhi = cast<VPReductionPHIRecipe>(&R);
+          // TODO: Support FMinNum/FMaxNum, FindLast reductions, and reductions
+          // without underlying values.
+          RecurKind Kind = RedPhi->getRecurrenceKind();
+          if (RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(Kind) ||
+              RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) ||
+              !RedPhi->getUnderlyingValue())
+            return true;
+          // TODO: Add support for FindIV reductions with sunk expressions: the
+          // resume value from the main loop is in expression domain (e.g.,
+          // mul(ReducedIV, 3)), but the epilogue tracks raw IV values. A sunk
+          // expression is identified by a non-VPInstruction user of
+          // ComputeReductionResult.
+          if (RecurrenceDescriptor::isFindIVRecurrenceKind(Kind)) {
+            auto *RdxResult = vputils::findComputeReductionResult(RedPhi);
+            assert(RdxResult &&
+                   "FindIV reduction must have ComputeReductionResult");
+            return any_of(RdxResult->users(),
+                          std::not_fn(IsaPred<VPInstruction>));
+          }
+          return false;
+        }
+        default:
+          return false;
+        };
+      });
+}
+
+bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
+    VPlan &MainPlan) const {
+  // Bail out if the plan contains header phi recipes not yet supported
+  // for epilogue vectorization.
+  if (hasUnsupportedHeaderPhiRecipe(MainPlan))
+    return false;
+
+  // Epilogue vectorization code has not been auditted to ensure it handles
+  // non-latch exits properly.  It may be fine, but it needs auditted and
+  // tested.
+  // TODO: Add support for loops with an early exit.
+  if (OrigLoop->getExitingBlock() != OrigLoop->getLoopLatch())
+    return false;
+
+  return true;
+}
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index e912751525fc7..a5669729b9d55 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3408,64 +3408,6 @@ static bool hasFindLastReductionPhi(VPlan &Plan) {
                 });
 }
 
-/// Returns true if the VPlan contains header phi recipes that are not currently
-/// supported for epilogue vectorization.
-static bool hasUnsupportedHeaderPhiRecipe(VPlan &Plan) {
-  return any_of(
-      Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis(),
-      [](VPRecipeBase &R) {
-        switch (R.getVPRecipeID()) {
-        case VPRecipeBase::VPFirstOrderRecurrencePHISC:
-          // TODO: Add support for fixed-order recurrences.
-          return true;
-        case VPRecipeBase::VPWidenIntOrFpInductionSC:
-          return !cast<VPWidenIntOrFpInductionRecipe>(&R)->getPHINode();
-        case VPRecipeBase::VPReductionPHISC: {
-          auto *RedPhi = cast<VPReductionPHIRecipe>(&R);
-          // TODO: Support FMinNum/FMaxNum, FindLast reductions, and reductions
-          // without underlying values.
-          RecurKind Kind = RedPhi->getRecurrenceKind();
-          if (RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(Kind) ||
-              RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) ||
-              !RedPhi->getUnderlyingValue())
-            return true;
-          // TODO: Add support for FindIV reductions with sunk expressions: the
-          // resume value from the main loop is in expression domain (e.g.,
-          // mul(ReducedIV, 3)), but the epilogue tracks raw IV values. A sunk
-          // expression is identified by a non-VPInstruction user of
-          // ComputeReductionResult.
-          if (RecurrenceDescriptor::isFindIVRecurrenceKind(Kind)) {
-            auto *RdxResult = vputils::findComputeReductionResult(RedPhi);
-            assert(RdxResult &&
-                   "FindIV reduction must have ComputeReductionResult");
-            return any_of(RdxResult->users(),
-                          std::not_fn(IsaPred<VPInstruction>));
-          }
-          return false;
-        }
-        default:
-          return false;
-        };
-      });
-}
-
-bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
-    VPlan &MainPlan) const {
-  // Bail out if the plan contains header phi recipes not yet supported
-  // for epilogue vectorization.
-  if (hasUnsupportedHeaderPhiRecipe(MainPlan))
-    return false;
-
-  // Epilogue vectorization code has not been auditted to ensure it handles
-  // non-latch exits properly.  It may be fine, but it needs auditted and
-  // tested.
-  // TODO: Add support for loops with an early exit.
-  if (OrigLoop->getExitingBlock() != OrigLoop->getLoopLatch())
-    return false;
-
-  return true;
-}
-
 bool LoopVectorizationCostModel::isEpilogueVectorizationProfitable(
     const ElementCount VF, const unsigned IC) const {
   // FIXME: We need a much better cost-model to take different parameters such

``````````

</details>


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


More information about the llvm-commits mailing list