[llvm] [InstCombine] Match intrinsic recurrences when known to be hoisted (PR #149858)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 22 07:01:31 PDT 2025


================
@@ -1532,6 +1532,46 @@ static Instruction *foldBitOrderCrossLogicOp(Value *V,
   return nullptr;
 }
 
+static bool foldBinaryIntrinsicRecurrence(InstCombinerImpl &IC,
+                                          IntrinsicInst *II) {
+  PHINode *PN;
+  Value *Init, *OtherOp;
+
+  // A binary intrinsic recurrence with loop-invariant operands is equivalent to
+  // `call @llvm.binary.intrinsic(Init, OtherOp)`.
+  if (!matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp) ||
+      isa<Constant>(OtherOp) || !PN->hasOneUse() ||
+      !IC.getDominatorTree().dominates(OtherOp, PN))
+    return false;
+
+  auto IID = II->getIntrinsicID();
+  switch (IID) {
+  case Intrinsic::maxnum:
+  case Intrinsic::minnum:
+  case Intrinsic::maximum:
+  case Intrinsic::minimum:
+  case Intrinsic::maximumnum:
+  case Intrinsic::minimumnum:
+  case Intrinsic::smax:
+  case Intrinsic::smin:
+  case Intrinsic::umax:
+  case Intrinsic::umin:
+    break;
+  default:
+    return false;
+  }
+
+  IC.Builder.SetInsertPoint(&*PN->getParent()->getFirstInsertionPt());
+  auto *InvariantBinaryInst =
+      cast<IntrinsicInst>(IC.Builder.CreateBinaryIntrinsic(IID, Init, OtherOp));
+  if (isa<FPMathOperator>(II))
+    InvariantBinaryInst->copyFastMathFlags(II);
+  InvariantBinaryInst->takeName(II);
+  IC.eraseInstFromFunction(*IC.replaceInstUsesWith(*II, InvariantBinaryInst));
+  IC.eraseInstFromFunction(*PN);
----------------
nikic wrote:

I don't think you need to manually erase any instructions?

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


More information about the llvm-commits mailing list