[llvm] [VPlan] Extend predicated load hoisting to widen consecutive loads. (PR #168537)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 26 07:43:24 PST 2025
================
@@ -3968,6 +3970,177 @@ void VPlanTransforms::hoistInvariantLoads(VPlan &Plan) {
}
}
+// Returns the intersection of metadata from a group of loads.
+static VPIRMetadata getCommonLoadMetadata(ArrayRef<VPReplicateRecipe *> Loads) {
+ VPIRMetadata CommonMetadata = *Loads.front();
+ for (VPReplicateRecipe *Load : drop_begin(Loads))
+ CommonMetadata.intersect(*Load);
+ return CommonMetadata;
+}
+
+// Check if a load can be hoisted by verifying it doesn't alias with any stores
+// in blocks between FirstBB and LastBB using scoped noalias metadata.
+static bool canHoistLoadWithNoAliasCheck(VPReplicateRecipe *Load,
+ VPBasicBlock *FirstBB,
+ VPBasicBlock *LastBB) {
+ // Get the load's memory location and check if it aliases with any stores
+ // using scoped noalias metadata.
+ auto LoadLoc = vputils::getMemoryLocation(*Load);
+ if (!LoadLoc || !LoadLoc->AATags.Scope)
+ return false;
+
+ const AAMDNodes &LoadAA = LoadLoc->AATags;
+ for (VPBlockBase *Block = FirstBB; Block;
+ Block = Block->getSingleSuccessor()) {
+ // This function assumes a simple linear chain of blocks. If there are
+ // multiple successors, we would need more complex analysis.
+ assert(Block->getNumSuccessors() <= 1 &&
+ "Expected at most one successor in block chain");
+ auto *VPBB = cast<VPBasicBlock>(Block);
+ for (VPRecipeBase &R : *VPBB) {
+ if (R.mayWriteToMemory()) {
+ auto Loc = vputils::getMemoryLocation(R);
+ // Bail out if we can't get the location or if the scoped noalias
+ // metadata indicates potential aliasing.
+ if (!Loc || ScopedNoAliasAAResult::mayAliasInScopes(
+ LoadAA.Scope, Loc->AATags.NoAlias))
+ return false;
+ }
+ }
+
+ if (Block == LastBB)
+ break;
+ }
+ return true;
+}
+
+/// Check if \p Addr accesses consecutive memory locations of type \p LoadTy.
+static bool isConsecutiveLoad(VPValue *Addr, Type *LoadTy, ScalarEvolution &SE,
+ const DataLayout &DL, const Loop *L) {
+ using namespace SCEVPatternMatch;
+ const SCEV *AddrSCEV = vputils::getSCEVExprForVPValue(Addr, SE, L);
+ const SCEV *StepSCEV;
+ if (!match(AddrSCEV, m_scev_AffineAddRec(m_SCEV(), m_SCEV(StepSCEV),
+ m_SpecificLoop(L))))
+ return false;
+
+ TypeSize TS = DL.getTypeStoreSize(LoadTy);
+ const SCEV *ElementSizeSCEV = SE.getSizeOfExpr(StepSCEV->getType(), TS);
+ return SE.isKnownPositive(StepSCEV) && StepSCEV == ElementSizeSCEV;
----------------
fhahn wrote:
Yep, added a TODO. thanks!
https://github.com/llvm/llvm-project/pull/168537
More information about the llvm-commits
mailing list