[llvm] [LV] Implement integer part of VPDerivedIV cost model (PR #198252)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Wed May 20 06:02:42 PDT 2026
================
@@ -2620,6 +2641,84 @@ bool VPWidenIntOrFpInductionRecipe::isCanonical() const {
getScalarType() == getRegion()->getCanonicalIVType();
}
+InstructionCost VPDerivedIVRecipe::computeCost(ElementCount VF,
+ VPCostContext &Ctx) const {
+ // The cost model for this is modelled on expandVPDerivedIV in
+ // VPlanTransforms.cpp. In order to avoid overly pessimistic costs that can
+ // negatively affect vectorization it takes into account any expected
+ // simplifications that happen in simplifyRecipe.
+ switch (getInductionKind()) {
+ default:
+ // TODO: Compute cost for remaining kinds.
+ break;
+ case InductionDescriptor::IK_IntInduction: {
+ // There are currently no tests that expose a path where all lanes are
+ // used, so it's better to bail out for now.
+ if (!vputils::onlyFirstLaneUsed(this))
+ break;
+
+ // Start off by assuming we need both mul and add, then refine this.
+ bool NeedsMul = true, NeedsAdd = true;
+
+ // If the start value is zero the add gets folded away.
+ if (auto *VPV = dyn_cast<VPIRValue>(getStartValue()))
+ if (auto *StartC = dyn_cast<ConstantInt>(VPV->getValue()))
+ NeedsAdd = !StartC->isZero();
+
+ // For some values of step the arithmetic changes:
+ // 1. A step of 1 requires no operation.
+ // 2. A step of -1 requires a negate.
+ // 3. A power-of-2 step will use a shl, instead of a mul.
+ Type *StepTy = Ctx.Types.inferScalarType(getStepValue());
+ InstructionCost Cost(0);
+ if (auto *VPV = dyn_cast<VPIRValue>(getStepValue())) {
+ if (auto *StepC = dyn_cast<ConstantInt>(VPV->getValue())) {
+ if (StepC->isOne())
+ NeedsMul = false;
+ else if (StepC->isMinusOne()) {
+ // This will most likely end up as a negate in simplifyRecipe, and
+ // the negate will be combined with the add to make a sub.
+ // NOTE: This is perhaps an invalid assumption that the cost of an
+ // 'add' is the same as a 'sub'.
+ NeedsMul = false;
+ NeedsAdd = true;
+ } else if (StepC->getValue().isPowerOf2()) {
+ // This will most likely end up as a shift-left in simplifyRecipe
+ NeedsMul = false;
+ Cost += Ctx.TTI.getArithmeticInstrCost(
+ Instruction::Shl, StepTy, Ctx.CostKind,
+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
+ {TargetTransformInfo::OK_UniformConstantValue,
+ TargetTransformInfo::OP_PowerOf2});
+ }
+ }
+ }
+
+ // Add the cost of the conversion from index to step type if the index
+ // will be used.
+ Type *IndexTy = Ctx.Types.inferScalarType(getIndex());
+ unsigned StepTySize = StepTy->getScalarSizeInBits();
+ unsigned IndexTySize = IndexTy->getScalarSizeInBits();
+ if ((NeedsAdd || NeedsMul) && StepTySize != IndexTySize) {
+ unsigned CastOpc =
+ StepTySize < IndexTySize ? Instruction::Trunc : Instruction::SExt;
+ Cost += Ctx.TTI.getCastInstrCost(
+ CastOpc, StepTy, IndexTy, TTI::CastContextHint::None, Ctx.CostKind);
+ }
+
+ if (NeedsAdd)
+ Cost += Ctx.TTI.getArithmeticInstrCost(Instruction::Add, StepTy,
+ Ctx.CostKind);
----------------
paulwalker-arm wrote:
Pedantic I know but this should be after `NeedsMul` to match the order of operations in `expandVPDerivedIV()`.
https://github.com/llvm/llvm-project/pull/198252
More information about the llvm-commits
mailing list