[llvm] [WIP][VectorCombine] Fold "shuffle (binop (shuffle, shuffle)), undef" --> "binop (shuffle), (shuffle)" (PR #114101)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 06:03:22 PDT 2024
================
@@ -1400,6 +1401,92 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
return true;
}
+/// Try to fold "shuffle (binop (shuffle, shuffle)), undef" into "binop (shuffle), (shuffle)".
+bool VectorCombine::foldPermuteOfBinops(Instruction &I) {
+ BinaryOperator *BinOp;
+ ArrayRef<int> OuterMask;
+ if (!match(&I,
+ m_Shuffle(m_OneUse(m_BinOp(BinOp)), m_Undef(), m_Mask(OuterMask))))
+ return false;
+
+ // Don't introduce poison into div/rem.
+ if (llvm::is_contained(OuterMask, PoisonMaskElem) && BinOp->isIntDivRem())
+ return false;
+
+ Value *Op00, *Op01;
+ ArrayRef<int> Mask0;
+ if (!match(BinOp->getOperand(0),
+ m_OneUse(m_Shuffle(m_Value(Op00), m_Value(Op01), m_Mask(Mask0)))))
+ return false;
+
+ Value *Op10, *Op11;
+ ArrayRef<int> Mask1;
+ if (!match(BinOp->getOperand(1),
+ m_OneUse(m_Shuffle(m_Value(Op10), m_Value(Op11), m_Mask(Mask1)))))
+ return false;
+
+ Instruction::BinaryOps Opcode = BinOp->getOpcode();
+ auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
+ auto *BinOpTy = dyn_cast<FixedVectorType>(BinOp->getType());
+ auto *Op0Ty = dyn_cast<FixedVectorType>(Op00->getType());
+ auto *Op1Ty = dyn_cast<FixedVectorType>(Op10->getType());
+ if (!ShuffleDstTy || !BinOpTy || !Op0Ty || !Op1Ty)
+ return false;
+
+ unsigned NumSrcElts = BinOpTy->getNumElements();
+
+ // Don't accept shuffles that reference the second (undef/poison) operand.
+ if (any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
----------------
RKSimon wrote:
Yes, we can enable this for non-intdiv cases
https://github.com/llvm/llvm-project/pull/114101
More information about the llvm-commits
mailing list