[llvm] [InstSimplify] Optimize maximumnum and minimumnum (PR #139581)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 19 08:58:04 PDT 2025


================
@@ -6715,36 +6725,138 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
     if (Q.isUndefValue(Op1))
       return Op0;
 
-    bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
-    bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
-
-    // minnum(X, nan) -> X
-    // maxnum(X, nan) -> X
-    // minimum(X, nan) -> nan
-    // maximum(X, nan) -> nan
-    if (match(Op1, m_NaN()))
-      return PropagateNaN ? propagateNaN(cast<Constant>(Op1)) : Op0;
-
-    // In the following folds, inf can be replaced with the largest finite
-    // float, if the ninf flag is set.
-    const APFloat *C;
-    if (match(Op1, m_APFloat(C)) &&
-        (C->isInfinity() || (Call && Call->hasNoInfs() && C->isLargest()))) {
-      // minnum(X, -inf) -> -inf
-      // maxnum(X, +inf) -> +inf
-      // minimum(X, -inf) -> -inf if nnan
-      // maximum(X, +inf) -> +inf if nnan
-      if (C->isNegative() == IsMin &&
-          (!PropagateNaN || (Call && Call->hasNoNaNs())))
-        return ConstantFP::get(ReturnType, *C);
-
-      // minnum(X, +inf) -> X if nnan
-      // maxnum(X, -inf) -> X if nnan
-      // minimum(X, +inf) -> X
-      // maximum(X, -inf) -> X
-      if (C->isNegative() != IsMin &&
-          (PropagateNaN || (Call && Call->hasNoNaNs())))
-        return Op0;
+    if (Constant *C = dyn_cast<Constant>(Op1)) {
+      bool PropagateNaN =
+          IID == Intrinsic::minimum || IID == Intrinsic::maximum;
+      bool PropagateSNaN = IID == Intrinsic::minnum || IID == Intrinsic::maxnum;
+      bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum ||
+                   IID == Intrinsic::minimumnum;
+
+      // Get the optimized value for a constant scalar input. The result may
+      // indicate either to use the non-const LHS value, or return a pointer
+      // to a new constant value to use instead of the input (after e.g.
+      // quieting NaNs). Returns empty optional value if it cannot be optimized.
+      typedef struct {
+        bool UseNonConstVal;
+        Constant *NewConstVal;
+      } OptResult;
+      auto GetOptResultFor = [PropagateNaN, PropagateSNaN, IsMin,
+                              Call](Constant *C) -> std::optional<OptResult> {
----------------
arsenm wrote:

I think this exceeds the size that's reasonable for a lambda, can you pull this into a separate utility function 

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


More information about the llvm-commits mailing list