[llvm] [LV] Strip VPlanNativePath (PR #189979)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 08:33:41 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-vectorizers
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
VPlanNativePath was introduced nearly a decade ago, with the intent of being temporary, but little progress has been made since. Much of it has bitrotted due to heavy changes to VPlan, and although it is a significant amount of code, the testing is very sparse: there are a total of 26 tests that even enable the VPlan-native path.
The big-ticket item for getting VPlanNativePath to work is to have outer loops supported by a dependence analysis -- currently, LoopAccessAnalysis bails out on non-innermost loops altogether.
Although there is undoubedly benefit to vectorizing outer loops, it is perhaps better to start attacking the problem from a clean slate, rather than trying to work with the broken VPlanNativePath.
Strip VPlanNativePath entirely, migrating some of the test-coverage to the usual innermost-loop path.
---
Patch is 239.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/189979.diff
32 Files Affected:
- (modified) llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h (+3-19)
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp (+10-169)
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h (-18)
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+7-268)
- (modified) llvm/lib/Transforms/Vectorize/VPlan.cpp (-21)
- (removed) llvm/test/Transforms/LoopVectorize/AArch64/outer_loop_prefer_scalable.ll (-106)
- (removed) llvm/test/Transforms/LoopVectorize/AArch64/outer_loop_test1_no_explicit_vect_width.ll (-151)
- (removed) llvm/test/Transforms/LoopVectorize/VPlan/vplan-printing-outer-loop.ll (-73)
- (removed) llvm/test/Transforms/LoopVectorize/VPlan/vplan-stress-test-no-explict-vf.ll (-43)
- (removed) llvm/test/Transforms/LoopVectorize/VPlan/vplan_hcfg_stress_test.ll (-48)
- (removed) llvm/test/Transforms/LoopVectorize/X86/outer_loop_test1_no_explicit_vect_width.ll (-115)
- (removed) llvm/test/Transforms/LoopVectorize/X86/vplan-native-inner-loop-only.ll (-83)
- (removed) llvm/test/Transforms/LoopVectorize/dbg-outer-loop-vect.ll (-172)
- (removed) llvm/test/Transforms/LoopVectorize/explicit_outer_detection.ll (-236)
- (removed) llvm/test/Transforms/LoopVectorize/explicit_outer_nonuniform_inner.ll (-173)
- (removed) llvm/test/Transforms/LoopVectorize/explicit_outer_uniform_diverg_branch.ll (-136)
- (added) llvm/test/Transforms/LoopVectorize/inner-loop-reduction.ll (+86)
- (renamed) llvm/test/Transforms/LoopVectorize/inner-loop-with-rtchecks.ll (+1-1)
- (removed) llvm/test/Transforms/LoopVectorize/noalias-scope-decl-outer-loop.ll (-73)
- (removed) llvm/test/Transforms/LoopVectorize/non-widenable-intrinsics-outer-loop.ll (-477)
- (removed) llvm/test/Transforms/LoopVectorize/outer-loop-inner-latch-successors.ll (-210)
- (removed) llvm/test/Transforms/LoopVectorize/outer-loop-vec-phi-predecessor-order.ll (-121)
- (removed) llvm/test/Transforms/LoopVectorize/outer-loop-wide-phis.ll (-220)
- (removed) llvm/test/Transforms/LoopVectorize/outer_loop_early_exit.ll (-49)
- (removed) llvm/test/Transforms/LoopVectorize/outer_loop_hcfg_construction.ll (-319)
- (removed) llvm/test/Transforms/LoopVectorize/outer_loop_scalable.ll (-140)
- (removed) llvm/test/Transforms/LoopVectorize/outer_loop_test1.ll (-88)
- (removed) llvm/test/Transforms/LoopVectorize/outer_loop_test2.ll (-107)
- (removed) llvm/test/Transforms/LoopVectorize/vplan-outer-loop-uncomputable-trip-count.ll (-47)
- (removed) llvm/test/Transforms/LoopVectorize/vplan-vectorize-inner-loop-reduction.ll (-78)
- (renamed) llvm/test/Transforms/LoopVectorize/widen-call.ll (+20-47)
- (renamed) llvm/test/Transforms/LoopVectorize/widen-select.ll (+73-85)
``````````diff
diff --git a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
index cff9162e39f60..48a86cac58997 100644
--- a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
+++ b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
@@ -292,11 +292,7 @@ class LoopVectorizationLegality {
/// Returns true if it is legal to vectorize this loop.
/// This does not mean that it is profitable to vectorize this
/// loop, only that it is legal to do so.
- /// Temporarily taking UseVPlanNativePath parameter. If true, take
- /// the new code path being implemented for outer loop vectorization
- /// (should be functional for inner loop vectorization) based on VPlan.
- /// If false, good old LV code.
- bool canVectorize(bool UseVPlanNativePath);
+ bool canVectorize();
/// Returns true if it is legal to vectorize the FP math operations in this
/// loop. Vectorizing is legal if we allow reordering of FP operations, or if
@@ -500,11 +496,7 @@ class LoopVectorizationLegality {
/// Return true if the pre-header, exiting and latch blocks of \p Lp and all
/// its nested loops are considered legal for vectorization. These legal
/// checks are common for inner and outer loop vectorization.
- /// Temporarily taking UseVPlanNativePath parameter. If true, take
- /// the new code path being implemented for outer loop vectorization
- /// (should be functional for inner loop vectorization) based on VPlan.
- /// If false, good old LV code.
- bool canVectorizeLoopNestCFG(Loop *Lp, bool UseVPlanNativePath);
+ bool canVectorizeLoopNestCFG(Loop *Lp);
/// Set up outer loop inductions by checking Phis in outer loop header for
/// supported inductions (int inductions). Return false if any of these Phis
@@ -513,11 +505,7 @@ class LoopVectorizationLegality {
/// Return true if the pre-header, exiting and latch blocks of \p Lp
/// (non-recursive) are considered legal for vectorization.
- /// Temporarily taking UseVPlanNativePath parameter. If true, take
- /// the new code path being implemented for outer loop vectorization
- /// (should be functional for inner loop vectorization) based on VPlan.
- /// If false, good old LV code.
- bool canVectorizeLoopCFG(Loop *Lp, bool UseVPlanNativePath);
+ bool canVectorizeLoopCFG(Loop *Lp);
/// Check if a single basic block loop is vectorizable.
/// At this point we know that this is a loop with a constant trip count
@@ -542,10 +530,6 @@ class LoopVectorizationLegality {
/// transformation.
bool canVectorizeWithIfConvert();
- /// Return true if we can vectorize this outer loop. The method performs
- /// specific checks for outer loop vectorization.
- bool canVectorizeOuterLoop();
-
/// Returns true if this is an early exit loop that can be vectorized.
/// Currently, a loop with an uncountable early exit is considered
/// vectorizable if:
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 6e4ecbdecb7cf..e59c8e75ba16d 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -335,86 +335,6 @@ void LoopVectorizeHints::setHint(StringRef Name, Metadata *Arg) {
}
}
-// Return true if the inner loop \p Lp is uniform with regard to the outer loop
-// \p OuterLp (i.e., if the outer loop is vectorized, all the vector lanes
-// executing the inner loop will execute the same iterations). This check is
-// very constrained for now but it will be relaxed in the future. \p Lp is
-// considered uniform if it meets all the following conditions:
-// 1) it has a canonical IV (starting from 0 and with stride 1),
-// 2) its latch terminator is a conditional branch and,
-// 3) its latch condition is a compare instruction whose operands are the
-// canonical IV and an OuterLp invariant.
-// This check doesn't take into account the uniformity of other conditions not
-// related to the loop latch because they don't affect the loop uniformity.
-//
-// NOTE: We decided to keep all these checks and its associated documentation
-// together so that we can easily have a picture of the current supported loop
-// nests. However, some of the current checks don't depend on \p OuterLp and
-// would be redundantly executed for each \p Lp if we invoked this function for
-// different candidate outer loops. This is not the case for now because we
-// don't currently have the infrastructure to evaluate multiple candidate outer
-// loops and \p OuterLp will be a fixed parameter while we only support explicit
-// outer loop vectorization. It's also very likely that these checks go away
-// before introducing the aforementioned infrastructure. However, if this is not
-// the case, we should move the \p OuterLp independent checks to a separate
-// function that is only executed once for each \p Lp.
-static bool isUniformLoop(Loop *Lp, Loop *OuterLp) {
- assert(Lp->getLoopLatch() && "Expected loop with a single latch.");
-
- // If Lp is the outer loop, it's uniform by definition.
- if (Lp == OuterLp)
- return true;
- assert(OuterLp->contains(Lp) && "OuterLp must contain Lp.");
-
- // 1.
- PHINode *IV = Lp->getCanonicalInductionVariable();
- if (!IV) {
- LLVM_DEBUG(dbgs() << "LV: Canonical IV not found.\n");
- return false;
- }
-
- // 2.
- BasicBlock *Latch = Lp->getLoopLatch();
- auto *LatchBr = dyn_cast<CondBrInst>(Latch->getTerminator());
- if (!LatchBr) {
- LLVM_DEBUG(dbgs() << "LV: Unsupported loop latch branch.\n");
- return false;
- }
-
- // 3.
- auto *LatchCmp = dyn_cast<CmpInst>(LatchBr->getCondition());
- if (!LatchCmp) {
- LLVM_DEBUG(
- dbgs() << "LV: Loop latch condition is not a compare instruction.\n");
- return false;
- }
-
- Value *CondOp0 = LatchCmp->getOperand(0);
- Value *CondOp1 = LatchCmp->getOperand(1);
- Value *IVUpdate = IV->getIncomingValueForBlock(Latch);
- if (!(CondOp0 == IVUpdate && OuterLp->isLoopInvariant(CondOp1)) &&
- !(CondOp1 == IVUpdate && OuterLp->isLoopInvariant(CondOp0))) {
- LLVM_DEBUG(dbgs() << "LV: Loop latch condition is not uniform.\n");
- return false;
- }
-
- return true;
-}
-
-// Return true if \p Lp and all its nested loops are uniform with regard to \p
-// OuterLp.
-static bool isUniformLoopNest(Loop *Lp, Loop *OuterLp) {
- if (!isUniformLoop(Lp, OuterLp))
- return false;
-
- // Check if nested loops are uniform.
- for (Loop *SubLp : *Lp)
- if (!isUniformLoopNest(SubLp, OuterLp))
- return false;
-
- return true;
-}
-
static IntegerType *getInductionIntegerTy(const DataLayout &DL, Type *Ty) {
assert(Ty->isIntOrPtrTy() && "Expected integer or pointer type");
@@ -630,73 +550,6 @@ bool LoopVectorizationLegality::isUniformMemOp(Instruction &I,
return isUniform(Ptr, VF) && !blockNeedsPredication(I.getParent());
}
-bool LoopVectorizationLegality::canVectorizeOuterLoop() {
- assert(!TheLoop->isInnermost() && "We are not vectorizing an outer loop.");
- // Store the result and return it at the end instead of exiting early, in case
- // allowExtraAnalysis is used to report multiple reasons for not vectorizing.
- bool Result = true;
- bool DoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
-
- for (BasicBlock *BB : TheLoop->blocks()) {
- // Check whether the BB terminator is a branch. Any other terminator is
- // not supported yet.
- Instruction *Term = BB->getTerminator();
- if (!isa<UncondBrInst, CondBrInst>(Term)) {
- reportVectorizationFailure("Unsupported basic block terminator",
- "loop control flow is not understood by vectorizer",
- "CFGNotUnderstood", ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
- }
-
- // Check whether the branch is a supported one. Only unconditional
- // branches, conditional branches with an outer loop invariant condition or
- // backedges are supported.
- // FIXME: We skip these checks when VPlan predication is enabled as we
- // want to allow divergent branches. This whole check will be removed
- // once VPlan predication is on by default.
- auto *Br = dyn_cast<CondBrInst>(Term);
- if (Br && !TheLoop->isLoopInvariant(Br->getCondition()) &&
- !LI->isLoopHeader(Br->getSuccessor(0)) &&
- !LI->isLoopHeader(Br->getSuccessor(1))) {
- reportVectorizationFailure("Unsupported conditional branch",
- "loop control flow is not understood by vectorizer",
- "CFGNotUnderstood", ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
- }
- }
-
- // Check whether inner loops are uniform. At this point, we only support
- // simple outer loops scenarios with uniform nested loops.
- if (!isUniformLoopNest(TheLoop /*loop nest*/,
- TheLoop /*context outer loop*/)) {
- reportVectorizationFailure("Outer loop contains divergent loops",
- "loop control flow is not understood by vectorizer",
- "CFGNotUnderstood", ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
- }
-
- // Check whether we are able to set up outer loop induction.
- if (!setupOuterLoopInductions()) {
- reportVectorizationFailure("Unsupported outer loop Phi(s)",
- "UnsupportedPhi", ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
- }
-
- return Result;
-}
-
void LoopVectorizationLegality::addInductionPhi(
PHINode *Phi, const InductionDescriptor &ID,
SmallPtrSetImpl<Value *> &AllowedExit) {
@@ -1616,10 +1469,8 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
}
// Helper function to canVectorizeLoopNestCFG.
-bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
- bool UseVPlanNativePath) {
- assert((UseVPlanNativePath || Lp->isInnermost()) &&
- "VPlan-native path is not enabled.");
+bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp) {
+ assert(Lp->isInnermost() && "Expected innermost loop");
// TODO: ORE should be improved to show more accurate information when an
// outer loop can't be vectorized because a nested loop is not understood or
@@ -1670,13 +1521,12 @@ bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
return Result;
}
-bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
- Loop *Lp, bool UseVPlanNativePath) {
+bool LoopVectorizationLegality::canVectorizeLoopNestCFG(Loop *Lp) {
// Store the result and return it at the end instead of exiting early, in case
// allowExtraAnalysis is used to report multiple reasons for not vectorizing.
bool Result = true;
bool DoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
- if (!canVectorizeLoopCFG(Lp, UseVPlanNativePath)) {
+ if (!canVectorizeLoopCFG(Lp)) {
if (DoExtraAnalysis)
Result = false;
else
@@ -1686,7 +1536,7 @@ bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
// Recursively check whether the loop control flow of nested loops is
// understood.
for (Loop *SubLp : *Lp)
- if (!canVectorizeLoopNestCFG(SubLp, UseVPlanNativePath)) {
+ if (!canVectorizeLoopNestCFG(SubLp)) {
if (DoExtraAnalysis)
Result = false;
else
@@ -1930,7 +1780,7 @@ bool LoopVectorizationLegality::canUncountableExitConditionLoadBeMoved(
return true;
}
-bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
+bool LoopVectorizationLegality::canVectorize() {
// Store the result and return it at the end instead of exiting early, in case
// allowExtraAnalysis is used to report multiple reasons for not vectorizing.
bool Result = true;
@@ -1938,7 +1788,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
bool DoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
// Check whether the loop-related control flow in the loop nest is expected by
// vectorizer.
- if (!canVectorizeLoopNestCFG(TheLoop, UseVPlanNativePath)) {
+ if (!canVectorizeLoopNestCFG(TheLoop)) {
if (DoExtraAnalysis) {
LLVM_DEBUG(dbgs() << "LV: legality check failed: loop nest");
Result = false;
@@ -1954,18 +1804,9 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
// Specific checks for outer loops. We skip the remaining legal checks at this
// point because they don't support outer loops.
if (!TheLoop->isInnermost()) {
- assert(UseVPlanNativePath && "VPlan-native path is not enabled.");
-
- if (!canVectorizeOuterLoop()) {
- reportVectorizationFailure("Unsupported outer loop",
- "UnsupportedOuterLoop", ORE, TheLoop);
- // TODO: Implement DoExtraAnalysis when subsequent legal checks support
- // outer loops.
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "LV: We can vectorize this outer loop!\n");
- return Result;
+ reportVectorizationFailure("Unsupported outer loop vectorization",
+ "UnsupportedOuterLoop", ORE, TheLoop);
+ return false;
}
assert(TheLoop->isInnermost() && "Inner loop expected.");
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
index bab9efee37533..054184ea8e4eb 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
@@ -48,7 +48,6 @@ class VPRecipeBuilder;
struct VPRegisterUsage;
struct VFRange;
-extern cl::opt<bool> EnableVPlanNativePath;
extern cl::opt<unsigned> ForceTargetInstructionCost;
/// VPlan-based builder utility analogous to IRBuilder.
@@ -553,10 +552,6 @@ class LoopVectorizationPlanner {
/// interleaving should be avoided up-front, no plans are generated.
void plan(ElementCount UserVF, unsigned UserIC);
- /// Use the VPlan-native path to plan how to best vectorize, return the best
- /// VF and its cost.
- VectorizationFactor planInVPlanNativePath(ElementCount UserVF);
-
/// Return the VPlan for \p VF. At the moment, there is always a single VPlan
/// for each VF.
VPlan &getPlanFor(ElementCount VF) const;
@@ -643,20 +638,7 @@ class LoopVectorizationPlanner {
unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
bool DisableRuntimeUnroll);
-protected:
- /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
- /// according to the information gathered by Legal when it checked if it is
- /// legal to vectorize the loop.
- void buildVPlans(ElementCount MinVF, ElementCount MaxVF);
-
private:
- /// Build a VPlan according to the information gathered by Legal. \return a
- /// VPlan for vectorization factors \p Range.Start and up to \p Range.End
- /// exclusive, possibly decreasing \p Range.End. If no VPlan can be built for
- /// the input range, set the largest included VF to the maximum VF for which
- /// no plan could be built.
- VPlanPtr tryToBuildVPlan(VFRange &Range);
-
/// Build a VPlan using VPRecipes according to the information gather by
/// Legal. This method is only used for the legacy inner loop vectorizer.
/// \p Range's largest included VF is restricted to the maximum VF the
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 32ef10e530187..85ef646e09e09 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -26,12 +26,7 @@
// can be one, if vectorization is not profitable.
//
// There is a development effort going on to migrate loop vectorizer to the
-// VPlan infrastructure and to introduce outer loop vectorization support (see
-// docs/VectorizationPlan.rst and
-// http://lists.llvm.org/pipermail/llvm-dev/2017-December/119523.html). For this
-// purpose, we temporarily introduced the VPlan-native vectorization path: an
-// alternative vectorization path that is natively implemented on top of the
-// VPlan infrastructure. See EnableVPlanNativePath for enabling.
+// VPlan infrastructure and (see docs/VectorizationPlan.rst).
//
//===----------------------------------------------------------------------===//
//
@@ -355,11 +350,6 @@ static cl::opt<bool> PreferPredicatedReductionSelect(
cl::desc(
"Prefer predicating a reduction operation over an after loop select."));
-cl::opt<bool> llvm::EnableVPlanNativePath(
- "enable-vplan-native-path", cl::Hidden,
- cl::desc("Enable VPlan-native vectorization path with "
- "support for outer loop vectorization."));
-
cl::opt<bool>
llvm::VerifyEachVPlan("vplan-verify-each",
#ifdef EXPENSIVE_CHECKS
@@ -385,17 +375,6 @@ cl::opt<bool> llvm::VPlanPrintVectorRegionScope(
"`-vplan-print-after*` if the plan has one."));
#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
-// verification of the H-CFGs built.
-static cl::opt<bool> VPlanBuildStressTest(
- "vplan-build-stress-test", cl::init(false), cl::Hidden,
- cl::desc(
- "Build VPlan for every supported loop nest in the function and bail "
- "out right after the build (stress test the VPlan H-CFG construction "
- "in the VPlan-native vectorization path)."));
-
cl::opt<bool> llvm::EnableLoopInterleaving(
"interleave-loops", cl::init(true), cl::Hidden,
cl::desc("Enable loop interleaving in Loop vectorization passes"));
@@ -1360,8 +1339,8 @@ class LoopVectorizationCostModel {
return;
// Override EVL styles if needed.
// FIXME: Investigate opportunity for fixed vector factor.
- bool EVLIsLegal = UserIC <= 1 && IsScalableVF &&
- TTI.hasActiveVectorLength() && !EnableVPlanNativePath;
+ bool EVLIsLegal =
+ UserIC <= 1 && IsScalableVF && TTI.hasActiveVectorLength();
if (EVLIsLegal)
return;
// If for some reason EVL mode is unsupported, fallback to a scalar epilogue
@@ -2100,48 +2079,6 @@ static bool useActiveLaneMaskForControlFlow(TailFoldingStyle Style) {
return Style == TailFoldingStyle::DataAndControlFlow;
}
-// Return true if \p OuterLp is an outer loop annotated with hints for explicit
-// vectorization. The loop needs to be annotated with #pragma omp simd
-// simdlen(#) or #pragma clang vectorize(enable) vectorize_width(#). If the
-// vector length information is not provided, vectorization is not considered
-// explicit. Interleave hints are not allowed either. These limitations will be
-// relaxed in the future.
-// Please, note that we are currently forced to abuse the pragma 'clang
-// vectorize' semantics. This pragma provides *auto-vectorization hints*
-// (i.e., LV must check that vectorization is legal) whereas pragma 'omp simd'
-// provides *explicit vectorization hints* (LV can bypass legal checks and
-// assume that vectorization is legal). However, both hints are implemented
-// using the same metadata (llvm.loop.vectorize, processed by
-// LoopVectorizeHints). This will be fixed in the future when the native IR
-// representation for pragma 'omp simd' is introduced.
-static bool isExplicitVecOuterLoop(Loop *OuterLp,
- OptimizationRemarkEmitter *ORE) {
- assert(!OuterLp->isInnermost() && "This is not an outer loop");
- LoopVectorizeHints Hints(OuterLp, true /*DisableInterleaving*/, *ORE);
-
- // Only outer loops with an explicit vectorization hint are supported.
- // Unannotated outer loops are ignored.
- if (Hints.getForce() == LoopVectorizeHints::FK_Undefined)
- return false;
-
- Function *Fn = OuterLp->getHeader()->getParent();
- if (!Hints.allowVectorization(Fn, OuterLp,
- true /*VectorizeOnlyWhenForced*/)) {
- LLVM_DEBUG(dbgs() << "LV: Loop hints prevent outer loop vectorization.\n");
- return false;
- }
-
- if (Hints.getInterleave() > 1) {
- // TODO: Interleave support is future work.
- LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Interleave is not supported for "
- "outer loops.\n");
- Hin...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/189979
More information about the llvm-commits
mailing list