[llvm] [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 09:48:28 PDT 2024
================
@@ -1400,6 +1401,100 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
return true;
}
+/// Try to convert "shuffle (binop (shuffle, shuffle)), undef"
+/// --> "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 (BinOp->isIntDivRem() && llvm::is_contained(OuterMask, PoisonMaskElem))
+ 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 in
+ // div/rem..
+ if (BinOp->isIntDivRem() &&
+ any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
----------------
RKSimon wrote:
This will prevent the folds for DivRem with both Undef/Poison - using the m_Undef() match in the m_Shuffle() above - is that not enough?
https://github.com/llvm/llvm-project/pull/114101
More information about the llvm-commits
mailing list