[llvm] [Support] Move `KnownFPClass` inference from `KnownBits` to Support (PR #189414)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 08:47:00 PDT 2026


https://github.com/zGoldthorpe created https://github.com/llvm/llvm-project/pull/189414

Move logic for inferring `KnownFPClass` from known bits into the Support library so the logic may be used e.g., for analogous value tracking functions in SelectionDAG.

>From ba5b76400adeebbda0bfa2092ce245a22673ef09 Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Mon, 30 Mar 2026 10:39:56 -0500
Subject: [PATCH] [Support] Move `KnownFPClass` inference from `KnownBits` to
 Support

---
 llvm/include/llvm/Support/KnownFPClass.h |  5 +++
 llvm/lib/Analysis/ValueTracking.cpp      | 45 +-------------------
 llvm/lib/Support/KnownFPClass.cpp        | 53 ++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 44 deletions(-)

diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 5b5004f061ea2..dce54812926c1 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -15,6 +15,7 @@
 #define LLVM_SUPPORT_KNOWNFPCLASS_H
 
 #include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/IR/Type.h"
 #include "llvm/Support/Compiler.h"
 #include <optional>
 
@@ -225,6 +226,10 @@ struct KnownFPClass {
   canonicalize(const KnownFPClass &Src,
                DenormalMode DenormMode = DenormalMode::getDynamic());
 
+  /// Report known values for a bitcast into a float with provided semantics.
+  LLVM_ABI static KnownFPClass bitcast(const Type *EltTy,
+                                       const KnownBits &Bits);
+
   /// Report known values for fadd
   LLVM_ABI static KnownFPClass
   fadd(const KnownFPClass &LHS, const KnownFPClass &RHS,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3528cc963e434..545bed7055f04 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6045,50 +6045,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
     KnownBits Bits(EltTy->getPrimitiveSizeInBits());
     computeKnownBits(Src, DemandedElts, Bits, Q, Depth + 1);
 
-    // Transfer information from the sign bit.
-    if (Bits.isNonNegative())
-      Known.signBitMustBeZero();
-    else if (Bits.isNegative())
-      Known.signBitMustBeOne();
-
-    if (EltTy->isIEEELikeFPTy()) {
-      // IEEE floats are NaN when all bits of the exponent plus at least one of
-      // the fraction bits are 1. This means:
-      //   - If we assume unknown bits are 0 and the value is NaN, it will
-      //     always be NaN
-      //   - If we assume unknown bits are 1 and the value is not NaN, it can
-      //     never be NaN
-      // Note: They do not hold for x86_fp80 format.
-      if (APFloat(EltTy->getFltSemantics(), Bits.One).isNaN())
-        Known.KnownFPClasses = fcNan;
-      else if (!APFloat(EltTy->getFltSemantics(), ~Bits.Zero).isNaN())
-        Known.knownNot(fcNan);
-
-      // Build KnownBits representing Inf and check if it must be equal or
-      // unequal to this value.
-      auto InfKB = KnownBits::makeConstant(
-          APFloat::getInf(EltTy->getFltSemantics()).bitcastToAPInt());
-      InfKB.Zero.clearSignBit();
-      if (const auto InfResult = KnownBits::eq(Bits, InfKB)) {
-        assert(!InfResult.value());
-        Known.knownNot(fcInf);
-      } else if (Bits == InfKB) {
-        Known.KnownFPClasses = fcInf;
-      }
-
-      // Build KnownBits representing Zero and check if it must be equal or
-      // unequal to this value.
-      auto ZeroKB = KnownBits::makeConstant(
-          APFloat::getZero(EltTy->getFltSemantics()).bitcastToAPInt());
-      ZeroKB.Zero.clearSignBit();
-      if (const auto ZeroResult = KnownBits::eq(Bits, ZeroKB)) {
-        assert(!ZeroResult.value());
-        Known.knownNot(fcZero);
-      } else if (Bits == ZeroKB) {
-        Known.KnownFPClasses = fcZero;
-      }
-    }
-
+    Known = KnownFPClass::bitcast(EltTy, Bits);
     break;
   }
   default:
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 1a25e3866c4fd..5a712773951a9 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -13,6 +13,7 @@
 
 #include "llvm/Support/KnownFPClass.h"
 #include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
 
@@ -234,6 +235,58 @@ KnownFPClass KnownFPClass::canonicalize(const KnownFPClass &KnownSrc,
   return Known;
 }
 
+KnownFPClass KnownFPClass::bitcast(const Type *EltTy, const KnownBits &Bits) {
+  assert(EltTy->getPrimitiveSizeInBits() == Bits.getBitWidth() &&
+         "Bitcast operand has incorrect bit width");
+  KnownFPClass Known;
+
+  // Transfer information from the sign bit.
+  if (Bits.isNonNegative())
+    Known.signBitMustBeZero();
+  else if (Bits.isNegative())
+    Known.signBitMustBeOne();
+
+  if (EltTy->isIEEELikeFPTy()) {
+    // IEEE floats are NaN when all bits of the exponent plus at least one of
+    // the fraction bits are 1. This means:
+    //   - If we assume unknown bits are 0 and the value is NaN, it will
+    //     always be NaN
+    //   - If we assume unknown bits are 1 and the value is not NaN, it can
+    //     never be NaN
+    // Note: They do not hold for x86_fp80 format.
+    if (APFloat(EltTy->getFltSemantics(), Bits.One).isNaN())
+      Known.KnownFPClasses = fcNan;
+    else if (!APFloat(EltTy->getFltSemantics(), ~Bits.Zero).isNaN())
+      Known.knownNot(fcNan);
+
+    // Build KnownBits representing Inf and check if it must be equal or
+    // unequal to this value.
+    auto InfKB = KnownBits::makeConstant(
+        APFloat::getInf(EltTy->getFltSemantics()).bitcastToAPInt());
+    InfKB.Zero.clearSignBit();
+    if (const auto InfResult = KnownBits::eq(Bits, InfKB)) {
+      assert(!InfResult.value());
+      Known.knownNot(fcInf);
+    } else if (Bits == InfKB) {
+      Known.KnownFPClasses = fcInf;
+    }
+
+    // Build KnownBits representing Zero and check if it must be equal or
+    // unequal to this value.
+    auto ZeroKB = KnownBits::makeConstant(
+        APFloat::getZero(EltTy->getFltSemantics()).bitcastToAPInt());
+    ZeroKB.Zero.clearSignBit();
+    if (const auto ZeroResult = KnownBits::eq(Bits, ZeroKB)) {
+      assert(!ZeroResult.value());
+      Known.knownNot(fcZero);
+    } else if (Bits == ZeroKB) {
+      Known.KnownFPClasses = fcZero;
+    }
+  }
+
+  return Known;
+}
+
 // Handle known sign bit and nan cases for fadd.
 static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
                               const KnownFPClass &KnownRHS, DenormalMode Mode) {



More information about the llvm-commits mailing list