[llvm] [InstCombine] Fold select of ordered fcmps of fabs over `isKnownNeverNaN`-selects to a single select (PR #192182)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 09:21:12 PDT 2026


================
@@ -3347,6 +3347,106 @@ static Instruction *foldSelectWithFCmpToFabs(SelectInst &SI,
   return ChangedFMF ? &SI : nullptr;
 }
 
+static bool matchIsNaNTest(FCmpInst *Cmp, Value *X, bool MatchIsNaN,
+                           InstCombinerImpl &IC) {
+  FCmpInst::Predicate ExpectedPred =
+      MatchIsNaN ? FCmpInst::FCMP_UNO : FCmpInst::FCMP_ORD;
+  if (Cmp->getPredicate() != ExpectedPred)
+    return false;
+
+  Value *Cmp0 = Cmp->getOperand(0), *Cmp1 = Cmp->getOperand(1);
+  if (Cmp0 == X && Cmp1 == X)
+    return true;
+
+  auto IsKnownNeverNaN = [&](Value *V) {
+    return match(V, m_NonNaN()) ||
+           isKnownNeverNaN(V, IC.getSimplifyQuery().getWithInstruction(Cmp));
+  };
+
+  return (Cmp0 == X && IsKnownNeverNaN(Cmp1)) ||
+         (Cmp1 == X && IsKnownNeverNaN(Cmp0));
+}
+
+// Match a select that returns X when X is not NaN, and Y otherwise.
+static Value *matchNaNScrubbedValue(SelectInst *SI, Value *Y,
+                                    InstCombinerImpl &IC) {
+  auto *Cmp = dyn_cast<FCmpInst>(SI->getCondition());
+  if (!Cmp || !Cmp->hasOneUse())
+    return nullptr;
+
+  Value *X;
+  bool MatchIsNaN;
+  if (SI->getFalseValue() == Y) {
+    X = SI->getTrueValue();
+    MatchIsNaN = false;
+  } else if (SI->getTrueValue() == Y) {
+    X = SI->getFalseValue();
+    MatchIsNaN = true;
+  } else {
+    return nullptr;
+  }
+
+  return matchIsNaNTest(Cmp, X, MatchIsNaN, IC) ? X : nullptr;
+}
+
+// Fold a select of an ordered fcmp using fabs of a NaN-scrubbed value:
+//   %s   = select i1 (isnotnan T %x), T %x, T %y
+//   %a   = call T @llvm.fabs.T(T %s)
+//   %c   = fcmp <ordered-pred> T %a, %k
+//   %r   = select i1 %c, T %s, T %y
+//     =>
+//   %a2  = call T @llvm.fabs.T(T %x)
+//   %c2  = fcmp <ordered-pred> T %a2, %k
+//   %r2  = select i1 %c2, T %x, T %y
+static Instruction *
+foldSelectOfOrderedFAbsCmpOfNaNScrubbedValue(SelectInst &SI,
----------------
arsenm wrote:

Use match() for most of these checks 

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


More information about the llvm-commits mailing list