Skip to content

Commit 8117ba1

Browse files
committed
[VPlan] Return Max from computeCost without underlying instrs.
Update computeCost to return InstructionCost::getMax() for recipes without underlying instructions. Max is used as a sentinel value to handle cases where there is no underlying instruction. At the moment we need to catch those cases when -force-target-instruction-cost is passed to avoid applying the forced cost to auxiliary recipes (like scalar steps). This is needed to match the legacy behavior. Unfortunately we cannot use InstructionCost::getInvalid, as this is used to indicate that an instruction cannot be legalized (e.g. for scalable vectors). Alternatively computeCost could return an optional cost.
1 parent 6e6d5ea commit 8117ba1

File tree

2 files changed

+12
-12
lines changed

2 files changed

+12
-12
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,9 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
844844
protected:
845845
/// Compute the cost of this recipe either using a recipe's specialized
846846
/// implementation or using the legacy cost model and the underlying
847-
/// instructions.
847+
/// instructions. Returns InstructionCost::max() if the cost of this recipe
848+
/// should be ignored. Forced target instruction cost is not applied for such
849+
/// recipes.
848850
virtual InstructionCost computeCost(ElementCount VF,
849851
VPCostContext &Ctx) const;
850852
};

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,6 @@ static Instruction *getInstructionForCost(const VPRecipeBase *R) {
276276
return dyn_cast_or_null<Instruction>(S->getUnderlyingValue());
277277
if (auto *IG = dyn_cast<VPInterleaveRecipe>(R))
278278
return IG->getInsertPos();
279-
// Currently the legacy cost model only calculates the instruction cost with
280-
// underlying instruction. Removing the WidenMem here will prevent
281-
// force-target-instruction-cost overwriting the cost of recipe with
282-
// underlying instruction which is inconsistent with the legacy model.
283-
// TODO: Remove WidenMem from this function when we don't need to compare to
284-
// the legacy model.
285-
if (auto *WidenMem = dyn_cast<VPWidenMemoryRecipe>(R))
286-
return &WidenMem->getIngredient();
287279
return nullptr;
288280
}
289281

@@ -293,9 +285,13 @@ InstructionCost VPRecipeBase::cost(ElementCount VF, VPCostContext &Ctx) {
293285
return 0;
294286

295287
InstructionCost RecipeCost = computeCost(VF, Ctx);
296-
if (UI && ForceTargetInstructionCost.getNumOccurrences() > 0 &&
297-
RecipeCost.isValid())
288+
if (ForceTargetInstructionCost.getNumOccurrences() > 0 &&
289+
(RecipeCost.isValid() && RecipeCost != InstructionCost::getMax()))
298290
RecipeCost = InstructionCost(ForceTargetInstructionCost);
291+
// Max cost is used as a sentinel value to detect recipes without underlying
292+
// instructions for which no forced target instruction cost should be applied.
293+
if (RecipeCost == InstructionCost::getMax())
294+
RecipeCost = 0;
299295

300296
LLVM_DEBUG({
301297
dbgs() << "Cost of " << RecipeCost << " for VF " << VF << ": ";
@@ -315,7 +311,9 @@ InstructionCost VPRecipeBase::computeCost(ElementCount VF,
315311
// transform, avoid computing their cost multiple times for now.
316312
Ctx.SkipCostComputation.insert(UI);
317313
}
318-
return UI ? Ctx.getLegacyCost(UI, VF) : 0;
314+
// Max cost is used as a sentinel value to detect recipes without underlying
315+
// instructions for which no forced target instruction cost should be applied.
316+
return UI ? Ctx.getLegacyCost(UI, VF) : InstructionCost::getMax();
319317
}
320318

321319
FastMathFlags VPRecipeWithIRFlags::getFastMathFlags() const {

0 commit comments

Comments
 (0)