[llvm] [KnownFPClass] Refactor NaN sign encoding for KnownFPClass (PR #220606)

Eric Ross via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 4 16:29:28 PDT 2026


https://github.com/ZERICO2005 updated https://github.com/llvm/llvm-project/pull/220606

>From 25249336c06723d3f6284dc015d326d15e40af4d Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Mon, 24 Aug 2026 14:59:31 -0600
Subject: [PATCH 1/4] [KnownFPClass] Refactor NaN sign encoding for
 KnownFPClass

---
 llvm/include/llvm/Support/KnownFPClass.h | 343 +++++++++++++++++------
 llvm/lib/Support/KnownFPClass.cpp        |  10 +-
 2 files changed, 267 insertions(+), 86 deletions(-)

diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 33a115b679ad0..5dc9c34e78d28 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -24,41 +24,219 @@ class APInt;
 struct fltSemantics;
 struct KnownBits;
 
+enum FPClassMask : unsigned {
+  kfcNone = 0,
+
+  kfcNegQNan = 0x0001,
+  kfcNegSNan = 0x0002,
+  kfcNegInf = 0x0004,
+  kfcNegNormal = 0x0008,
+  kfcNegSubnormal = 0x0010,
+  kfcNegZero = 0x0020,
+  kfcPosZero = 0x0040,
+  kfcPosSubnormal = 0x0080,
+  kfcPosNormal = 0x0100,
+  kfcPosInf = 0x0200,
+  kfcPosSNan = 0x0400,
+  kfcPosQNan = 0x0800,
+
+  kfcSNan = kfcPosSNan | kfcNegSNan,
+  kfcQNan = kfcPosQNan | kfcNegQNan,
+  kfcPosNan = kfcPosSNan | kfcPosQNan,
+  kfcNegNan = kfcNegSNan | kfcNegQNan,
+  kfcNan = kfcSNan | kfcQNan,
+  kfcInf = kfcPosInf | kfcNegInf,
+  kfcNormal = kfcPosNormal | kfcNegNormal,
+  kfcSubnormal = kfcPosSubnormal | kfcNegSubnormal,
+  kfcZero = kfcPosZero | kfcNegZero,
+  kfcPosFinite = kfcPosNormal | kfcPosSubnormal | kfcPosZero,
+  kfcNegFinite = kfcNegNormal | kfcNegSubnormal | kfcNegZero,
+  kfcFinite = kfcPosFinite | kfcNegFinite,
+  kfcPositive = kfcPosFinite | kfcPosInf,
+  kfcNegative = kfcNegFinite | kfcNegInf,
+  kfcPosSignBit = kfcPositive | kfcPosNan,
+  kfcNegSignBit = kfcNegative | kfcNegNan,
+
+  kfcAllFlags = kfcNan | kfcInf | kfcFinite,
+};
+
+LLVM_DECLARE_ENUM_AS_BITMASK(FPClassMask, /* LargestValue */ kfcPosQNan);
+
+constexpr FPClassMask toFPClassMask(FPClassTest Classes) {
+  FPClassMask Mask = kfcNone;
+
+  if (Classes & fcQNan)
+    Mask |= kfcQNan;
+  if (Classes & fcSNan)
+    Mask |= kfcSNan;
+  if (Classes & fcNegInf)
+    Mask |= kfcNegInf;
+  if (Classes & fcNegNormal)
+    Mask |= kfcNegNormal;
+  if (Classes & fcNegSubnormal)
+    Mask |= kfcNegSubnormal;
+  if (Classes & fcNegZero)
+    Mask |= kfcNegZero;
+  if (Classes & fcPosZero)
+    Mask |= kfcPosZero;
+  if (Classes & fcPosSubnormal)
+    Mask |= kfcPosSubnormal;
+  if (Classes & fcPosNormal)
+    Mask |= kfcPosNormal;
+  if (Classes & fcPosInf)
+    Mask |= kfcPosInf;
+
+  return Mask;
+}
+
+constexpr FPClassMask toFPClassMask(FPClassTest Classes,
+                                    std::optional<bool> SignBit) {
+  FPClassMask Mask = toFPClassMask(Classes);
+
+  // This is the only way to generate a NaN with a specific sign from
+  // FPClassTest. SignBit must agree with the input classes.
+  if (SignBit) {
+    if (!*SignBit) {
+      Mask &= ~kfcNegNan;
+      // If the SignBit is false, then we should not have any negative classes.
+      if (!(Mask & kfcNegSignBit))
+        return Mask;
+    } else {
+      Mask &= ~kfcPosNan;
+      // If the SignBit is true, then we should not have any positive classes.
+      if (!(Mask & kfcPosSignBit))
+        return Mask;
+    }
+  }
+
+  // SignBit is unknown or inconsistent with the input classes. Expand the
+  // possible set to its opposite sign pair.
+  if (Classes & fcQNan)
+    Mask |= kfcQNan;
+  if (Classes & fcSNan)
+    Mask |= kfcSNan;
+  if (Classes & fcInf)
+    Mask |= kfcInf;
+  if (Classes & fcNormal)
+    Mask |= kfcNormal;
+  if (Classes & fcSubnormal)
+    Mask |= kfcSubnormal;
+  if (Classes & fcZero)
+    Mask |= kfcZero;
+
+  return Mask;
+}
+
+constexpr FPClassTest toFPClassTest(FPClassMask Mask) {
+  FPClassTest Classes = fcNone;
+
+  // Sign of qNaN and sNaN are lost in the conversion.
+  if (Mask & kfcQNan)
+    Classes |= fcQNan;
+  if (Mask & kfcSNan)
+    Classes |= fcSNan;
+
+  if (Mask & kfcNegInf)
+    Classes |= fcNegInf;
+  if (Mask & kfcNegNormal)
+    Classes |= fcNegNormal;
+  if (Mask & kfcNegSubnormal)
+    Classes |= fcNegSubnormal;
+  if (Mask & kfcNegZero)
+    Classes |= fcNegZero;
+  if (Mask & kfcPosZero)
+    Classes |= fcPosZero;
+  if (Mask & kfcPosSubnormal)
+    Classes |= fcPosSubnormal;
+  if (Mask & kfcPosNormal)
+    Classes |= fcPosNormal;
+  if (Mask & kfcPosInf)
+    Classes |= fcPosInf;
+
+  return Classes;
+}
+
 struct KnownFPClass {
-  FPClassTest KnownFPClassesValue = fcAllFlags;
-  std::optional<bool> SignBitValue;
+  FPClassMask KnownFPMask = kfcAllFlags;
 
   /// Floating-point classes the value could be one of.
-  FPClassTest getKnownFPClasses() const { return KnownFPClassesValue; }
+  FPClassTest getKnownFPClasses() const { return toFPClassTest(KnownFPMask); }
 
-  void setKnownFPClasses(FPClassTest Classes) { KnownFPClassesValue = Classes; }
+  void setKnownFPClasses(FPClassTest Classes) {
+    KnownFPMask = toFPClassMask(Classes);
+  }
+
+  void setKnownFPClasses(FPClassTest Classes, std::optional<bool> Sign) {
+    KnownFPMask = toFPClassMask(Classes, Sign);
+  }
 
   /// std::nullopt if the sign bit is unknown, true if the sign bit is
   /// definitely set or false if the sign bit is definitely unset.
-  std::optional<bool> getSignBit() const { return SignBitValue; }
+  /// By convention, returns false for kfcNone/poison.
+  std::optional<bool> getSignBit() const {
+    if (KnownFPMask == kfcNone)
+      return false;
 
-  void setSignBit(std::optional<bool> Sign) { SignBitValue = Sign; }
+    if ((KnownFPMask & kfcPosSignBit) == KnownFPMask)
+      return false;
+    if ((KnownFPMask & kfcNegSignBit) == KnownFPMask)
+      return true;
 
-  KnownFPClass(FPClassTest Known = fcAllFlags, std::optional<bool> Sign = {})
-      : KnownFPClassesValue(Known), SignBitValue(Sign) {}
+    return std::nullopt;
+  }
+
+  void setSignBit(std::optional<bool> Sign) {
+    if (Sign && !*Sign) {
+      KnownFPMask &= kfcPosSignBit;
+      return;
+    }
+    if (Sign && *Sign) {
+      KnownFPMask &= kfcNegSignBit;
+      return;
+    }
+    // Set sign to unknown.
+    if (KnownFPMask & kfcQNan)
+      KnownFPMask |= kfcQNan;
+    if (KnownFPMask & kfcSNan)
+      KnownFPMask |= kfcSNan;
+    if (KnownFPMask & kfcInf)
+      KnownFPMask |= kfcInf;
+    if (KnownFPMask & kfcNormal)
+      KnownFPMask |= kfcNormal;
+    if (KnownFPMask & kfcSubnormal)
+      KnownFPMask |= kfcSubnormal;
+    if (KnownFPMask & kfcZero)
+      KnownFPMask |= kfcZero;
+  }
+
+  KnownFPClass(FPClassMask Known = kfcAllFlags) : KnownFPMask(Known) {}
+  KnownFPClass(FPClassTest Known) : KnownFPMask(toFPClassMask(Known)) {}
+  KnownFPClass(FPClassTest Known, std::optional<bool> Sign)
+      : KnownFPMask(toFPClassMask(Known, Sign)) {}
   LLVM_ABI KnownFPClass(const APFloat &C);
 
   bool operator==(KnownFPClass Other) const {
-    return getKnownFPClasses() == Other.getKnownFPClasses() &&
-           getSignBit() == Other.getSignBit();
+    return KnownFPMask == Other.KnownFPMask;
+  }
+
+  /// Return true if it's known this can never be one of the mask entries.
+  bool isKnownNever(FPClassMask Mask) const {
+    return (KnownFPMask & Mask) == kfcNone;
   }
 
   /// Return true if it's known this can never be one of the mask entries.
   bool isKnownNever(FPClassTest Mask) const {
-    return (getKnownFPClasses() & Mask) == fcNone;
+    return isKnownNever(toFPClassMask(Mask));
   }
 
-  bool isKnownAlways(FPClassTest Mask) const { return isKnownNever(~Mask); }
+  bool isKnownAlways(FPClassMask Mask) const { return isKnownNever(~Mask); }
 
-  bool isUnknown() const {
-    return getKnownFPClasses() == fcAllFlags && !getSignBit();
+  bool isKnownAlways(FPClassTest Mask) const {
+    return isKnownAlways(toFPClassMask(Mask));
   }
 
+  bool isUnknown() const { return KnownFPMask == kfcAllFlags; }
+
   /// Return true if it's known this can never be a nan.
   bool isKnownNeverNaN() const { return isKnownNever(fcNan); }
 
@@ -171,44 +349,51 @@ struct KnownFPClass {
                                                        DenormalMode Mode);
 
   KnownFPClass intersectWith(const KnownFPClass &RHS) const {
-    return KnownFPClass(getKnownFPClasses() | RHS.getKnownFPClasses(),
-                        getSignBit() == RHS.getSignBit() ? getSignBit()
-                                                         : std::nullopt);
+    return KnownFPClass(KnownFPMask | RHS.KnownFPMask);
   }
 
   KnownFPClass unionWith(const KnownFPClass &RHS) const {
-    std::optional<bool> MergedSignBit;
-    if (getSignBit() && !RHS.getSignBit())
-      MergedSignBit = getSignBit();
-    else if (!getSignBit() && RHS.getSignBit())
-      MergedSignBit = RHS.getSignBit();
-
-    return KnownFPClass(getKnownFPClasses() & RHS.getKnownFPClasses(),
-                        MergedSignBit);
+    return KnownFPClass(KnownFPMask & RHS.KnownFPMask);
   }
 
   KnownFPClass &operator|=(const KnownFPClass &RHS) {
-    setKnownFPClasses(getKnownFPClasses() | RHS.getKnownFPClasses());
-
-    if (getSignBit() != RHS.getSignBit())
-      setSignBit(std::nullopt);
+    KnownFPMask |= RHS.KnownFPMask;
     return *this;
   }
 
-  void knownNot(FPClassTest RuleOut) {
-    setKnownFPClasses(getKnownFPClasses() & ~RuleOut);
-    if (isKnownNever(fcNan) && !getSignBit()) {
-      if (isKnownNever(fcNegative))
-        setSignBit(false);
-      else if (isKnownNever(fcPositive))
-        setSignBit(true);
-    }
-  }
+  void knownNot(FPClassMask RuleOut) { KnownFPMask &= ~RuleOut; }
+
+  void knownNot(FPClassTest RuleOut) { knownNot(toFPClassMask(RuleOut)); }
 
   void fneg() {
-    setKnownFPClasses(llvm::fneg(getKnownFPClasses()));
-    if (std::optional<bool> Sign = getSignBit())
-      setSignBit(!*Sign);
+    FPClassMask Known = kfcNone;
+
+    if (KnownFPMask & kfcNegQNan)
+      Known |= kfcPosQNan;
+    if (KnownFPMask & kfcNegSNan)
+      Known |= kfcPosSNan;
+    if (KnownFPMask & kfcNegInf)
+      Known |= kfcPosInf;
+    if (KnownFPMask & kfcNegNormal)
+      Known |= kfcPosNormal;
+    if (KnownFPMask & kfcNegSubnormal)
+      Known |= kfcPosSubnormal;
+    if (KnownFPMask & kfcNegZero)
+      Known |= kfcPosZero;
+    if (KnownFPMask & kfcPosZero)
+      Known |= kfcNegZero;
+    if (KnownFPMask & kfcPosSubnormal)
+      Known |= kfcNegSubnormal;
+    if (KnownFPMask & kfcPosNormal)
+      Known |= kfcNegNormal;
+    if (KnownFPMask & kfcPosInf)
+      Known |= kfcNegInf;
+    if (KnownFPMask & kfcPosSNan)
+      Known |= kfcNegSNan;
+    if (KnownFPMask & kfcPosQNan)
+      Known |= kfcNegQNan;
+
+    KnownFPMask = Known;
   }
 
   static KnownFPClass fneg(const KnownFPClass &Src) {
@@ -218,19 +403,22 @@ struct KnownFPClass {
   }
 
   void fabs() {
-    if (getKnownFPClasses() & fcNegZero)
-      setKnownFPClasses(getKnownFPClasses() | fcPosZero);
-
-    if (getKnownFPClasses() & fcNegInf)
-      setKnownFPClasses(getKnownFPClasses() | fcPosInf);
-
-    if (getKnownFPClasses() & fcNegSubnormal)
-      setKnownFPClasses(getKnownFPClasses() | fcPosSubnormal);
-
-    if (getKnownFPClasses() & fcNegNormal)
-      setKnownFPClasses(getKnownFPClasses() | fcPosNormal);
-
-    signBitMustBeZero();
+    FPClassMask Known = kfcNone;
+
+    if (KnownFPMask & kfcQNan)
+      Known |= kfcPosQNan;
+    if (KnownFPMask & kfcSNan)
+      Known |= kfcPosSNan;
+    if (KnownFPMask & kfcInf)
+      Known |= kfcPosInf;
+    if (KnownFPMask & kfcNormal)
+      Known |= kfcPosNormal;
+    if (KnownFPMask & kfcSubnormal)
+      Known |= kfcPosSubnormal;
+    if (KnownFPMask & kfcZero)
+      Known |= kfcPosZero;
+
+    KnownFPMask = Known;
   }
 
   static KnownFPClass fabs(const KnownFPClass &Src) {
@@ -379,39 +567,32 @@ struct KnownFPClass {
   bool signBitIsZeroOrNaN() const { return isKnownNever(fcNegative); }
 
   /// Assume the sign bit is zero.
-  void signBitMustBeZero() {
-    setKnownFPClasses(getKnownFPClasses() & (fcPositive | fcNan));
-    setSignBit(false);
-  }
+  void signBitMustBeZero() { KnownFPMask &= kfcPosSignBit; }
 
   /// Assume the sign bit is one.
-  void signBitMustBeOne() {
-    setKnownFPClasses(getKnownFPClasses() & (fcNegative | fcNan));
-    setSignBit(true);
-  }
+  void signBitMustBeOne() { KnownFPMask &= kfcNegSignBit; }
 
   void copysign(const KnownFPClass &Sign) {
     // Don't know anything about the sign of the source. Expand the possible set
     // to its opposite sign pair.
-    if (getKnownFPClasses() & fcZero)
-      setKnownFPClasses(getKnownFPClasses() | fcZero);
-    if (getKnownFPClasses() & fcSubnormal)
-      setKnownFPClasses(getKnownFPClasses() | fcSubnormal);
-    if (getKnownFPClasses() & fcNormal)
-      setKnownFPClasses(getKnownFPClasses() | fcNormal);
-    if (getKnownFPClasses() & fcInf)
-      setKnownFPClasses(getKnownFPClasses() | fcInf);
-
-    // Sign bit is exactly preserved even for nans.
-    setSignBit(Sign.getSignBit());
-
-    // Clear sign bits based on the input sign mask.
-    if (Sign.isKnownNever(fcPositive | fcNan) ||
-        (getSignBit() && *getSignBit()))
-      setKnownFPClasses(getKnownFPClasses() & (fcNegative | fcNan));
-    if (Sign.isKnownNever(fcNegative | fcNan) ||
-        (getSignBit() && !*getSignBit()))
-      setKnownFPClasses(getKnownFPClasses() & (fcPositive | fcNan));
+
+    if (KnownFPMask & kfcQNan)
+      KnownFPMask |= kfcQNan;
+    if (KnownFPMask & kfcSNan)
+      KnownFPMask |= kfcSNan;
+    if (KnownFPMask & kfcInf)
+      KnownFPMask |= kfcInf;
+    if (KnownFPMask & kfcNormal)
+      KnownFPMask |= kfcNormal;
+    if (KnownFPMask & kfcSubnormal)
+      KnownFPMask |= kfcSubnormal;
+    if (KnownFPMask & kfcZero)
+      KnownFPMask |= kfcZero;
+
+    if (Sign.getSignBit() && !*Sign.getSignBit())
+      KnownFPMask &= kfcPosSignBit;
+    if (Sign.getSignBit() && *Sign.getSignBit())
+      KnownFPMask &= kfcNegSignBit;
   }
 
   static KnownFPClass copysign(const KnownFPClass &KnownMag,
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 96d6a9758b8f8..6b040b9015970 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -19,9 +19,7 @@
 using namespace llvm;
 
 KnownFPClass::KnownFPClass(const APFloat &C)
-    : KnownFPClassesValue(C.classify()) {
-  setSignBit(C.isNegative());
-}
+    : KnownFPClass(C.classify(), C.isNegative()) {}
 
 KnownFPClass KnownFPClass::applyInputDenormalMode(const KnownFPClass &KnownSrc,
                                                   DenormalMode Mode) {
@@ -987,8 +985,10 @@ KnownFPClass KnownFPClass::fpext(const KnownFPClass &KnownSrc,
   }
 
   // Sign bit of a nan isn't guaranteed.
-  if (!Known.isKnownNeverNaN())
-    Known.setSignBit(std::nullopt);
+  if (Known.KnownFPMask & kfcSNan)
+    Known.KnownFPMask |= kfcSNan;
+  if (Known.KnownFPMask & kfcQNan)
+    Known.KnownFPMask |= kfcQNan;
 
   return Known;
 }

>From 791d0853a4b2ec2eeaaec841bce380899ce0c366 Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Wed, 23 Sep 2026 15:02:00 -0600
Subject: [PATCH 2/4] make KnownFPClass a class, and convert some
 std::optional<bool> parameters to bool

---
 llvm/include/llvm/Analysis/ValueTracking.h |  2 +-
 llvm/include/llvm/IR/ConstantFPRange.h     |  2 +-
 llvm/include/llvm/Support/KnownFPClass.h   | 34 +++++++++-------------
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index b3c8a894ef056..46eb729c2eaff 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -36,7 +36,7 @@ class DominatorTree;
 class GEPOperator;
 class WithOverflowInst;
 struct KnownBits;
-struct KnownFPClass;
+class KnownFPClass;
 class Loop;
 class LoopInfo;
 class MDNode;
diff --git a/llvm/include/llvm/IR/ConstantFPRange.h b/llvm/include/llvm/IR/ConstantFPRange.h
index e772095a266cc..f13778c5eb95d 100644
--- a/llvm/include/llvm/IR/ConstantFPRange.h
+++ b/llvm/include/llvm/IR/ConstantFPRange.h
@@ -31,7 +31,7 @@
 namespace llvm {
 
 class raw_ostream;
-struct KnownFPClass;
+class KnownFPClass;
 
 /// This class represents a range of floating-point values.
 class [[nodiscard]] ConstantFPRange {
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 5dc9c34e78d28..255f92782676b 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -89,24 +89,21 @@ constexpr FPClassMask toFPClassMask(FPClassTest Classes) {
   return Mask;
 }
 
-constexpr FPClassMask toFPClassMask(FPClassTest Classes,
-                                    std::optional<bool> SignBit) {
+constexpr FPClassMask toFPClassMask(FPClassTest Classes, bool SignBit) {
   FPClassMask Mask = toFPClassMask(Classes);
 
   // This is the only way to generate a NaN with a specific sign from
   // FPClassTest. SignBit must agree with the input classes.
-  if (SignBit) {
-    if (!*SignBit) {
-      Mask &= ~kfcNegNan;
-      // If the SignBit is false, then we should not have any negative classes.
-      if (!(Mask & kfcNegSignBit))
-        return Mask;
-    } else {
-      Mask &= ~kfcPosNan;
-      // If the SignBit is true, then we should not have any positive classes.
-      if (!(Mask & kfcPosSignBit))
-        return Mask;
-    }
+  if (!SignBit) {
+    Mask &= ~kfcNegNan;
+    // If the SignBit is false, then we should not have any negative classes.
+    if (!(Mask & kfcNegSignBit))
+      return Mask;
+  } else {
+    Mask &= ~kfcPosNan;
+    // If the SignBit is true, then we should not have any positive classes.
+    if (!(Mask & kfcPosSignBit))
+      return Mask;
   }
 
   // SignBit is unknown or inconsistent with the input classes. Expand the
@@ -156,9 +153,10 @@ constexpr FPClassTest toFPClassTest(FPClassMask Mask) {
   return Classes;
 }
 
-struct KnownFPClass {
+class KnownFPClass {
   FPClassMask KnownFPMask = kfcAllFlags;
 
+public:
   /// Floating-point classes the value could be one of.
   FPClassTest getKnownFPClasses() const { return toFPClassTest(KnownFPMask); }
 
@@ -166,10 +164,6 @@ struct KnownFPClass {
     KnownFPMask = toFPClassMask(Classes);
   }
 
-  void setKnownFPClasses(FPClassTest Classes, std::optional<bool> Sign) {
-    KnownFPMask = toFPClassMask(Classes, Sign);
-  }
-
   /// std::nullopt if the sign bit is unknown, true if the sign bit is
   /// definitely set or false if the sign bit is definitely unset.
   /// By convention, returns false for kfcNone/poison.
@@ -211,7 +205,7 @@ struct KnownFPClass {
 
   KnownFPClass(FPClassMask Known = kfcAllFlags) : KnownFPMask(Known) {}
   KnownFPClass(FPClassTest Known) : KnownFPMask(toFPClassMask(Known)) {}
-  KnownFPClass(FPClassTest Known, std::optional<bool> Sign)
+  KnownFPClass(FPClassTest Known, bool Sign)
       : KnownFPMask(toFPClassMask(Known, Sign)) {}
   LLVM_ABI KnownFPClass(const APFloat &C);
 

>From 352be2af70e1fd6c5a28cc8946bcd55ad8aa349e Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Wed, 30 Sep 2026 00:00:56 -0600
Subject: [PATCH 3/4] Make FPClassMask an enum class

---
 llvm/include/llvm/Support/KnownFPClass.h | 339 ++++++++++++-----------
 llvm/lib/Support/KnownFPClass.cpp        |   8 +-
 2 files changed, 175 insertions(+), 172 deletions(-)

diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 255f92782676b..80cfcfd0608b5 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_SUPPORT_KNOWNFPCLASS_H
 #define LLVM_SUPPORT_KNOWNFPCLASS_H
 
+#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Support/Compiler.h"
 #include <optional>
@@ -24,7 +25,7 @@ class APInt;
 struct fltSemantics;
 struct KnownBits;
 
-enum FPClassMask : unsigned {
+enum class FPClassMask : unsigned {
   kfcNone = 0,
 
   kfcNegQNan = 0x0001,
@@ -58,103 +59,104 @@ enum FPClassMask : unsigned {
   kfcNegSignBit = kfcNegative | kfcNegNan,
 
   kfcAllFlags = kfcNan | kfcInf | kfcFinite,
-};
 
-LLVM_DECLARE_ENUM_AS_BITMASK(FPClassMask, /* LargestValue */ kfcPosQNan);
-
-constexpr FPClassMask toFPClassMask(FPClassTest Classes) {
-  FPClassMask Mask = kfcNone;
-
-  if (Classes & fcQNan)
-    Mask |= kfcQNan;
-  if (Classes & fcSNan)
-    Mask |= kfcSNan;
-  if (Classes & fcNegInf)
-    Mask |= kfcNegInf;
-  if (Classes & fcNegNormal)
-    Mask |= kfcNegNormal;
-  if (Classes & fcNegSubnormal)
-    Mask |= kfcNegSubnormal;
-  if (Classes & fcNegZero)
-    Mask |= kfcNegZero;
-  if (Classes & fcPosZero)
-    Mask |= kfcPosZero;
-  if (Classes & fcPosSubnormal)
-    Mask |= kfcPosSubnormal;
-  if (Classes & fcPosNormal)
-    Mask |= kfcPosNormal;
-  if (Classes & fcPosInf)
-    Mask |= kfcPosInf;
-
-  return Mask;
-}
+  LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ kfcPosQNan)
+};
 
-constexpr FPClassMask toFPClassMask(FPClassTest Classes, bool SignBit) {
-  FPClassMask Mask = toFPClassMask(Classes);
-
-  // This is the only way to generate a NaN with a specific sign from
-  // FPClassTest. SignBit must agree with the input classes.
-  if (!SignBit) {
-    Mask &= ~kfcNegNan;
-    // If the SignBit is false, then we should not have any negative classes.
-    if (!(Mask & kfcNegSignBit))
-      return Mask;
-  } else {
-    Mask &= ~kfcPosNan;
-    // If the SignBit is true, then we should not have any positive classes.
-    if (!(Mask & kfcPosSignBit))
-      return Mask;
+class KnownFPClass {
+  FPClassMask KnownFPMask = FPClassMask::kfcAllFlags;
+
+  static constexpr FPClassMask toFPClassMask(FPClassTest Classes) {
+    FPClassMask Mask = FPClassMask::kfcNone;
+
+    if (Classes & fcQNan)
+      Mask |= FPClassMask::kfcQNan;
+    if (Classes & fcSNan)
+      Mask |= FPClassMask::kfcSNan;
+    if (Classes & fcNegInf)
+      Mask |= FPClassMask::kfcNegInf;
+    if (Classes & fcNegNormal)
+      Mask |= FPClassMask::kfcNegNormal;
+    if (Classes & fcNegSubnormal)
+      Mask |= FPClassMask::kfcNegSubnormal;
+    if (Classes & fcNegZero)
+      Mask |= FPClassMask::kfcNegZero;
+    if (Classes & fcPosZero)
+      Mask |= FPClassMask::kfcPosZero;
+    if (Classes & fcPosSubnormal)
+      Mask |= FPClassMask::kfcPosSubnormal;
+    if (Classes & fcPosNormal)
+      Mask |= FPClassMask::kfcPosNormal;
+    if (Classes & fcPosInf)
+      Mask |= FPClassMask::kfcPosInf;
+
+    return Mask;
   }
 
-  // SignBit is unknown or inconsistent with the input classes. Expand the
-  // possible set to its opposite sign pair.
-  if (Classes & fcQNan)
-    Mask |= kfcQNan;
-  if (Classes & fcSNan)
-    Mask |= kfcSNan;
-  if (Classes & fcInf)
-    Mask |= kfcInf;
-  if (Classes & fcNormal)
-    Mask |= kfcNormal;
-  if (Classes & fcSubnormal)
-    Mask |= kfcSubnormal;
-  if (Classes & fcZero)
-    Mask |= kfcZero;
-
-  return Mask;
-}
+  static constexpr FPClassMask toFPClassMask(FPClassTest Classes,
+                                             bool SignBit) {
+    FPClassMask Mask = toFPClassMask(Classes);
+
+    // This is the only way to generate a NaN with a specific sign from
+    // FPClassTest. SignBit must agree with the input classes.
+    if (!SignBit) {
+      Mask &= ~FPClassMask::kfcNegNan;
+      // If the SignBit is false, then we should not have any negative classes.
+      if ((Mask & FPClassMask::kfcNegSignBit) == FPClassMask::kfcNone)
+        return Mask;
+    } else {
+      Mask &= ~FPClassMask::kfcPosNan;
+      // If the SignBit is true, then we should not have any positive classes.
+      if ((Mask & FPClassMask::kfcPosSignBit) == FPClassMask::kfcNone)
+        return Mask;
+    }
 
-constexpr FPClassTest toFPClassTest(FPClassMask Mask) {
-  FPClassTest Classes = fcNone;
-
-  // Sign of qNaN and sNaN are lost in the conversion.
-  if (Mask & kfcQNan)
-    Classes |= fcQNan;
-  if (Mask & kfcSNan)
-    Classes |= fcSNan;
-
-  if (Mask & kfcNegInf)
-    Classes |= fcNegInf;
-  if (Mask & kfcNegNormal)
-    Classes |= fcNegNormal;
-  if (Mask & kfcNegSubnormal)
-    Classes |= fcNegSubnormal;
-  if (Mask & kfcNegZero)
-    Classes |= fcNegZero;
-  if (Mask & kfcPosZero)
-    Classes |= fcPosZero;
-  if (Mask & kfcPosSubnormal)
-    Classes |= fcPosSubnormal;
-  if (Mask & kfcPosNormal)
-    Classes |= fcPosNormal;
-  if (Mask & kfcPosInf)
-    Classes |= fcPosInf;
-
-  return Classes;
-}
+    // SignBit is unknown or inconsistent with the input classes. Expand the
+    // possible set to its opposite sign pair.
+    if (Classes & fcQNan)
+      Mask |= FPClassMask::kfcQNan;
+    if (Classes & fcSNan)
+      Mask |= FPClassMask::kfcSNan;
+    if (Classes & fcInf)
+      Mask |= FPClassMask::kfcInf;
+    if (Classes & fcNormal)
+      Mask |= FPClassMask::kfcNormal;
+    if (Classes & fcSubnormal)
+      Mask |= FPClassMask::kfcSubnormal;
+    if (Classes & fcZero)
+      Mask |= FPClassMask::kfcZero;
+
+    return Mask;
+  }
 
-class KnownFPClass {
-  FPClassMask KnownFPMask = kfcAllFlags;
+  static constexpr FPClassTest toFPClassTest(FPClassMask Mask) {
+    FPClassTest Classes = fcNone;
+
+    // Sign of qNaN and sNaN are lost in the conversion.
+    if ((Mask & FPClassMask::kfcQNan) != FPClassMask::kfcNone)
+      Classes |= fcQNan;
+    if ((Mask & FPClassMask::kfcSNan) != FPClassMask::kfcNone)
+      Classes |= fcSNan;
+
+    if ((Mask & FPClassMask::kfcNegInf) != FPClassMask::kfcNone)
+      Classes |= fcNegInf;
+    if ((Mask & FPClassMask::kfcNegNormal) != FPClassMask::kfcNone)
+      Classes |= fcNegNormal;
+    if ((Mask & FPClassMask::kfcNegSubnormal) != FPClassMask::kfcNone)
+      Classes |= fcNegSubnormal;
+    if ((Mask & FPClassMask::kfcNegZero) != FPClassMask::kfcNone)
+      Classes |= fcNegZero;
+    if ((Mask & FPClassMask::kfcPosZero) != FPClassMask::kfcNone)
+      Classes |= fcPosZero;
+    if ((Mask & FPClassMask::kfcPosSubnormal) != FPClassMask::kfcNone)
+      Classes |= fcPosSubnormal;
+    if ((Mask & FPClassMask::kfcPosNormal) != FPClassMask::kfcNone)
+      Classes |= fcPosNormal;
+    if ((Mask & FPClassMask::kfcPosInf) != FPClassMask::kfcNone)
+      Classes |= fcPosInf;
+
+    return Classes;
+  }
 
 public:
   /// Floating-point classes the value could be one of.
@@ -168,12 +170,12 @@ class KnownFPClass {
   /// definitely set or false if the sign bit is definitely unset.
   /// By convention, returns false for kfcNone/poison.
   std::optional<bool> getSignBit() const {
-    if (KnownFPMask == kfcNone)
+    if (KnownFPMask == FPClassMask::kfcNone)
       return false;
 
-    if ((KnownFPMask & kfcPosSignBit) == KnownFPMask)
+    if ((KnownFPMask & FPClassMask::kfcPosSignBit) == KnownFPMask)
       return false;
-    if ((KnownFPMask & kfcNegSignBit) == KnownFPMask)
+    if ((KnownFPMask & FPClassMask::kfcNegSignBit) == KnownFPMask)
       return true;
 
     return std::nullopt;
@@ -181,29 +183,30 @@ class KnownFPClass {
 
   void setSignBit(std::optional<bool> Sign) {
     if (Sign && !*Sign) {
-      KnownFPMask &= kfcPosSignBit;
+      KnownFPMask &= FPClassMask::kfcPosSignBit;
       return;
     }
     if (Sign && *Sign) {
-      KnownFPMask &= kfcNegSignBit;
+      KnownFPMask &= FPClassMask::kfcNegSignBit;
       return;
     }
     // Set sign to unknown.
-    if (KnownFPMask & kfcQNan)
-      KnownFPMask |= kfcQNan;
-    if (KnownFPMask & kfcSNan)
-      KnownFPMask |= kfcSNan;
-    if (KnownFPMask & kfcInf)
-      KnownFPMask |= kfcInf;
-    if (KnownFPMask & kfcNormal)
-      KnownFPMask |= kfcNormal;
-    if (KnownFPMask & kfcSubnormal)
-      KnownFPMask |= kfcSubnormal;
-    if (KnownFPMask & kfcZero)
-      KnownFPMask |= kfcZero;
+    if ((KnownFPMask & FPClassMask::kfcQNan) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcQNan;
+    if ((KnownFPMask & FPClassMask::kfcSNan) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcSNan;
+    if ((KnownFPMask & FPClassMask::kfcInf) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcInf;
+    if ((KnownFPMask & FPClassMask::kfcNormal) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcNormal;
+    if ((KnownFPMask & FPClassMask::kfcSubnormal) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcSubnormal;
+    if ((KnownFPMask & FPClassMask::kfcZero) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcZero;
   }
 
-  KnownFPClass(FPClassMask Known = kfcAllFlags) : KnownFPMask(Known) {}
+  KnownFPClass(FPClassMask Known = FPClassMask::kfcAllFlags)
+      : KnownFPMask(Known) {}
   KnownFPClass(FPClassTest Known) : KnownFPMask(toFPClassMask(Known)) {}
   KnownFPClass(FPClassTest Known, bool Sign)
       : KnownFPMask(toFPClassMask(Known, Sign)) {}
@@ -215,7 +218,7 @@ class KnownFPClass {
 
   /// Return true if it's known this can never be one of the mask entries.
   bool isKnownNever(FPClassMask Mask) const {
-    return (KnownFPMask & Mask) == kfcNone;
+    return (KnownFPMask & Mask) == FPClassMask::kfcNone;
   }
 
   /// Return true if it's known this can never be one of the mask entries.
@@ -229,7 +232,7 @@ class KnownFPClass {
     return isKnownAlways(toFPClassMask(Mask));
   }
 
-  bool isUnknown() const { return KnownFPMask == kfcAllFlags; }
+  bool isUnknown() const { return KnownFPMask == FPClassMask::kfcAllFlags; }
 
   /// Return true if it's known this can never be a nan.
   bool isKnownNeverNaN() const { return isKnownNever(fcNan); }
@@ -360,32 +363,32 @@ class KnownFPClass {
   void knownNot(FPClassTest RuleOut) { knownNot(toFPClassMask(RuleOut)); }
 
   void fneg() {
-    FPClassMask Known = kfcNone;
-
-    if (KnownFPMask & kfcNegQNan)
-      Known |= kfcPosQNan;
-    if (KnownFPMask & kfcNegSNan)
-      Known |= kfcPosSNan;
-    if (KnownFPMask & kfcNegInf)
-      Known |= kfcPosInf;
-    if (KnownFPMask & kfcNegNormal)
-      Known |= kfcPosNormal;
-    if (KnownFPMask & kfcNegSubnormal)
-      Known |= kfcPosSubnormal;
-    if (KnownFPMask & kfcNegZero)
-      Known |= kfcPosZero;
-    if (KnownFPMask & kfcPosZero)
-      Known |= kfcNegZero;
-    if (KnownFPMask & kfcPosSubnormal)
-      Known |= kfcNegSubnormal;
-    if (KnownFPMask & kfcPosNormal)
-      Known |= kfcNegNormal;
-    if (KnownFPMask & kfcPosInf)
-      Known |= kfcNegInf;
-    if (KnownFPMask & kfcPosSNan)
-      Known |= kfcNegSNan;
-    if (KnownFPMask & kfcPosQNan)
-      Known |= kfcNegQNan;
+    FPClassMask Known = FPClassMask::kfcNone;
+
+    if ((KnownFPMask & FPClassMask::kfcNegQNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosQNan;
+    if ((KnownFPMask & FPClassMask::kfcNegSNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosSNan;
+    if ((KnownFPMask & FPClassMask::kfcNegInf) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosInf;
+    if ((KnownFPMask & FPClassMask::kfcNegNormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosNormal;
+    if ((KnownFPMask & FPClassMask::kfcNegSubnormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosSubnormal;
+    if ((KnownFPMask & FPClassMask::kfcNegZero) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosZero;
+    if ((KnownFPMask & FPClassMask::kfcPosZero) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegZero;
+    if ((KnownFPMask & FPClassMask::kfcPosSubnormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegSubnormal;
+    if ((KnownFPMask & FPClassMask::kfcPosNormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegNormal;
+    if ((KnownFPMask & FPClassMask::kfcPosInf) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegInf;
+    if ((KnownFPMask & FPClassMask::kfcPosSNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegSNan;
+    if ((KnownFPMask & FPClassMask::kfcPosQNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcNegQNan;
 
     KnownFPMask = Known;
   }
@@ -397,20 +400,20 @@ class KnownFPClass {
   }
 
   void fabs() {
-    FPClassMask Known = kfcNone;
-
-    if (KnownFPMask & kfcQNan)
-      Known |= kfcPosQNan;
-    if (KnownFPMask & kfcSNan)
-      Known |= kfcPosSNan;
-    if (KnownFPMask & kfcInf)
-      Known |= kfcPosInf;
-    if (KnownFPMask & kfcNormal)
-      Known |= kfcPosNormal;
-    if (KnownFPMask & kfcSubnormal)
-      Known |= kfcPosSubnormal;
-    if (KnownFPMask & kfcZero)
-      Known |= kfcPosZero;
+    FPClassMask Known = FPClassMask::kfcNone;
+
+    if ((KnownFPMask & FPClassMask::kfcQNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosQNan;
+    if ((KnownFPMask & FPClassMask::kfcSNan) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosSNan;
+    if ((KnownFPMask & FPClassMask::kfcInf) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosInf;
+    if ((KnownFPMask & FPClassMask::kfcNormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosNormal;
+    if ((KnownFPMask & FPClassMask::kfcSubnormal) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosSubnormal;
+    if ((KnownFPMask & FPClassMask::kfcZero) != FPClassMask::kfcNone)
+      Known |= FPClassMask::kfcPosZero;
 
     KnownFPMask = Known;
   }
@@ -561,32 +564,32 @@ class KnownFPClass {
   bool signBitIsZeroOrNaN() const { return isKnownNever(fcNegative); }
 
   /// Assume the sign bit is zero.
-  void signBitMustBeZero() { KnownFPMask &= kfcPosSignBit; }
+  void signBitMustBeZero() { KnownFPMask &= FPClassMask::kfcPosSignBit; }
 
   /// Assume the sign bit is one.
-  void signBitMustBeOne() { KnownFPMask &= kfcNegSignBit; }
+  void signBitMustBeOne() { KnownFPMask &= FPClassMask::kfcNegSignBit; }
 
   void copysign(const KnownFPClass &Sign) {
     // Don't know anything about the sign of the source. Expand the possible set
     // to its opposite sign pair.
 
-    if (KnownFPMask & kfcQNan)
-      KnownFPMask |= kfcQNan;
-    if (KnownFPMask & kfcSNan)
-      KnownFPMask |= kfcSNan;
-    if (KnownFPMask & kfcInf)
-      KnownFPMask |= kfcInf;
-    if (KnownFPMask & kfcNormal)
-      KnownFPMask |= kfcNormal;
-    if (KnownFPMask & kfcSubnormal)
-      KnownFPMask |= kfcSubnormal;
-    if (KnownFPMask & kfcZero)
-      KnownFPMask |= kfcZero;
+    if ((KnownFPMask & FPClassMask::kfcQNan) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcQNan;
+    if ((KnownFPMask & FPClassMask::kfcSNan) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcSNan;
+    if ((KnownFPMask & FPClassMask::kfcInf) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcInf;
+    if ((KnownFPMask & FPClassMask::kfcNormal) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcNormal;
+    if ((KnownFPMask & FPClassMask::kfcSubnormal) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcSubnormal;
+    if ((KnownFPMask & FPClassMask::kfcZero) != FPClassMask::kfcNone)
+      KnownFPMask |= FPClassMask::kfcZero;
 
     if (Sign.getSignBit() && !*Sign.getSignBit())
-      KnownFPMask &= kfcPosSignBit;
+      KnownFPMask &= FPClassMask::kfcPosSignBit;
     if (Sign.getSignBit() && *Sign.getSignBit())
-      KnownFPMask &= kfcNegSignBit;
+      KnownFPMask &= FPClassMask::kfcNegSignBit;
   }
 
   static KnownFPClass copysign(const KnownFPClass &KnownMag,
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 6b040b9015970..947f7d6184062 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -985,10 +985,10 @@ KnownFPClass KnownFPClass::fpext(const KnownFPClass &KnownSrc,
   }
 
   // Sign bit of a nan isn't guaranteed.
-  if (Known.KnownFPMask & kfcSNan)
-    Known.KnownFPMask |= kfcSNan;
-  if (Known.KnownFPMask & kfcQNan)
-    Known.KnownFPMask |= kfcQNan;
+  if (!Known.isKnownNever(fcSNan))
+    Known.setKnownFPClasses(Known.getKnownFPClasses() | fcSNan);
+  if (!Known.isKnownNever(fcQNan))
+    Known.setKnownFPClasses(Known.getKnownFPClasses() | fcQNan);
 
   return Known;
 }

>From 052ffb88c3bef9613fdc2a3e2982bf179abba44f Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Sun, 4 Oct 2026 17:27:58 -0600
Subject: [PATCH 4/4] Update applyDenormalMode helpers

---
 llvm/lib/Support/KnownFPClass.cpp | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 947f7d6184062..c2799d54b3329 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -34,18 +34,12 @@ KnownFPClass KnownFPClass::applyInputDenormalMode(const KnownFPClass &KnownSrc,
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
     return Known;
   case DenormalMode::PositiveZero:
-    if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
+    if (KnownSrc.getKnownFPClasses() & fcSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
-      if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
-        Known.setSignBit(std::nullopt);
-    }
     return Known;
   default:
-    if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
+    if (KnownSrc.getKnownFPClasses() & fcSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
-      if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
-        Known.setSignBit(std::nullopt);
-    }
     if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
     return Known;
@@ -67,18 +61,12 @@ KnownFPClass KnownFPClass::applyOutputDenormalMode(const KnownFPClass &KnownSrc,
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
     return Known;
   case DenormalMode::PositiveZero:
-    if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
+    if (KnownSrc.getKnownFPClasses() & fcSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
-      if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
-        Known.setSignBit(std::nullopt);
-    }
     return Known;
   default:
-    if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
+    if (KnownSrc.getKnownFPClasses() & fcSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
-      if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
-        Known.setSignBit(std::nullopt);
-    }
     if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
       Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
     return Known;



More information about the llvm-commits mailing list