[llvm] [VPlan] Wrap SCEVAddRecExprs in VPExpandSCEVRecipe in VPSCEVExpander. (PR #210013)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 06:09:29 PDT 2026
================
@@ -873,22 +876,37 @@ VPValue *VPSCEVExpander::tryToExpand(const SCEV *S) {
llvm_unreachable("Unexpected min/max SCEV type");
}
// Chain operands in reverse order matching SCEVExpander's expansion of
- // min/max expressions.
- SmallVector<VPValue *, 2> Ops;
- for (const SCEVUse &Op : reverse(MinMax->operands())) {
- VPValue *OpV = tryToExpand(Op);
- if (!OpV)
- return nullptr;
- Ops.push_back(OpV);
- }
+ // min/max expressions. In SafeUDivMode freeze expansion results of operands
+ // other than the first for sequential UMins, to avoid short-circuiting
+ // divide-by-0/poison.
+ bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
Type *ResultTy = MinMax->getType();
- VPValue *Result = Ops.front();
- for (VPValue *Op : drop_begin(Ops))
- Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
- ResultTy, DL);
+ bool PrevSafeMode = SafeUDivMode;
+ VPValue *Result = nullptr;
+ for (const auto &[I, SCEVOp] : enumerate(reverse(MinMax->operands()))) {
+ bool MayShortCircuit = IsSequential && I != MinMax->getNumOperands() - 1;
+ SafeUDivMode = MayShortCircuit || PrevSafeMode;
+ VPValue *Op = expand(SCEVOp);
+ SafeUDivMode = PrevSafeMode;
+ if (MayShortCircuit)
+ Op = Builder.createScalarFreeze(Op, ResultTy, DL);
+ Result = Result ? Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
+ ResultTy, DL)
+ : Op;
+ }
return Result;
}
- default:
- return nullptr;
+ case scAddRecExpr: {
+ [[maybe_unused]] BasicBlock *PH =
+ cast<VPIRBasicBlock>(Builder.getPlan().getEntry())->getIRBasicBlock();
+ assert(
+ SE.DT.dominates(cast<SCEVAddRecExpr>(S)->getLoop()->getHeader(), PH) &&
+ "can only expand AddRecs for loops outside VPlan's scope");
+ // AddRecs outside VPlan's scope must be expanded via VPExpandSCEV.
----------------
artagnon wrote:
In fact, if the AR's loop header refers to a BasicBlock that's completely absent in the Plan, there would be no point expanding it, as the expansion would target a BasicBlock that we don't emit (we only ever execute the Plan?).
https://github.com/llvm/llvm-project/pull/210013
More information about the llvm-commits
mailing list