[llvm-branch-commits] [libc] [libc] Add Operator Overloads for Float80 (PR #214493)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 13 07:55:42 PDT 2026


https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/214493

>From deeb89ab7c9a442dc2e85516c7419e27d0a5a55a Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 19:11:47 +0530
Subject: [PATCH 1/3] feat: add negation and a test for it

---
 libc/src/__support/FPUtil/float80.h             | 7 +++++++
 libc/test/src/__support/FPUtil/float80_test.cpp | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
index d6823f7bedb76..98d2a579c4f3d 100644
--- a/libc/src/__support/FPUtil/float80.h
+++ b/libc/src/__support/FPUtil/float80.h
@@ -95,6 +95,13 @@ struct Float80 {
         x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
     return static_cast<T>(xd.as_mantissa_type());
   }
+
+  // unary operators
+  LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float80 operator-() const {
+    fputil::FPBits<Float80> result(*this);
+    result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+    return result.get_val();
+  }
 };
 
 static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index 68b38a63c23b4..ef0b34df8044d 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -21,7 +21,9 @@ TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
 TEST(LlvmLibcFloat80Test, IntegerConversion) {
   // Float80 to Integer conversion test
   ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0);
+  ASSERT_EQ(static_cast<int>(Float80(-0.0f)), 0);
   ASSERT_EQ(static_cast<int>(Float80(1.0f)), 1);
+  ASSERT_EQ(static_cast<int>(Float80(-1.0f)), -1);
   ASSERT_EQ(static_cast<long long>(Float80(1000000000.0)),
             static_cast<long long>(1000000000));
   ASSERT_EQ(static_cast<unsigned>(Float80(7.0f)), 7U);

>From 0e3c5815d36496e3d0bd1c09fc2f6e3650f77dea Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 21:03:12 +0530
Subject: [PATCH 2/3] add tests

---
 libc/src/__support/FPUtil/float80.h           | 21 +++++++++++++++++++
 .../src/__support/FPUtil/float80_test.cpp     | 13 ++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
index 98d2a579c4f3d..726f15a06520a 100644
--- a/libc/src/__support/FPUtil/float80.h
+++ b/libc/src/__support/FPUtil/float80.h
@@ -101,6 +101,27 @@ struct Float80 {
     fputil::FPBits<Float80> result(*this);
     result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
     return result.get_val();
+
+    // operator overloads
+    LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
+      return fputil::generic::add<Float80>(*this, other);
+    }
+
+    LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
+      return fputil::generic::sub<Float80>(*this, other);
+    }
+
+    LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
+      return fputil::generic::mul<Float80>(*this, other);
+    }
+
+    LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
+      return fputil::generic::div<Float80>(*this, other);
+    }
+
+    LIBC_INLINE constexpr bool operator==(const Float128 &other) const {
+      return fputil::equals(*this, other);
+    }
   }
 };
 
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index ef0b34df8044d..ae5623bf2b759 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -18,6 +18,19 @@ using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
 TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
 
+TEST(LlvmLibcFloat80Test, Operators) {
+  Float80 a(1.0f), b(1.0f), c(2.0f), d(3.0f), pa(1.0f), na(-1.0f);
+
+  // Unary operators
+  ASSERT_TRUE(FPBits(-pa) == FPBits(na));
+
+  // Binary operators
+  ASSERT_TRUE(a + b == c);
+  ASSERT_TRUE(a - b == Float128(0.0));
+  ASSERT_TRUE(c * d == Float128(6.0));
+  ASSERT_TRUE(Float80(6.0f) / d) == Float80(2.0f);
+}
+
 TEST(LlvmLibcFloat80Test, IntegerConversion) {
   // Float80 to Integer conversion test
   ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0);

>From d5f681872abb740d7957afb93c336c95600b7533 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 13 Aug 2026 20:25:20 +0530
Subject: [PATCH 3/3] suggestions and add more operators

---
 libc/src/__support/FPUtil/float80.h           | 56 +++++++++++++------
 .../src/__support/FPUtil/float80_test.cpp     | 39 +++++++++++--
 2 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
index 726f15a06520a..cb8dc618c9280 100644
--- a/libc/src/__support/FPUtil/float80.h
+++ b/libc/src/__support/FPUtil/float80.h
@@ -14,6 +14,7 @@
 #include "src/__support/FPUtil/cast.h"
 #include "src/__support/FPUtil/comparison_operations.h"
 #include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/float128.h"
 #include "src/__support/FPUtil/generic/add_sub.h"
 #include "src/__support/FPUtil/generic/div.h"
 #include "src/__support/FPUtil/generic/mul.h"
