[llvm] [GVN] Support rnflow pattern matching and transform (PR #162259)
Madhur Amilkanthwar via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 00:56:42 PDT 2026
================
@@ -3339,6 +3336,302 @@ void GVNPass::assignValNumForDeadCode() {
}
}
+/// Return true if the load can be hoisted to the loop preheader (no clobber
+/// in the loop) using MemorySSA's clobbering access.
+static bool canHoistLoadWithMSSA(Loop *L, Instruction *LoadInst,
+ MemorySSAUpdater *MSSAU) {
+ MemoryAccess *MA = MSSAU->getMemorySSA()->getMemoryAccess(LoadInst);
+ assert(MA && "MemoryAccess expected when MemorySSA is available");
+ MemoryAccess *Clobber =
+ MSSAU->getMemorySSA()->getSkipSelfWalker()->getClobberingMemoryAccess(MA);
+ if (!Clobber || MSSAU->getMemorySSA()->isLiveOnEntryDef(Clobber))
+ return true;
+ if (!L->contains(Clobber->getBlock()))
+ return true;
+ LLVM_DEBUG(dbgs() << "GVN: Cannot hoist - clobbered in loop by " << *Clobber
+ << "\n");
+ return false;
+}
+
+/// Return true if the load can be hoisted to the loop preheader (no clobber
+/// in the loop) using MemoryDependenceResults.
+static bool canHoistLoadWithMD(Loop *L, LoadInst *Load,
+ MemoryDependenceResults *MD) {
+ MemDepResult Dep = MD->getDependency(Load);
+ if (Dep.isLocal() && (Dep.isDef() || Dep.isClobber())) {
+ Instruction *DepInst = Dep.getInst();
+ if (DepInst && L->contains(DepInst->getParent())) {
+ LLVM_DEBUG(dbgs() << "GVN: Cannot hoist - clobbered in loop by "
+ << *DepInst << "\n");
+ return false;
+ }
+ } else if (Dep.isNonLocal()) {
+ SmallVector<NonLocalDepResult, 64> Deps;
+ MD->getNonLocalPointerDependency(Load, Deps);
+ for (const auto &NLDep : Deps) {
+ if (L->contains(NLDep.getBB()) &&
+ (NLDep.getResult().isDef() || NLDep.getResult().isClobber())) {
+ LLVM_DEBUG(dbgs() << "GVN: Cannot hoist - clobbered in loop (block "
+ << NLDep.getBB()->getName() << ")\n");
+ return false;
+ }
+ }
+ } else if (Dep.isUnknown()) {
+ LLVM_DEBUG(dbgs() << "GVN: Cannot hoist - unknown memory dependence\n");
+ return false;
+ }
+ return true;
+}
+
+/// Hoist the chain of operations for the second load to preheader.
+/// In this transformation, we hoist the redundant load to the preheader,
+/// caching the first value of the iteration. This value is used to compare with
+/// the current value of the iteration and update the minimum value.
+/// The comparison is done in the loop body using the new select instruction.
+///
+/// *** Before transformation ***
+///
+/// preheader:
+/// ...
+/// loop:
+/// ...
+/// ...
+/// %val.first = load <TYPE>, ptr %ptr.first.load, align 4
+/// %min.idx.ext = sext i32 %min.idx to i64
+/// %ptr.<TYPE>.min = getelementptr <TYPE>, ptr %0, i64 %min.idx.ext
+/// %ptr.second.load = getelementptr i8, ptr %ptr.<TYPE>.min, i64 -4
+/// %val.current.min = load <TYPE>, ptr %ptr.second.load, align 4
+/// ...
+/// ...
+/// br i1 %cond, label %loop, label %exit
+///
+/// We capture <TYPE> as a part of pattern matching and then later
+/// use it in the transformation.
+///
+/// *** After transformation ***
+///
+/// preheader:
+/// %min.idx.ext = sext i32 %min.idx.ext to i64
+/// %hoist_gep1 = getelementptr <TYPE>, ptr %0, i64 %min.idx.ext
+/// %hoist_gep2 = getelementptr i8, ptr %hoist_gep1, i64 -4
+/// %hoisted_load = load <TYPE>, ptr %hoist_gep2, align 4
+/// br label %loop
+///
+/// loop:
+/// %val.first = load <TYPE>, ptr %ptr.first.load, align 4
+/// ...
+/// (new) %val.current.min = select i1 %cond, <TYPE> %hoisted_load, <TYPE>
+/// %val.current.min
+/// ...
+/// ...
+/// br i1 %cond, label %loop, label %exit
+bool GVNPass::transformMinFindingSelectPattern(
+ Loop *L, Type *LoadType, BasicBlock *Preheader, BasicBlock *BB, Value *LHS,
+ Value *LoadVal, CmpInst *Comparison, SelectInst *Select, Value *BasePtr,
+ PHINode *IndexValPhi, Value *OffsetVal) {
+
+ assert(BasePtr && "BasePtr is null");
+ assert(OffsetVal && "OffsetVal is null");
+ assert(IndexValPhi && "IndexValPhi is null");
+ AAResults *AA = VN.getAliasAnalysis();
----------------
madhur13490 wrote:
Done.
https://github.com/llvm/llvm-project/pull/162259
More information about the llvm-commits
mailing list