[llvm-branch-commits] [llvm] ValueTracking: Improve nan tracking for fma square special case (PR #175999)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 14 11:24:18 PST 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/175999

>From 246522cde1987db996a2c313f827ff9bb21b967d Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 12 Jan 2026 14:28:25 +0100
Subject: [PATCH] ValueTracking: Improve nan tracking for fma square special
 case

In the square multiply case, we can infer if the add of opposite
sign infinities can occur.
---
 llvm/lib/Analysis/ValueTracking.cpp              |  4 ++++
 llvm/lib/Support/KnownFPClass.cpp                | 12 +++++++++++-
 llvm/test/Transforms/Attributor/nofpclass-fma.ll |  4 ++--
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a99fca1de3118..3f16eda0b475a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5661,6 +5661,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
                           Q, Depth + 1);
     }
 
+    // TODO: Improve accuracy in unfused FMA pattern. We can prove an additional
+    // not-nan if the addend is known-not negative infinity if the multiply is
+    // known-not infinity.
+
     computeKnownFPClass(Op->getOperand(0), DemandedElts, fcAllFlags, KnownLHS,
                         Q, Depth + 1);
 
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index e96d4b94ec07c..d9ff6da17a876 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -357,7 +357,17 @@ KnownFPClass KnownFPClass::fma(const KnownFPClass &KnownLHS,
 KnownFPClass KnownFPClass::fma_square(const KnownFPClass &KnownSquared,
                                       const KnownFPClass &KnownAddend,
                                       DenormalMode Mode) {
-  return fadd(square(KnownSquared, Mode), KnownAddend, Mode);
+  KnownFPClass Squared = square(KnownSquared, Mode);
+  KnownFPClass Known = fadd(Squared, KnownAddend, Mode);
+
+  // Since we know the squared input must be positive, the add of opposite sign
+  // infinities nan hazard only applies for negative nan.
+  if (KnownAddend.isKnownNever(fcNegInf | fcNan) &&
+      KnownSquared.isKnownNever(fcPosInf | fcNan) &&
+      KnownSquared.isKnownNeverLogicalZero(Mode))
+    Known.knownNot(fcNan);
+
+  return Known;
 }
 
 KnownFPClass KnownFPClass::exp(const KnownFPClass &KnownSrc) {
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fma.ll b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
index 84f89f3c463d9..e8e99584a001d 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fma.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
@@ -454,9 +454,9 @@ define half @ret_fma_square__no_nan_no_inf__no_nan_no_ninf(half noundef nofpclas
 }
 
 define half @ret_fma_square__no_nan_no_inf_no_zero__no_nan_no_ninf(half noundef nofpclass(nan inf zero) %arg0, half nofpclass(nan ninf) %arg1) {
-; CHECK-LABEL: define nofpclass(nzero) half @ret_fma_square__no_nan_no_inf_no_zero__no_nan_no_ninf
+; CHECK-LABEL: define nofpclass(nan nzero) half @ret_fma_square__no_nan_no_inf_no_zero__no_nan_no_ninf
 ; CHECK-SAME: (half noundef nofpclass(nan inf zero) [[ARG0:%.*]], half nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero) half @llvm.fma.f16(half noundef nofpclass(nan inf zero) [[ARG0]], half noundef nofpclass(nan inf zero) [[ARG0]], half nofpclass(nan ninf) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan nzero) half @llvm.fma.f16(half noundef nofpclass(nan inf zero) [[ARG0]], half noundef nofpclass(nan inf zero) [[ARG0]], half nofpclass(nan ninf) [[ARG1]]) #[[ATTR2]]
 ; CHECK-NEXT:    ret half [[CALL]]
 ;
   %call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)



More information about the llvm-branch-commits mailing list