[llvm] [LoopPeel] Peel last iteration to enable load widening (PR #173420)
Guy David via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 10:50:15 PDT 2026
================
@@ -895,6 +1098,70 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
}
}
+bool llvm::widenLoadsAfterPeel(Loop &L, ScalarEvolution &SE,
+ const TargetTransformInfo &TTI,
+ DominatorTree &DT) {
+ BasicBlock *Latch = L.getLoopLatch();
+ assert(Latch && "Loop should have a latch after peeling");
+ const DataLayout &DL = L.getHeader()->getDataLayout();
+ bool Changed = false;
+
+ for (BasicBlock *BB : L.blocks()) {
+ if (!DT.dominates(BB, Latch))
+ continue;
+ SmallVector<LoadGroup> Groups =
+ findLoadGroupsForWidening(BB, L, SE, DL, TTI);
+ for (const LoadGroup &Group : Groups) {
+ LoadInst *InsertPoint = Group.FirstLoad;
+ IRBuilder<> Builder(InsertPoint);
+ Value *BasePtr = Group.BasePtr;
+ int64_t FirstOffset = Group.Loads[0].second.getSExtValue();
+ unsigned AddrSpace = Group.FirstLoad->getPointerAddressSpace();
+ // If the first load doesn't start at offset 0, we need to adjust.
+ if (FirstOffset != 0) {
+ Value *OrigPtr = Group.BasePtr;
+ BasePtr = Builder.CreatePtrAdd(
+ OrigPtr,
+ ConstantInt::get(Builder.getIndexTy(DL, AddrSpace), FirstOffset));
+ }
+ // Merge AA metadata from all loads using intersection for correctness.
+ AAMDNodes AATags = InsertPoint->getAAMetadata();
+ for (const auto &[Load, Offset] : Group.Loads) {
+ if (Load != InsertPoint)
+ AATags = AATags.merge(Load->getAAMetadata());
+ }
+ // Create the wider load.
+ LoadInst *WideLoad = Builder.CreateLoad(Group.WideType, BasePtr);
+ unsigned SizeInBits = WideLoad->getType()->getScalarSizeInBits();
+ if (AATags)
+ WideLoad->setAAMetadata(AATags);
+ // For each original load, extract the corresponding bytes.
+ for (const auto &[Load, Offset] : Group.Loads) {
+ unsigned LoadBits = Load->getType()->getScalarSizeInBits();
+ Value *Extracted = WideLoad;
+ uint64_t BitPosition = (Offset.getSExtValue() - FirstOffset) * 8;
+ uint64_t BitOffset =
+ DL.getElementBitOffset(BitPosition, LoadBits, SizeInBits);
+ if (BitOffset != 0)
+ Extracted = Builder.CreateLShr(
+ Extracted, ConstantInt::get(WideLoad->getType(), BitOffset));
+ if (LoadBits < SizeInBits)
+ Extracted = Builder.CreateTrunc(Extracted, Load->getType());
+ Load->replaceAllUsesWith(Extracted);
+ }
+ // Delete the original loads.
+ for (auto &[Load, Offset] : Group.Loads)
+ Load->eraseFromParent();
----------------
guy-david wrote:
Formatter actually changes this back into a regular for loop.
https://github.com/llvm/llvm-project/pull/173420
More information about the llvm-commits
mailing list