summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
diff options
context:
space:
mode:
authorLuke Lau <luke@igalia.com>2025-11-13 21:17:01 +0800
committerGitHub <noreply@github.com>2025-11-13 13:17:01 +0000
commitc0f7d51e8a49ebf9ac0426cd9d19dba657c8447e (patch)
tree079d7d33539dfe066dc863692477d1856a7d66ac /llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
parent78554d9e8437c88058e6ab8b95d10eaebb8c3ca9 (diff)
[VPlan] Simplify ExplicitVectorLength(%AVL) -> %AVL when AVL <= VF (#167647)
[`llvm.experimental.get.vector.length`](https://llvm.org/docs/LangRef.html#id2399) has the property that if the AVL (%cnt) is less than or equal to VF (%max_lanes) then the return value is just AVL. This patch uses SCEV to simplify this in optimizeForVFAndUF, and adds `ExplicitVectorLength` to `VPInstruction::opcodeMayReadOrWriteFromMemory` so it gets removed once dead.
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp')
-rw-r--r--llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index e8fea6851dae..7fe40c3e0490 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1843,6 +1843,35 @@ 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;
+
+ ScalarEvolution &SE = *PSE.getSE();
+ const SCEV *AVLSCEV = vputils::getSCEVExprForVPValue(AVL, SE);
+ if (isa<SCEVCouldNotCompute>(AVLSCEV))
+ continue;
+ 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) {
@@ -1852,6 +1881,7 @@ 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);