[llvm] [VectorCombine] Fold binary op of reductions. (PR #121567)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 29 07:59:18 PST 2025
================
@@ -1182,6 +1189,62 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
return true;
}
+bool VectorCombine::foldBinopOfReductions(Instruction &I) {
+ Instruction::BinaryOps BinOpOpc = cast<BinaryOperator>(&I)->getOpcode();
+ Intrinsic::ID ReductionIID = getReductionForBinop(BinOpOpc);
+ if (BinOpOpc == Instruction::Sub)
+ ReductionIID = Intrinsic::vector_reduce_add;
+ if (ReductionIID == Intrinsic::not_intrinsic)
+ return false;
+
+ auto checkIntrinsicAndGetItsArgument = [](Value *V,
+ Intrinsic::ID IID) -> Value * {
+ IntrinsicInst *II = dyn_cast<IntrinsicInst>(V);
+ if (!II)
+ return nullptr;
+ if (II->getIntrinsicID() == IID && II->hasOneUse())
+ return II->getArgOperand(0);
+ return nullptr;
+ };
+
+ Value *V0 = checkIntrinsicAndGetItsArgument(I.getOperand(0), ReductionIID);
+ if (!V0)
+ return false;
+ Value *V1 = checkIntrinsicAndGetItsArgument(I.getOperand(1), ReductionIID);
+ if (!V1)
+ return false;
+
+ VectorType *VTy = cast<VectorType>(V0->getType());
+ if (V1->getType() != VTy)
+ return false;
+
+ InstructionCost ReductionCost =
+ TTI.getArithmeticReductionCost(BinOpOpc, VTy, std::nullopt, CostKind);
+ InstructionCost OldCost =
+ 2 * ReductionCost + TTI.getInstructionCost(&I, CostKind);
+ Value *VectorBO = Builder.CreateBinOp(BinOpOpc, V0, V1);
+ Instruction *VectorBOInst = dyn_cast<Instruction>(VectorBO);
+ if (!VectorBOInst)
+ // Both V0 and V1 are constant?
+ return false;
+
+ InstructionCost ReduceResOfVecBinopCost =
+ ReductionCost + TTI.getInstructionCost(VectorBOInst, CostKind);
----------------
RKSimon wrote:
Use TTI.getArithmeticInstrCost
https://github.com/llvm/llvm-project/pull/121567
More information about the llvm-commits
mailing list