Skip to content

Commit 5d30383

Browse files
committed
[LV] Check for hoisted safe-div selects in planContainsAdditionalSimp.
In some cases, safe-divisor selects can be hoisted out of the vector loop. Catching all cases in the legacy cost model isn't possible, in particular checking if all conditions guarding a division are loop invariant. Instead, check in planContainsAdditionalSimplifications if there are any hoisted safe-divisor selects. If so, don't compare to the more inaccurate legacy cost model. Fixes llvm#160354. Fixes llvm#160356. (cherry picked from commit 88aab08)
1 parent e89fd9a commit 5d30383

File tree

2 files changed

+285
-194
lines changed

2 files changed

+285
-194
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3053,15 +3053,12 @@ LoopVectorizationCostModel::getDivRemSpeculationCost(Instruction *I,
30533053

30543054
InstructionCost SafeDivisorCost = 0;
30553055
auto *VecTy = toVectorTy(I->getType(), VF);
3056-
auto *DivisorI = dyn_cast<Instruction>(I->getOperand(1));
3057-
if (DivisorI && !Legal->isInvariant(DivisorI)) {
3058-
// The cost of the select guard to ensure all lanes are well defined
3059-
// after we speculate above any internal control flow.
3060-
SafeDivisorCost +=
3061-
TTI.getCmpSelInstrCost(Instruction::Select, VecTy,
3062-
toVectorTy(Type::getInt1Ty(I->getContext()), VF),
3063-
CmpInst::BAD_ICMP_PREDICATE, CostKind);
3064-
}
3056+
// The cost of the select guard to ensure all lanes are well defined
3057+
// after we speculate above any internal control flow.
3058+
SafeDivisorCost +=
3059+
TTI.getCmpSelInstrCost(Instruction::Select, VecTy,
3060+
toVectorTy(Type::getInt1Ty(I->getContext()), VF),
3061+
CmpInst::BAD_ICMP_PREDICATE, CostKind);
30653062

30663063
SmallVector<const Value *, 4> Operands(I->operand_values());
30673064
SafeDivisorCost += TTI.getArithmeticInstrCost(
@@ -6932,6 +6929,28 @@ static bool planContainsAdditionalSimplifications(VPlan &Plan,
69326929
return nullptr;
69336930
};
69346931

6932+
// Check if a select for a safe divisor was hoisted to the pre-header. If so,
6933+
// the select doesn't need to be considered for the vector loop cost; go with
6934+
// the more accurate VPlan-based cost model.
6935+
for (VPRecipeBase &R : *Plan.getVectorPreheader()) {
6936+
auto *VPI = dyn_cast<VPInstruction>(&R);
6937+
if (!VPI || VPI->getOpcode() != Instruction::Select ||
6938+
VPI->getNumUsers() != 1)
6939+
continue;
6940+
6941+
if (auto *WR = dyn_cast<VPWidenRecipe>(*VPI->user_begin())) {
6942+
switch (WR->getOpcode()) {
6943+
case Instruction::UDiv:
6944+
case Instruction::SDiv:
6945+
case Instruction::URem:
6946+
case Instruction::SRem:
6947+
return true;
6948+
default:
6949+
break;
6950+
}
6951+
}
6952+
}
6953+
69356954
DenseSet<Instruction *> SeenInstrs;
69366955
auto Iter = vp_depth_first_deep(Plan.getVectorLoopRegion()->getEntry());
69376956
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(Iter)) {

0 commit comments

Comments
 (0)