[llvm] [SelectionDAG] Remove NoNaNsFPMath (PR #169904)

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 28 03:37:27 PST 2025


https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/169904

Replaced by checking fast-math flags or nofpclass.

>From cb990d42fda162048bc3d068f347c67b858f488f Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 28 Nov 2025 19:36:20 +0800
Subject: [PATCH] [SelectionDAG] Remove NoNaNsFPMath Replaced by checking
 fast-math flags or nofpclass.

---
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 57 ++++++++++++++++---
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 88b0809b767b5..4e1c2a9de16a9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2444,6 +2444,52 @@ static bool InBlock(const Value *V, const BasicBlock *BB) {
   return true;
 }
 
+// Similar with isKnownNonNaN in lib/Analysis/ValueTracking.cpp
+// but this version also inspects the def.
+static bool IsKnownNonNaN(const Value *V) {
+  if (auto *C = dyn_cast<ConstantFP>(V))
+    return !C->isNaN();
+
+  if (auto *C = dyn_cast<ConstantDataVector>(V)) {
+    if (!C->getElementType()->isFloatingPointTy())
+      return false;
+    for (unsigned I = 0, E = C->getNumElements(); I < E; ++I) {
+      if (C->getElementAsAPFloat(I).isNaN())
+        return false;
+    }
+    return true;
+  }
+
+  if (isa<ConstantAggregateZero>(V))
+    return true;
+
+  if (const auto *FPOp = dyn_cast<FPMathOperator>(V))
+    return FPOp->hasNoNaNs();
+
+  if (const auto *Arg = dyn_cast<Argument>(V))
+    return Arg->getNoFPClass() & fcNan;
+
+  return false;
+}
+
+static bool AreFCmpOperandsNonNaN(const Instruction *Inst) {
+  assert((isa<FCmpInst>(Inst) || isa<ConstrainedFPCmpIntrinsic>(Inst)) &&
+         "Not fcmp instruction or its intrinsic variants!");
+  if (const auto *VPFCmp = dyn_cast<VPIntrinsic>(Inst))
+    assert(VPFCmp->getIntrinsicID() == Intrinsic::vp_fcmp &&
+           "Not fcmp instruction or its intrinsic variants!");
+
+  if (const auto *FPOp = dyn_cast<FPMathOperator>(Inst))
+    if (FPOp->hasNoNaNs())
+      return true;
+
+  for (const auto &U : Inst->operands())
+    if (!IsKnownNonNaN(U))
+      return false;
+
+  return true;
+}
+
 /// EmitBranchForMergedCondition - Helper method for FindMergedConditions.
 /// This function emits a branch and is used at the leaves of an OR or an
 /// AND operator tree.
@@ -2477,7 +2523,7 @@ SelectionDAGBuilder::EmitBranchForMergedCondition(const Value *Cond,
         FCmpInst::Predicate Pred =
             InvertCond ? FC->getInversePredicate() : FC->getPredicate();
         Condition = getFCmpCondCode(Pred);
-        if (TM.Options.NoNaNsFPMath)
+        if (AreFCmpOperandsNonNaN(FC))
           Condition = getFCmpCodeWithoutNaN(Condition);
       }
 
@@ -3756,7 +3802,7 @@ void SelectionDAGBuilder::visitFCmp(const FCmpInst &I) {
 
   ISD::CondCode Condition = getFCmpCondCode(predicate);
   auto *FPMO = cast<FPMathOperator>(&I);
-  if (FPMO->hasNoNaNs() || TM.Options.NoNaNsFPMath)
+  if (AreFCmpOperandsNonNaN(&I))
     Condition = getFCmpCodeWithoutNaN(Condition);
 
   SDNodeFlags Flags;
@@ -8480,7 +8526,7 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
   case ISD::STRICT_FSETCCS: {
     auto *FPCmp = dyn_cast<ConstrainedFPCmpIntrinsic>(&FPI);
     ISD::CondCode Condition = getFCmpCondCode(FPCmp->getPredicate());
-    if (TM.Options.NoNaNsFPMath)
+    if (AreFCmpOperandsNonNaN(FPCmp))
       Condition = getFCmpCodeWithoutNaN(Condition);
     Opers.push_back(DAG.getCondCode(Condition));
     break;
@@ -8763,11 +8809,8 @@ void SelectionDAGBuilder::visitVPCmp(const VPCmpIntrinsic &VPIntrin) {
   CmpInst::Predicate CondCode = VPIntrin.getPredicate();
   bool IsFP = VPIntrin.getOperand(0)->getType()->isFPOrFPVectorTy();
   if (IsFP) {
-    // FIXME: Regular fcmps are FPMathOperators which may have fast-math (nnan)
-    // flags, but calls that don't return floating-point types can't be
-    // FPMathOperators, like vp.fcmp. This affects constrained fcmp too.
     Condition = getFCmpCondCode(CondCode);
-    if (TM.Options.NoNaNsFPMath)
+    if (AreFCmpOperandsNonNaN(&VPIntrin))
       Condition = getFCmpCodeWithoutNaN(Condition);
   } else {
     Condition = getICmpCondCode(CondCode);



More information about the llvm-commits mailing list