[llvm] Extending LoopVersioningLICM to handle cases where loopbound is invariant (PR #192902)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 02:14:50 PDT 2026


================
@@ -507,39 +638,149 @@ bool LoopVersioningLICM::isLegalForVersioning() {
   return true;
 }
 
+Instruction *LoopVersioningLICM::insertRuntimeCheckPlaceholder(Loop *L) {
+  // Preheader for our checks
+  BasicBlock *Preheader = L->getLoopPreheader();
+
+  // Determine the insertion point.
+  Instruction *InsertPt = Preheader->getTerminator();
+  LLVMContext &Context = CurLoop->getHeader()->getParent()->getContext();
+  // Create the comparison.
+  Instruction *Placeholder = nullptr;
+  Placeholder = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ,
+                                 ConstantInt::get(Type::getInt32Ty(Context), 1),
+                                 ConstantInt::get(Type::getInt32Ty(Context), 1),
+                                 "runtime.check.placeholder", InsertPt->getIterator());
+
+  return Placeholder;
+}
+
+void LoopVersioningLICM::generateAndAddRuntimeChecks(DominatorTree *DT) {
+  BasicBlock *RuntimeCheckBB = PlaceholderForRuntimeChecks->getParent();
+
+  const auto &RtPtrChecking = *LAI->getRuntimePointerChecking();
+
+  SCEVExpander Exp1(*RtPtrChecking.getSE(), "induction");
+  
+  auto RPC = LAI->getRuntimePointerChecking();
+
+  Value *MemRuntimeChecks = llvm::addRuntimeChecks(PlaceholderForRuntimeChecks, 
+    CurLoop, RPC->getChecks(), Exp1);
+
+  SCEVExpander Exp2(*SE, "scev.check");
+  
+  const SCEVPredicate &Preds(LAI->getPSE().getPredicate());
+  Value *SCEVRuntimeChecks = Exp2.expandCodeForPredicate(&Preds, PlaceholderForRuntimeChecks);
+
+  IRBuilder<InstSimplifyFolder> Builder(RuntimeCheckBB->getContext(), 
+                InstSimplifyFolder(RuntimeCheckBB->getModule()->getDataLayout()));
+  
+  Value *RuntimeCheck = nullptr;
+  if (MemRuntimeChecks && SCEVRuntimeChecks) {
+    Builder.SetInsertPoint(PlaceholderForRuntimeChecks);
+    RuntimeCheck = Builder.CreateOr(MemRuntimeChecks, SCEVRuntimeChecks, "lver.safe");
+  } else {
+    RuntimeCheck = MemRuntimeChecks ? MemRuntimeChecks : SCEVRuntimeChecks;
+  }
+
+  RuntimeCheckBB->setName(CurLoop->getHeader()->getName() + ".lver.check");
+
+  CondBrInst *BI = dyn_cast<CondBrInst>(RuntimeCheckBB->getTerminator());
+  assert(BI && "Expected conditional branch in runtime check block");
+
+  assert(RuntimeCheck && "called even though we don't need "
+    "any runtime checks");
+
+  PlaceholderForRuntimeChecks->replaceAllUsesWith(RuntimeCheck);
+  PlaceholderForRuntimeChecks->eraseFromParent();
+}
+
 bool LoopVersioningLICM::run(DominatorTree *DT) {
   // Do not do the transformation if disabled by metadata.
   if (hasLICMVersioningTransformation(CurLoop) & TM_Disable)
     return false;
-
   bool Changed = false;
-
----------------
artagnon wrote:

Please avoid stray changes like this?

https://github.com/llvm/llvm-project/pull/192902


More information about the llvm-commits mailing list