[llvm] [GVN] Support rnflow pattern matching and transform (PR #162259)
Madhur Amilkanthwar via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 28 08:27:48 PST 2026
================
@@ -3330,6 +3333,235 @@ void GVNPass::assignValNumForDeadCode() {
}
}
+// 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
+//
+// *** 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,
+ Value *IndexVal, Value *OffsetVal) {
+
+ assert(IndexVal && "IndexVal is null");
+ AAResults *AA = VN.getAliasAnalysis();
+ assert(AA && "AA is null");
+
+ IRBuilder<> Builder(Preheader->getTerminator());
+ Value *InitialMinIndex =
+ dyn_cast<PHINode>(IndexVal)->getIncomingValueForBlock(Preheader);
+
+ // Insert PHI node at the top of this block.
+ // This PHI node will be used to memoize the current minimum value so far.
+ PHINode *KnownMinPhi = PHINode::Create(LoadType, 2, "known_min", BB->begin());
+
+ // Hoist the load and build the necessary operations.
+ // 1. hoist_0 = sext i32 1 to i64
+ Value *HoistedSExt =
+ Builder.CreateSExt(InitialMinIndex, Builder.getInt64Ty(), "hoist_sext");
+
+ // 2. hoist_gep1 = getelementptr float, ptr BasePtr, i64 HoistedSExt
+ Value *HoistedGEP1 =
+ Builder.CreateGEP(LoadType, BasePtr, HoistedSExt, "hoist_gep1");
+
+ // 3. hoist_gep2 = getelementptr i8, ptr HoistedGEP1, i64 OffsetVal
+ Value *HoistedGEP2 = Builder.CreateGEP(Builder.getInt8Ty(), HoistedGEP1,
+ OffsetVal, "hoist_gep2");
+
+ MemoryLocation NewLoc = MemoryLocation(
----------------
madhur13490 wrote:
Done
https://github.com/llvm/llvm-project/pull/162259
More information about the llvm-commits
mailing list