[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