[llvm] [LLVM][InstSimplify] Refactor simplifyBinaryIntrinsic to remove Call operand. (PR #196309)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 05:57:26 PDT 2026


https://github.com/paulwalker-arm created https://github.com/llvm/llvm-project/pull/196309

I picked this up from https://github.com/llvm/llvm-project/pull/194825#issuecomment-4343487394 because I have a low priority thread where I'm trying to simplify/reduce the uses of vscale_range.

>From 9612a532740c4c9657f08f5d032a69bb0ebf8082 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 6 May 2026 11:59:27 +0100
Subject: [PATCH] [LLVM][InstSimplify] Refactor simplifyBinaryIntrinsic to
 remove Call operand.

---
 .../llvm/Analysis/InstSimplifyFolder.h        |  4 +--
 .../llvm/Analysis/InstructionSimplify.h       |  3 +-
 llvm/lib/Analysis/InstructionSimplify.cpp     | 31 ++++++++++---------
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
index 2832beb9e337c..1a0bd03f3d407 100644
--- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h
+++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
@@ -121,8 +121,8 @@ class LLVM_ABI InstSimplifyFolder final : public IRBuilderFolder {
 
   Value *FoldBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Type *Ty,
                              Instruction *FMFSource = nullptr) const override {
-    return simplifyBinaryIntrinsic(ID, Ty, LHS, RHS, SQ,
-                                   dyn_cast_if_present<CallBase>(FMFSource));
+    return simplifyBinaryIntrinsic(ID, Ty, LHS, RHS,
+                                   SQ.getWithInstruction(FMFSource));
   }
 
   //===--------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h
index b5fdd8422ab9a..c0b2e6c49a3e8 100644
--- a/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -198,8 +198,7 @@ LLVM_ABI Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
 /// The \p `Call` argument is optional and may be null.
 LLVM_ABI Value *simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
                                         Value *Op0, Value *Op1,
-                                        const SimplifyQuery &Q,
-                                        const CallBase *Call);
+                                        const SimplifyQuery &Q);
 
 /// Given operands for a ShuffleVectorInst, fold the result or return null.
 /// See class ShuffleVectorInst for a description of the mask representation.
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 2bd0eb269510f..1c7ba26c63288 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6722,7 +6722,7 @@ enum class MinMaxOptResult {
 // quieted), or to choose either option in the case of undef/poison.
 static MinMaxOptResult OptimizeConstMinMax(const Constant *RHSConst,
                                            const Intrinsic::ID IID,
-                                           const CallBase *Call,
+                                           FastMathFlags FMF,
                                            Constant **OutNewConstVal) {
   assert(OutNewConstVal != nullptr);
 
@@ -6758,15 +6758,14 @@ static MinMaxOptResult OptimizeConstMinMax(const Constant *RHSConst,
     return MinMaxOptResult::UseOtherVal;
   }
 
-  if (CAPF.isInfinity() || (Call && Call->hasNoInfs() && CAPF.isLargest())) {
+  if (CAPF.isInfinity() || (FMF.noInfs() && CAPF.isLargest())) {
     // minnum(X, -inf) -> -inf (ignoring sNaN -> qNaN propagation)
     // maxnum(X, +inf) -> +inf (ignoring sNaN -> qNaN propagation)
     // minimum(X, -inf) -> -inf if nnan
     // maximum(X, +inf) -> +inf if nnan
     // minimumnum(X, -inf) -> -inf
     // maximumnum(X, +inf) -> +inf
-    if (CAPF.isNegative() == IsMin &&
-        (!PropagateNaN || (Call && Call->hasNoNaNs()))) {
+    if (CAPF.isNegative() == IsMin && (!PropagateNaN || FMF.noNaNs())) {
       *OutNewConstVal = const_cast<Constant *>(RHSConst);
       return MinMaxOptResult::UseNewConstVal;
     }
@@ -6777,8 +6776,7 @@ static MinMaxOptResult OptimizeConstMinMax(const Constant *RHSConst,
     // maximum(X, -inf) -> X (ignoring quieting of sNaNs)
     // minimumnum(X, +inf) -> X if nnan
     // maximumnum(X, -inf) -> X if nnan
-    if (CAPF.isNegative() != IsMin &&
-        (PropagateNaN || (Call && Call->hasNoNaNs())))
+    if (CAPF.isNegative() != IsMin && (PropagateNaN || FMF.noNaNs()))
       return MinMaxOptResult::UseOtherVal;
   }
   return MinMaxOptResult::CannotOptimize;
@@ -6842,18 +6840,17 @@ static Value *simplifySVEIntReduction(Intrinsic::ID IID, Type *ReturnType,
 
 Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
                                      Value *Op0, Value *Op1,
-                                     const SimplifyQuery &Q,
-                                     const CallBase *Call) {
+                                     const SimplifyQuery &Q) {
   unsigned BitWidth = ReturnType->getScalarSizeInBits();
   switch (IID) {
   case Intrinsic::get_active_lane_mask: {
     if (match(Op1, m_Zero()))
       return ConstantInt::getFalse(ReturnType);
 
-    if (!Call)
+    if (!Q.CxtI)
       break;
 
-    const Function *F = Call->getFunction();
+    const Function *F = Q.CxtI->getFunction();
     auto *ScalableTy = dyn_cast<ScalableVectorType>(ReturnType);
     Attribute Attr = F->getFnAttribute(Attribute::VScaleRange);
     if (ScalableTy && Attr.isValid()) {
@@ -7133,12 +7130,16 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
       MinMaxOptResult OptResult = MinMaxOptResult::CannotOptimize;
       Constant *NewConst = nullptr;
 
+      FastMathFlags FMF;
+      if (auto *FPMO = dyn_cast_if_present<FPMathOperator>(Q.CxtI))
+        FMF = FPMO->getFastMathFlags();
+
       if (VectorType *VTy = dyn_cast<VectorType>(C->getType())) {
         ElementCount ElemCount = VTy->getElementCount();
 
         if (Constant *SplatVal = C->getSplatValue()) {
           // Handle splat vectors (including scalable vectors)
-          OptResult = OptimizeConstMinMax(SplatVal, IID, Call, &NewConst);
+          OptResult = OptimizeConstMinMax(SplatVal, IID, FMF, &NewConst);
           if (OptResult == MinMaxOptResult::UseNewConstVal)
             NewConst = ConstantVector::getSplat(ElemCount, NewConst);
 
@@ -7157,7 +7158,7 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
               OptResult = MinMaxOptResult::CannotOptimize;
               break;
             }
-            auto ElemResult = OptimizeConstMinMax(Elt, IID, Call, &NewConst);
+            auto ElemResult = OptimizeConstMinMax(Elt, IID, FMF, &NewConst);
             if (ElemResult == MinMaxOptResult::CannotOptimize ||
                 (ElemResult != OptResult &&
                  OptResult != MinMaxOptResult::UseEither &&
@@ -7174,7 +7175,7 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
         }
       } else {
         // Handle scalar inputs
-        OptResult = OptimizeConstMinMax(C, IID, Call, &NewConst);
+        OptResult = OptimizeConstMinMax(C, IID, FMF, &NewConst);
       }
 
       if (OptResult == MinMaxOptResult::UseOtherVal ||
@@ -7254,8 +7255,8 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
     return simplifyUnaryIntrinsic(F, Args[0], Q, Call);
 
   if (NumOperands == 2)
-    return simplifyBinaryIntrinsic(IID, F->getReturnType(), Args[0], Args[1], Q,
-                                   Call);
+    return simplifyBinaryIntrinsic(IID, F->getReturnType(), Args[0], Args[1],
+                                   Q.getWithInstruction(Call));
 
   // Handle intrinsics with 3 or more arguments.
   switch (IID) {



More information about the llvm-commits mailing list