[llvm] [VectorCombine] foldShuffleOfBinops - add support for length changing shuffles (PR #88899)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 22 00:48:04 PDT 2024
================
@@ -1394,55 +1394,85 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
return true;
}
-/// Try to convert "shuffle (binop), (binop)" with a shared binop operand into
-/// "binop (shuffle), (shuffle)".
+/// Try to convert "shuffle (binop), (binop)" into "binop (shuffle), (shuffle)".
bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
- auto *VecTy = cast<FixedVectorType>(I.getType());
BinaryOperator *B0, *B1;
- ArrayRef<int> Mask;
+ ArrayRef<int> OldMask;
if (!match(&I, m_Shuffle(m_OneUse(m_BinOp(B0)), m_OneUse(m_BinOp(B1)),
- m_Mask(Mask))) ||
- B0->getOpcode() != B1->getOpcode() || B0->getType() != VecTy)
+ m_Mask(OldMask))))
return false;
- // Try to replace a binop with a shuffle if the shuffle is not costly.
- // The new shuffle will choose from a single, common operand, so it may be
- // cheaper than the existing two-operand shuffle.
- SmallVector<int> UnaryMask = createUnaryMask(Mask, Mask.size());
+ // TODO: Add support for addlike etc.
Instruction::BinaryOps Opcode = B0->getOpcode();
- InstructionCost BinopCost = TTI.getArithmeticInstrCost(Opcode, VecTy);
- InstructionCost ShufCost = TTI.getShuffleCost(
- TargetTransformInfo::SK_PermuteSingleSrc, VecTy, UnaryMask);
- if (ShufCost > BinopCost)
+ if (Opcode != B1->getOpcode())
+ return false;
+
+ auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
+ auto *BinOpTy = dyn_cast<FixedVectorType>(B0->getType());
+ if (!ShuffleDstTy || !BinOpTy)
return false;
+ unsigned NumSrcElts = BinOpTy->getNumElements();
+
// If we have something like "add X, Y" and "add Z, X", swap ops to match.
Value *X = B0->getOperand(0), *Y = B0->getOperand(1);
Value *Z = B1->getOperand(0), *W = B1->getOperand(1);
if (BinaryOperator::isCommutative(Opcode) && X != Z && Y != W)
std::swap(X, Y);
----------------
davemgreen wrote:
This arbitrary commuting of the operands might mess up existing patterns. Could it be more selective about only commuting the operands when useful?
https://github.com/llvm/llvm-project/pull/88899
More information about the llvm-commits
mailing list