[clang] [llvm] [InstCombine] fold float clamp pattern into llvm.max/min (PR #159652)

Vedant Paranjape via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 18 21:01:52 PDT 2025


================
@@ -3963,6 +3963,61 @@ static Value *foldSelectIntoAddConstant(SelectInst &SI,
   return nullptr;
 }
 
+// fcmp + sel patterns into max/min intrinsic.
+static Value *foldSelectICmpIntoMaxMin(SelectInst &SI,
+                                       InstCombiner::BuilderTy &Builder) {
+
+  auto TryFoldIntoMaxMinIntrinsic =
+      [&Builder, &SI](CmpInst::Predicate Pred, Value *CmpLHS, Value *CmpRHS,
+                      Value *TVal, Value *FVal) -> Value * {
+    // Early exit if the operands are not in the expected form.
+    if ((CmpRHS != TVal || CmpLHS != FVal) &&
+        (CmpLHS != TVal || CmpRHS != FVal))
+      return nullptr;
+
+    bool isSwapped = (CmpLHS == FVal && CmpRHS == TVal);
+    // Only these relational predicates can be transformed into maxnum/minnum
+    // intrinsic.
+    // X > C ? X : C --> maxnum(X, C)
+    // X > C ? C : X --> minnum(X, C)
+    if (Pred == CmpInst::FCMP_OGT) {
+      Intrinsic::ID MaxMinIID =
+          isSwapped ? Intrinsic::minnum : Intrinsic::maxnum;
+      return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
+                                     &SI);
+    }
+
+    // X < C ? X : C --> minnum(X, C)
+    // X < C ? C : X --> maxnum(X, C)
+    if (Pred == CmpInst::FCMP_OLT) {
+      Intrinsic::ID MaxMinIID =
+          isSwapped ? Intrinsic::maxnum : Intrinsic::minnum;
+      return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
+                                     &SI);
+    }
+
+    return nullptr;
+  };
+
+  // select((fcmp Pred, X, Y), X, Y)
+  //      => minnum/maxnum(X, Y)
+  //
+  // Pred := OGT and OLT
+  Value *X, *Y;
+  Value *TVal, *FVal;
+  CmpPredicate Pred;
+
+  // Note: OneUse check for `Cmp` is necessary because it makes sure that other
+  // InstCombine folds don't undo this transformation and cause an infinite
+  // loop. Furthermore, it could also increase the operation count.
+  if (match(&SI,
----------------
VedantParanjape wrote:

Fixed this and cleaned up the testcases.

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


More information about the llvm-commits mailing list