@@ -101,27 +102,50 @@ struct Float80 {
     fputil::FPBits<Float80> result(*this);
     result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
     return result.get_val();
+  }
+  LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
+    return fputil::generic::add<Float80>(fputil::cast<Float128>(*this),
+                                         fputil::cast<Float128>(other));
+  }
 
-    // operator overloads
-    LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
-      return fputil::generic::add<Float80>(*this, other);
-    }
+  LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
+    return fputil::generic::sub<Float80>(fputil::cast<Float128>(*this),
+                                         fputil::cast<Float128>(other));
+  }
 
-    LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
-      return fputil::generic::sub<Float80>(*this, other);
-    }
+  LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
+    return fputil::generic::mul<Float80>(fputil::cast<Float128>(*this),
+                                         fputil::cast<Float128>(other));
+  }
 
-    LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
-      return fputil::generic::mul<Float80>(*this, other);
-    }
+  LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
+    return fputil::generic::div<Float80>(fputil::cast<Float128>(*this),
+                                         fputil::cast<Float128>(other));
+  }
 
-    LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
-      return fputil::generic::div<Float80>(*this, other);
-    }
+  // Comparison operators
+  LIBC_INLINE constexpr bool operator==(const Float80 &other) const {
+    return fputil::equals(*this, other);
+  }
 
-    LIBC_INLINE constexpr bool operator==(const Float128 &other) const {
-      return fputil::equals(*this, other);
-    }
+  LIBC_INLINE constexpr bool operator!=(const Float80 &other) const {
+    return !fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<(const Float80 &other) const {
+    return fputil::less_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<=(const Float80 &other) const {
+    return fputil::less_than_or_equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>(const Float80 &other) const {
+    return fputil::greater_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>=(const Float80 &other) const {
+    return fputil::greater_than_or_equals(*this, other);
   }
 };
 
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index ae5623bf2b759..86312b2f1440e 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -16,19 +16,48 @@ using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
 using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
+// will be removed
 TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
 
 TEST(LlvmLibcFloat80Test, Operators) {
   Float80 a(1.0f), b(1.0f), c(2.0f), d(3.0f), pa(1.0f), na(-1.0f);
 
+  // comparison operators
+  ASSERT_TRUE(a == b);
+  ASSERT_TRUE(a == Float80(1.0));
+  ASSERT_TRUE(a != c);
+  ASSERT_TRUE(b != c);
+  ASSERT_TRUE(c > b);
+  ASSERT_TRUE(a >= b);
+  ASSERT_TRUE(b <= c);
+  ASSERT_TRUE(a < c);
+
   // Unary operators
-  ASSERT_TRUE(FPBits(-pa) == FPBits(na));
+  ASSERT_TRUE(-pa == na);
+  ASSERT_TRUE(-(-pa) == pa);
 
   // Binary operators
-  ASSERT_TRUE(a + b == c);
-  ASSERT_TRUE(a - b == Float128(0.0));
-  ASSERT_TRUE(c * d == Float128(6.0));
-  ASSERT_TRUE(Float80(6.0f) / d) == Float80(2.0f);
+  ASSERT_TRUE((a + b) == c);
+  ASSERT_TRUE((a - b) == Float80(0.0f));
+  ASSERT_TRUE((c * d) == Float80(6.0f));
+  ASSERT_TRUE((Float80(6.0f) / d) == Float80(2.0f));
+}
+
+TEST(LlvmLibcFloat80Test, SpecialValues) {
+  Float80 inf = FPBits::inf(Sign::POS).get_val();
+  Float80 neg_inf = FPBits::inf(Sign::NEG).get_val();
+  Float80 nan = FPBits::quiet_nan().get_val();
+
+  // checking operators with special values
+  ASSERT_TRUE(Float80(0.0f) == Float80(-0.0f)); // +0.0 == -0.0 is true
+  ASSERT_TRUE(Float80(0.0f) == Float80(0.0f));
+  ASSERT_TRUE(inf == inf);
+  ASSERT_TRUE(-inf == neg_inf);
+  ASSERT_TRUE((inf + Float80(1.0f)) == inf);
+  ASSERT_TRUE(inf + inf == inf);
+  ASSERT_TRUE(nan != nan);
+  ASSERT_TRUE(!(nan == nan));
+  ASSERT_TRUE(nan != Float80(0.0f));
 }
 
 TEST(LlvmLibcFloat80Test, IntegerConversion) {



More information about the llvm-branch-commits mailing list