Skip to content

[VPlan] Replace simplifyKnownEVL by fold in simplifyRecipe (NFCI).#183392

Closed
fhahn wants to merge 1 commit into
llvm:mainfrom
fhahn:vplan-move-evl-fold
Closed

[VPlan] Replace simplifyKnownEVL by fold in simplifyRecipe (NFCI).#183392
fhahn wants to merge 1 commit into
llvm:mainfrom
fhahn:vplan-move-evl-fold

Conversation

@fhahn

@fhahn fhahn commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Move the logic to simplify known EVL to simplifyRecipe as fold once we have a single VF.

It does not look like this is only triggers when folding EVL with constant arguments. It cannot be a complete constant fold, as it needs to access the function's vscale range.

Needed to avoid regressions in combination with
#181252.

Move the logic to simplify known EVL to simplifyRecipe as fold once we
have a single VF.

It does not look like this is only triggers when folding EVL with
constant arguments. It cannot be a complete constant fold, as it needs
to access the function's vscale range.

Needed to avoid regressions in combination with
llvm#181252.
@llvmbot

llvmbot commented Feb 25, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

Changes

Move the logic to simplify known EVL to simplifyRecipe as fold once we have a single VF.

It does not look like this is only triggers when folding EVL with constant arguments. It cannot be a complete constant fold, as it needs to access the function's vscale range.

Needed to avoid regressions in combination with
#181252.


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

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+20-30)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index c16149303b180..180f7270a2d50 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Analysis/MemoryLocation.h"
 #include "llvm/Analysis/ScalarEvolutionPatternMatch.h"
 #include "llvm/Analysis/ScopedNoAliasAA.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
@@ -1532,6 +1533,25 @@ static void simplifyRecipe(VPSingleDefRecipe *Def, VPTypeAnalysis &TypeInfo) {
       match(Def, m_ComputeReductionResult(m_VPIRValue(IRV))))
     return Def->replaceAllUsesWith(IRV);
 
+  // Fold EVL(const_avl) -> const_avl when const_avl is known to be <= VF *
+  // vscale_min.
+  const APInt *AVL;
+  if (match(Def, m_EVL(m_APInt(AVL))) && size(Plan->vectorFactors()) == 1) {
+    ElementCount VF = *Plan->vectorFactors().begin();
+    uint64_t MinVScale = 1;
+    if (VF.isScalable()) {
+      const Function *F =
+          Plan->getScalarHeader()->getIRBasicBlock()->getParent();
+      MinVScale =
+          getVScaleRange(F, /*BitWidth=*/64).getUnsignedMin().getZExtValue();
+    }
+    unsigned MaxLanes = VF.getKnownMinValue() * MinVScale;
+    if (AVL->ule(MaxLanes)) {
+      return Def->replaceAllUsesWith(
+          Plan->getConstantInt(AVL->zextOrTrunc(32)));
+    }
+  }
+
   // Some simplifications can only be applied after unrolling. Perform them
   // below.
   if (!Plan->isUnrolled())
@@ -2166,35 +2186,6 @@ static bool simplifyBranchConditionForVFAndUF(VPlan &Plan, ElementCount BestVF,
   return true;
 }
 
-/// From the definition of llvm.experimental.get.vector.length,
-/// VPInstruction::ExplicitVectorLength(%AVL) = %AVL when %AVL <= VF.
-static bool simplifyKnownEVL(VPlan &Plan, ElementCount VF,
-                             PredicatedScalarEvolution &PSE) {
-  for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
-           vp_depth_first_deep(Plan.getEntry()))) {
-    for (VPRecipeBase &R : *VPBB) {
-      VPValue *AVL;
-      if (!match(&R, m_EVL(m_VPValue(AVL))))
-        continue;
-
-      const SCEV *AVLSCEV = vputils::getSCEVExprForVPValue(AVL, PSE);
-      if (isa<SCEVCouldNotCompute>(AVLSCEV))
-        continue;
-      ScalarEvolution &SE = *PSE.getSE();
-      const SCEV *VFSCEV = SE.getElementCount(AVLSCEV->getType(), VF);
-      if (!SE.isKnownPredicate(CmpInst::ICMP_ULE, AVLSCEV, VFSCEV))
-        continue;
-
-      VPValue *Trunc = VPBuilder(&R).createScalarZExtOrTrunc(
-          AVL, Type::getInt32Ty(Plan.getContext()), AVLSCEV->getType(),
-          R.getDebugLoc());
-      R.getVPSingleValue()->replaceAllUsesWith(Trunc);
-      return true;
-    }
-  }
-  return false;
-}
-
 void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
                                          unsigned BestUF,
                                          PredicatedScalarEvolution &PSE) {
@@ -2204,7 +2195,6 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
   bool MadeChange = tryToReplaceALMWithWideALM(Plan, BestVF, BestUF);
   MadeChange |= simplifyBranchConditionForVFAndUF(Plan, BestVF, BestUF, PSE);
   MadeChange |= optimizeVectorInductionWidthForTCAndVFUF(Plan, BestVF, BestUF);
-  MadeChange |= simplifyKnownEVL(Plan, BestVF, PSE);
 
   if (MadeChange) {
     Plan.setVF(BestVF);

@artagnon artagnon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hm, have to get @lukel97 to chime in on this -- the equivalence of comparing SCEVs and a constant isn't obvious to me.

@fhahn

fhahn commented Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

Found a case where this is not NFC and we need SCEV to simplify. Will add a test and close this one

@fhahn fhahn closed this Feb 26, 2026
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.

3 participants