[llvm] [ValueTracking] Add support for most `llvm.vector.reduce.*` ops. (PR #88320)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 11 02:21:38 PDT 2024
================
@@ -2904,6 +2942,41 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
case Intrinsic::vector_reduce_smax:
case Intrinsic::vector_reduce_smin:
return isKnownNonZero(II->getArgOperand(0), Depth, Q);
+ // If we know the reduction doesn't overflow and all elements are
+ // non-zero, the reduction is non-zero.
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_add:
+ if (computeKnownBits(I, Depth + 1, Q).isNonZero())
+ return true;
+
+ if (auto *VecTy =
+ dyn_cast<FixedVectorType>(I->getOperand(0)->getType())) {
+ bool Overflow;
+ if (II->getIntrinsicID() == Intrinsic::vector_reduce_add) {
+ APInt NumEle(BitWidth, VecTy->getNumElements());
+ // If we can't store num ele in bitwidth, the result is either
+ // known-zero or we won't get anything useful.
+ if (NumEle.getZExtValue() != VecTy->getNumElements())
+ break;
+ APInt MaxVal =
+ computeKnownBits(II->getArgOperand(0), Depth, Q).getMaxValue();
+ MaxVal = MaxVal.umul_ov(NumEle, Overflow);
+ } else {
+ APInt MaxVal =
+ computeKnownBits(II->getArgOperand(0), Depth, Q).getMaxValue();
+ APInt SingleVal = MaxVal;
+ for (unsigned i = 1, e = VecTy->getNumElements(); i < e; ++i) {
+ MaxVal = MaxVal.umul_ov(SingleVal, Overflow);
+ if (Overflow)
+ break;
+ }
+ }
+
+ if (Overflow)
+ break;
+ return isKnownNonZero(II->getArgOperand(0), Depth, Q);
+ }
+ break;
----------------
nikic wrote:
Yeah, I don't think this is worthwhile.
https://github.com/llvm/llvm-project/pull/88320
More information about the llvm-commits
mailing list