[llvm] [SLP] Vectorize zero-tested OR/UMax reductions (PR #205473)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 27 05:03:28 PDT 2026
================
@@ -28744,6 +28757,159 @@ class HorizontalReduction {
(match(I, m_LogicalAnd()) || match(I, m_LogicalOr()));
}
+ /// Match an OR/UMax reduction whose only use is an equality compare against
+ /// zero, for example:
+ /// %r = call iN @llvm.vector.reduce.or/umax(...)
+ /// %c = icmp eq/ne iN %r, 0
+ ///
+ /// this is an all-zero / any-nonzero test of the reduced input lanes.
+ std::optional<ReductionZeroTestInfo> matchReductionZeroTestUse() const {
+ auto *Root = dyn_cast<Instruction>(ReductionRoot);
+ if (!Root || !Root->getType()->isIntegerTy() || !Root->hasOneUse() ||
+ (RdxKind != RecurKind::Or && RdxKind != RecurKind::UMax))
+ return std::nullopt;
+
+ auto *Cmp = dyn_cast<ICmpInst>(*Root->user_begin());
+ CmpPredicate Pred;
+ if (!Cmp || !match(Cmp, m_c_ICmp(Pred, m_Specific(Root), m_ZeroInt())) ||
+ !ICmpInst::isEquality(Pred))
+ return std::nullopt;
+
+ return ReductionZeroTestInfo{Cmp, Pred};
+ }
+
+ /// Cost the boolean-vector form of a reduction zero-test:
+ /// %cmp = icmp eq/ne <N x Ty> %v, zeroinitializer
+ /// %r = call i1 @llvm.vector.reduce.and/or.vNi1(%cmp)
+ ///
+ /// `eq` uses reduce.and for an all-zero test, while `ne` uses reduce.or for
+ /// an any-nonzero test.
+ static InstructionCost
+ getBoolReductionZeroTestCost(const TargetTransformInfo &TTI,
+ FixedVectorType *VecTy, CmpPredicate Pred,
+ TTI::TargetCostKind CostKind) {
+ auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
+ unsigned ReductionOpcode =
+ Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
----------------
alexey-bataev wrote:
Weak check, need to check explcitily for ICmpInst::ICMP_NE
https://github.com/llvm/llvm-project/pull/205473
More information about the llvm-commits
mailing list