[llvm] [VPlan] Model first memory runtime checks as VPlan recipes. (PR #221483)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 06:50:30 PDT 2026
================
@@ -1541,13 +1494,55 @@ void VPlanTransforms::attachCheckBlock(VPlan &Plan, Value *Cond,
attachVPCheckBlock(Plan, CondVPV, CheckBlockVPBB, AddBranchWeights);
}
+void VPlanTransforms::addMemoryRuntimeChecks(
+ VPlan &Plan, ArrayRef<RuntimePointerCheck> Checks, ScalarEvolution &SE,
+ DebugLoc DL, bool AddBranchWeights) {
+ assert(!Checks.empty() && "no checks to replace the pre-built block with");
+
+ auto *MemCheckVPBB = Plan.createVPBasicBlock("vector.memcheck");
+ VPBuilder Builder(MemCheckVPBB);
+ insertCheckBlockBeforeVectorLoop(Plan, MemCheckVPBB);
+ VPSCEVExpander Expander(Builder, SE, DL);
+
+ // Expand each group's bounds once and up front.
+ SmallDenseMap<const RuntimeCheckingPtrGroup *,
+ std::pair<VPValue *, VPValue *>>
+ GroupToBounds;
+ for (const auto &[A, B] : Checks)
+ for (const RuntimeCheckingPtrGroup *CG : {A, B}) {
+ if (GroupToBounds.contains(CG))
+ continue;
+ VPValue *Start = Expander.expand(CG->Low);
+ VPValue *End = Expander.expand(CG->High);
+ if (CG->NeedsFreeze) {
+ Start = Builder.createFreeze(Start, DL);
+ End = Builder.createFreeze(End, DL);
+ }
+ GroupToBounds.try_emplace(CG, Start, End);
+ }
+
+ VPValue *Cond = nullptr;
+ for (const auto &[A, B] : Checks) {
+ auto [AStart, AEnd] = GroupToBounds.at(A);
+ auto [BStart, BEnd] = GroupToBounds.at(B);
+ VPValue *Bound0 =
+ Builder.createICmp(CmpInst::ICMP_ULT, AStart, BEnd, DL, "bound0");
+ VPValue *Bound1 =
+ Builder.createICmp(CmpInst::ICMP_ULT, BStart, AEnd, DL, "bound1");
+ VPValue *IsConflict =
+ Builder.createAnd(Bound0, Bound1, DL, "found.conflict");
+ Cond = Cond ? Builder.createOr(Cond, IsConflict, DL, "conflict.rdx")
+ : IsConflict;
----------------
fhahn wrote:
updated, thanks
https://github.com/llvm/llvm-project/pull/221483
More information about the llvm-commits
mailing list