[llvm] [InstCombine] Fold umax/umin with NUW-shifted operand and constant (PR #193959)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 24 09:51:08 PDT 2026


================
@@ -1775,6 +1775,54 @@ static bool rightDistributesOverLeft(Instruction::BinaryOps LOp, bool HasNUW,
   }
 }
 
+/// Folds a min/max intrinsic when one operand is a NUW shift-by-constant.
+///
+/// Handles patterns like:
+///   umax(x << K, C) --> umax(x, C >> K) << K
+static Value *foldMinMaxWithShiftedOperand(IntrinsicInst *MinMax,
+                                           InstCombiner::BuilderTy &Builder) {
+  Intrinsic::ID IID = MinMax->getIntrinsicID();
+  if (IID != Intrinsic::umax && IID != Intrinsic::umin)
+    return nullptr;
+
+  Value *LHS = MinMax->getOperand(0), *RHS = MinMax->getOperand(1);
+
+  const APInt *ConstOperand;
+  BinaryOperator *BinOp;
+
+  bool Matched =
+      (match(LHS, m_BinOp(BinOp)) && match(RHS, m_APInt(ConstOperand))) ||
+      (match(RHS, m_BinOp(BinOp)) && match(LHS, m_APInt(ConstOperand)));
+
+  if (!Matched)
+    return nullptr;
+
+  if (!BinOp->hasOneUse())
+    return nullptr;
+
+  if (BinOp->getOpcode() != Instruction::Shl || !BinOp->hasNoUnsignedWrap())
+    return nullptr;
+
+  Value *ShiftBase = BinOp->getOperand(0);
+  Value *ShiftAmount = BinOp->getOperand(1);
+
+  const APInt *ShiftAmountConst;
+  if (!match(ShiftAmount, m_APInt(ShiftAmountConst)))
+    return nullptr;
+
+  uint64_t K = ShiftAmountConst->getZExtValue();
+  if (ConstOperand->countTrailingZeros() < K)
+    return nullptr;
+
+  APInt HoistedConst = ConstOperand->lshr(K);
+  Value *NewConstant = ConstantInt::get(MinMax->getType(), HoistedConst);
+
+  Value *NarrowedMinMax =
+      Builder.CreateBinaryIntrinsic(IID, ShiftBase, NewConstant);
+
+  return Builder.CreateShl(NarrowedMinMax, ShiftAmount, "", /*NUW=*/true);
----------------
dtcxzyw wrote:

Use `BinaryOperator::CreateNUWShl` and return `Instruction *`.


https://github.com/llvm/llvm-project/pull/193959


More information about the llvm-commits mailing list