Skip to content

Commit b43e6f9

Browse files
committed
Fixup! consider VPInterleaveRecipe, VPReplicateRecipe, Live-in/out
1 parent 8a8462e commit b43e6f9

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,10 +1468,9 @@ InstructionCost VPWidenCastRecipe::computeCost(ElementCount VF,
14681468
ToVectorTy(Ctx.Types.inferScalarType(getOperand(0)), VF));
14691469
auto *DestTy = cast<VectorType>(ToVectorTy(getResultType(), VF));
14701470
// Computes the CastContextHint from a VPWidenMemoryRecipe instruction.
1471-
auto ComputeCCH = [&](VPWidenMemoryRecipe *R) -> TTI::CastContextHint {
1471+
auto ComputeCCH = [&](const VPWidenMemoryRecipe *R) -> TTI::CastContextHint {
14721472
assert((isa<VPWidenLoadRecipe>(R) || isa<VPWidenStoreRecipe>(R)) &&
14731473
"Expected a load or a store!");
1474-
14751474
if (VF.isScalar())
14761475
return TTI::CastContextHint::Normal;
14771476
if (!R->isConsecutive())
@@ -1485,19 +1484,31 @@ InstructionCost VPWidenCastRecipe::computeCost(ElementCount VF,
14851484

14861485
TTI::CastContextHint CCH = TTI::CastContextHint::None;
14871486
// For Trunc, the context is the only user, which must be a
1488-
// VPWidenStoreRecipe.
1489-
if (Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) {
1490-
if (!cast<VPValue>(this)->hasMoreThanOneUniqueUser())
1491-
if (VPWidenMemoryRecipe *Store =
1492-
dyn_cast<VPWidenMemoryRecipe>(*this->user_begin()))
1493-
CCH = ComputeCCH(Store);
1494-
}
1495-
// For Z/Sext, the context is the operand, which must be a VPWidenLoadRecipe.
1487+
// VPWidenStoreRecipe, a VPInterleaveRecipe ,a VPReplicateRecipe or a live-out
1488+
// value.
1489+
if ((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&
1490+
!hasMoreThanOneUniqueUser() && getNumUsers() > 0) {
1491+
auto *StoreRecipe = dyn_cast<VPRecipeBase>(*user_begin());
1492+
if (isa<VPLiveOut>(*user_begin()) || isa<VPReplicateRecipe>(StoreRecipe))
1493+
CCH = TTI::CastContextHint::Normal;
1494+
else if (const VPWidenMemoryRecipe *MemoryStoreRecipe =
1495+
dyn_cast<VPWidenMemoryRecipe>(StoreRecipe))
1496+
CCH = ComputeCCH(MemoryStoreRecipe);
1497+
else if (isa<VPInterleaveRecipe>(StoreRecipe))
1498+
CCH = TTI::CastContextHint::Interleave;
1499+
}
1500+
// For Z/Sext, the context is the operand, which must be a VPWidenLoadRecipe,
1501+
// a VPInterleaveRecipe, a VPReplicateRecipe or a live-in value.
14961502
else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt ||
14971503
Opcode == Instruction::FPExt) {
1498-
if (VPWidenMemoryRecipe *Load = dyn_cast<VPWidenMemoryRecipe>(
1499-
this->getOperand(0)->getDefiningRecipe()))
1500-
CCH = ComputeCCH(Load);
1504+
const VPRecipeBase *LoadRecipe = getOperand(0)->getDefiningRecipe();
1505+
if (getOperand(0)->isLiveIn() || isa<VPReplicateRecipe>(LoadRecipe))
1506+
CCH = TTI::CastContextHint::Normal;
1507+
else if (const VPWidenMemoryRecipe *MemoryLoadRecipe =
1508+
dyn_cast<VPWidenMemoryRecipe>(LoadRecipe))
1509+
CCH = ComputeCCH(MemoryLoadRecipe);
1510+
else if (isa<VPInterleaveRecipe>(LoadRecipe))
1511+
CCH = TTI::CastContextHint::Interleave;
15011512
}
15021513
// Arm TTI will use the underlying instruction to determine the cost.
15031514
return Ctx.TTI.getCastInstrCost(

0 commit comments

Comments
 (0)