[llvm] [InstCombine] Fold Minimum over Trailing/Leading Bits Counts (PR #90402)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 29 03:51:40 PDT 2024
================
@@ -1428,6 +1428,46 @@ static Instruction *foldBitOrderCrossLogicOp(Value *V,
return nullptr;
}
+/// Fold an unsigned minimum of trailing or leading zero bits counts:
+/// umin(cttz(CtOp, ZeroUndef), ConstOp) --> cttz(CtOp | (1 << ConstOp))
+/// umin(ctlz(CtOp, ZeroUndef), ConstOp) --> ctlz(CtOp | ((1 << (bitwidth-1))
+/// >> ConstOp))
+static Value *
+foldMinimumOverTrailingOrLeadingZeroCount(Intrinsic::ID IntrID, Value *I0,
+ Value *I1, const DataLayout &DL,
+ InstCombiner::BuilderTy &Builder) {
+ assert((IntrID == Intrinsic::cttz || IntrID == Intrinsic::ctlz) &&
+ "This helper only supports cttz and ctlz intrinsics");
+
+ if (I0->hasOneUse()) {
+ if (auto *II0 = dyn_cast<IntrinsicInst>(I0);
+ II0 && II0->getIntrinsicID() == IntrID) {
+ Value *X = II0->getArgOperand(0);
+ Value *Z = II0->getArgOperand(1);
+
+ auto BitWidth = I1->getType()->getScalarSizeInBits();
+ auto *Ty = I1->getType();
+
+ auto LessBitWidth = [BitWidth](auto &C) { return C.ult(BitWidth); };
+ if (match(I1, m_CheckedInt(LessBitWidth))) {
+ Constant *NewConst = ConstantFoldBinaryOpOperands(
+ IntrID == Intrinsic::cttz ? Instruction::Shl : Instruction::LShr,
+ IntrID == Intrinsic::cttz
+ ? ConstantInt::get(Ty, 1)
+ : ConstantInt::get(Ty, APInt::getSignedMinValue(BitWidth)),
+ cast<Constant>(I1), DL);
+ return Builder.CreateBinaryIntrinsic(IntrID,
+ Builder.CreateOr(X, NewConst), Z);
+ }
+ if (match(I1, m_CheckedInt(std::not_fn(LessBitWidth)))) {
+ return I0;
+ }
----------------
mskamp wrote:
I've removed the handling for constants >= BitWidth. Since I agree that this case is probably never encountered, it's not worth the effort to maintain this.
https://github.com/llvm/llvm-project/pull/90402
More information about the llvm-commits
mailing list