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

Lewis Crawford via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 20 06:08:32 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;
----------------
LewisCrawford wrote:

The NewConstVal was intended only for when a constant-value needed returned (which was different from the original RHS value, as NaNs were quieted).

I've now simplified this logic to return an enum for whether we either:
- Cannot optimize
- Use a modified constant value
- Use the other non-const argument
- Use either argument (in the case of undef/poison).

The modified constant is now returned via an output parameter instead of encoding it as part of a confusion struct inside an optional.

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


More information about the llvm-commits mailing list