[llvm] [VectorCombine] Allow shuffling between vectors the same type but different element sizes (PR #121216)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 29 07:34:32 PST 2025
================
@@ -3067,42 +3067,73 @@ bool VectorCombine::foldInsExtVectorToShuffle(Instruction &I) {
m_ConstantInt(InsIdx))))
return false;
- auto *VecTy = dyn_cast<FixedVectorType>(I.getType());
- if (!VecTy || SrcVec->getType() != VecTy)
+ auto *DstVecTy = dyn_cast<FixedVectorType>(I.getType());
+ auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
+ // We can try combining vectors with different element sizes.
+ if (!DstVecTy || !SrcVecTy ||
+ SrcVecTy->getElementType() != DstVecTy->getElementType())
return false;
- unsigned NumElts = VecTy->getNumElements();
- if (ExtIdx >= NumElts || InsIdx >= NumElts)
+ unsigned NumDstElts = DstVecTy->getNumElements();
+ unsigned NumSrcElts = SrcVecTy->getNumElements();
+ if (InsIdx >= NumDstElts || ExtIdx >= NumSrcElts || NumDstElts == 1)
return false;
// Insertion into poison is a cheaper single operand shuffle.
TargetTransformInfo::ShuffleKind SK;
- SmallVector<int> Mask(NumElts, PoisonMaskElem);
- if (isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec)) {
+ SmallVector<int> Mask(NumDstElts, PoisonMaskElem);
+
+ bool NeedExpOrNarrow = NumSrcElts != NumDstElts;
+ bool IsExtIdxInBounds = ExtIdx < NumDstElts;
+ bool NeedDstSrcSwap = isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec);
+ if (NeedDstSrcSwap) {
SK = TargetTransformInfo::SK_PermuteSingleSrc;
- Mask[InsIdx] = ExtIdx;
+ if (!IsExtIdxInBounds && NeedExpOrNarrow)
+ Mask[InsIdx] = 0;
+ else
+ Mask[InsIdx] = ExtIdx;
std::swap(DstVec, SrcVec);
} else {
SK = TargetTransformInfo::SK_PermuteTwoSrc;
std::iota(Mask.begin(), Mask.end(), 0);
- Mask[InsIdx] = ExtIdx + NumElts;
+ if (!IsExtIdxInBounds && NeedExpOrNarrow)
+ Mask[InsIdx] = NumDstElts;
+ else
+ Mask[InsIdx] = ExtIdx + NumDstElts;
}
// Cost
auto *Ins = cast<InsertElementInst>(&I);
auto *Ext = cast<ExtractElementInst>(I.getOperand(1));
InstructionCost InsCost =
- TTI.getVectorInstrCost(*Ins, VecTy, CostKind, InsIdx);
+ TTI.getVectorInstrCost(*Ins, DstVecTy, CostKind, InsIdx);
InstructionCost ExtCost =
- TTI.getVectorInstrCost(*Ext, VecTy, CostKind, ExtIdx);
+ TTI.getVectorInstrCost(*Ext, DstVecTy, CostKind, ExtIdx);
InstructionCost OldCost = ExtCost + InsCost;
- // Ignore 'free' identity insertion shuffle.
- // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
InstructionCost NewCost = 0;
- if (!ShuffleVectorInst::isIdentityMask(Mask, NumElts))
- NewCost += TTI.getShuffleCost(SK, VecTy, Mask, CostKind, 0, nullptr,
- {DstVec, SrcVec});
+ SmallVector<int> ExtToVecMask;
+ if (!NeedExpOrNarrow) {
+ // Ignore 'free' identity insertion shuffle.
+ // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
+ if (!ShuffleVectorInst::isIdentityMask(Mask, NumDstElts))
----------------
RKSimon wrote:
You need NumSrcElts here isIdentityMask needs to be told the src element count (it knows the dst count from Mask.size())
https://github.com/llvm/llvm-project/pull/121216
More information about the llvm-commits
mailing list