@@ -10193,10 +10193,38 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
10193
10193
return VecCost;
10194
10194
};
10195
10195
if (SLPReVec && !E->isAltShuffle())
10196
- return GetCostDiff(GetScalarCost, [&](InstructionCost) {
10197
- return ::getShuffleCost(*TTI, TargetTransformInfo::SK_PermuteSingleSrc,
10198
- VecTy, calculateShufflevectorMask(E->Scalars));
10199
- });
10196
+ return GetCostDiff(
10197
+ GetScalarCost, [&](InstructionCost) -> InstructionCost {
10198
+ // If a group uses mask in order, the shufflevector can be
10199
+ // eliminated by instcombine. Then the cost is 0.
10200
+ bool IsIdentity = true;
10201
+ auto *SV = cast<ShuffleVectorInst>(VL.front());
10202
+ unsigned SVNumElements =
10203
+ cast<FixedVectorType>(SV->getOperand(0)->getType())
10204
+ ->getNumElements();
10205
+ unsigned GroupSize = SVNumElements / SV->getShuffleMask().size();
10206
+ for (size_t I = 0, E = VL.size(); I != E; I += GroupSize) {
10207
+ ArrayRef<Value *> Group = VL.slice(I, GroupSize);
10208
+ SmallVector<int> ExtractionIndex(SVNumElements);
10209
+ for_each(Group, [&](Value *V) {
10210
+ auto *SV = cast<ShuffleVectorInst>(V);
10211
+ int Index;
10212
+ SV->isExtractSubvectorMask(Index);
10213
+ for (int I :
10214
+ seq<int>(Index, Index + SV->getShuffleMask().size()))
10215
+ ExtractionIndex.push_back(I);
10216
+ });
10217
+ if (!is_sorted(ExtractionIndex)) {
10218
+ IsIdentity = false;
10219
+ break;
10220
+ }
10221
+ }
10222
+ return IsIdentity
10223
+ ? TTI::TCC_Free
10224
+ : ::getShuffleCost(
10225
+ *TTI, TargetTransformInfo::SK_PermuteSingleSrc,
10226
+ VecTy, calculateShufflevectorMask(E->Scalars));
10227
+ });
10200
10228
return GetCostDiff(GetScalarCost, GetVectorCost);
10201
10229
}
10202
10230
case Instruction::Freeze:
0 commit comments