[libc-commits] [libc] [libc] Add compound assignment operator overloads for BFloat16 (PR #201301)

via libc-commits libc-commits at lists.llvm.org
Wed Jun 3 04:52:46 PDT 2026


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

>From 56ee4e624bb0075b31ae133131d5688fa5f332f4 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 15:03:17 +0530
Subject: [PATCH 1/4] feat:const Bfloat16 & + additional operator + smoke

---
 libc/src/__support/FPUtil/bfloat16.h          | 32 ++++++++++-----
 .../src/__support/FPUtil/bfloat16_test.cpp    | 39 ++++++++++++++++++-
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 638500d94cef2..0816d3442b8fc 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -68,27 +68,27 @@ struct BFloat16 {
     return static_cast<T>(static_cast<float>(*this));
   }
 
-  LIBC_INLINE constexpr bool operator==(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator==(const BFloat16 &other) const {
     return fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator!=(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator!=(const BFloat16 &other) const {
     return !fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator<(const BFloat16 &other) const {
     return fputil::less_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<=(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator<=(const BFloat16 &other) const {
     return fputil::less_than_or_equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator>(const BFloat16 &other) const {
     return fputil::greater_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>=(BFloat16 other) const {
+  LIBC_INLINE constexpr bool operator>=(const BFloat16 &other) const {
     return fputil::greater_than_or_equals(*this, other);
   }
 
@@ -98,19 +98,19 @@ struct BFloat16 {
     return result.get_val();
   }
 
-  LIBC_INLINE constexpr BFloat16 operator+(BFloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator+(const BFloat16 &other) const {
     return fputil::generic::add<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator-(BFloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator-(const BFloat16 &other) const {
     return fputil::generic::sub<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator*(BFloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator*(const BFloat16 &other) const {
     return fputil::generic::mul<bfloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator/(BFloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator/(const BFloat16 &other) const {
     return fputil::generic::div<bfloat16>(*this, other);
   }
 
@@ -118,6 +118,18 @@ struct BFloat16 {
     *this = *this * other;
     return *this;
   }
+  LIBC_INLINE constexpr BFloat16 &operator+=(const BFloat16 &other) {
+    *this = *this + other;
+    return *this;
+  }
+  LIBC_INLINE constexpr BFloat16 &operator-=(const BFloat16 &other) {
+    *this = *this - other;
+    return *this;
+  }
+  LIBC_INLINE constexpr BFloat16 &operator/=(const BFloat16 &other) {
+    *this = *this / other;
+    return *this;
+  }
 }; // struct BFloat16
 
 } // namespace fputil
diff --git a/libc/test/src/__support/FPUtil/bfloat16_test.cpp b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
index 8760b2abe3ce3..9ea97ad842d5f 100644
--- a/libc/test/src/__support/FPUtil/bfloat16_test.cpp
+++ b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
@@ -68,12 +68,13 @@ TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
   }
 }
 
-TEST_F(LlvmLibcBfloat16ConversionTest, MultiplyAssign) {
+TEST_F(LlvmLibcBfloat16ConversionTest, shortHandOperators) {
 
   constexpr BFloat16 VAL[] = {zero,           neg_zero,        inf,
                               neg_inf,        min_normal,      max_normal,
                               bfloat16(1.0f), bfloat16(-1.0f), bfloat16(2.0f),
                               bfloat16(3.0f)};
+  // *=
   for (const bfloat16 &x : VAL) {
     for (const bfloat16 &y : VAL) {
       BFloat16 a = x, b = y;
@@ -85,4 +86,40 @@ TEST_F(LlvmLibcBfloat16ConversionTest, MultiplyAssign) {
       EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
     }
   }
+  // /=
+  for (const bfloat16 &x : VAL) {
+    for (const bfloat16 &y : VAL) {
+      BFloat16 a = x, b = y;
+      MPFRNumber mpfr_a{a}, mpfr_b{b};
+      MPFRNumber mpfr_c = mpfr_a.div(mpfr_b);
+      BFloat16 mpfr_bfloat = mpfr_c.as<BFloat16>();
+      a /= b;
+      BFloat16 libc_bfloat = a;
+      EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+    }
+  }
+  // +=
+  for (const bfloat16 &x : VAL) {
+    for (const bfloat16 &y : VAL) {
+      BFloat16 a = x, b = y;
+      MPFRNumber mpfr_a{a}, mpfr_b{b};
+      MPFRNumber mpfr_c = mpfr_a.add(mpfr_b);
+      BFloat16 mpfr_bfloat = mpfr_c.as<BFloat16>();
+      a += b;
+      BFloat16 libc_bfloat = a;
+      EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+    }
+  }
+  // -=
+  for (const bfloat16 &x : VAL) {
+    for (const bfloat16 &y : VAL) {
+      BFloat16 a = x, b = y;
+      MPFRNumber mpfr_a{a}, mpfr_b{b};
+      MPFRNumber mpfr_c = mpfr_a.sub(mpfr_b);
+      BFloat16 mpfr_bfloat = mpfr_c.as<BFloat16>();
+      a -= b;
+      BFloat16 libc_bfloat = a;
+      EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+    }
+  }
 }

>From 2ccfcd81ae16e441d6f2af46ab42b1e6f74c5650 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 17:13:46 +0530
Subject: [PATCH 2/4] switch to pass-by-val

---
 libc/src/__support/FPUtil/bfloat16.h | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 0816d3442b8fc..eae6b6e27a6d2 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -68,27 +68,27 @@ struct BFloat16 {
     return static_cast<T>(static_cast<float>(*this));
   }
 
-  LIBC_INLINE constexpr bool operator==(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator==(Bfloat16 other) const {
     return fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator!=(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator!=(Bfloat16 other) const {
     return !fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator<(Bfloat16 other) const {
     return fputil::less_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<=(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator<=(Bfloat16 other) const {
     return fputil::less_than_or_equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator>(Bfloat16 other) const {
     return fputil::greater_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>=(const BFloat16 &other) const {
+  LIBC_INLINE constexpr bool operator>=(Bfloat16 other) const {
     return fputil::greater_than_or_equals(*this, other);
   }
 
@@ -98,35 +98,35 @@ struct BFloat16 {
     return result.get_val();
   }
 
-  LIBC_INLINE constexpr BFloat16 operator+(const BFloat16 &other) const {
+  LIBC_INLINE constexpr BFloat16 operator+(Bfloat16 other) const {
     return fputil::generic::add<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator-(const BFloat16 &other) const {
+  LIBC_INLINE constexpr BFloat16 operator-(Bfloat16 other) const {
     return fputil::generic::sub<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator*(const BFloat16 &other) const {
+  LIBC_INLINE constexpr BFloat16 operator*(Bfloat16 other) const {
     return fputil::generic::mul<bfloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator/(const BFloat16 &other) const {
+  LIBC_INLINE constexpr BFloat16 operator/(Bfloat16 other) const {
     return fputil::generic::div<bfloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 &operator*=(const BFloat16 &other) {
+  LIBC_INLINE constexpr BFloat16 &operator*=(Bfloat16 other) {
     *this = *this * other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator+=(const BFloat16 &other) {
+  LIBC_INLINE constexpr BFloat16 &operator+=(Bfloat16 other) {
     *this = *this + other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator-=(const BFloat16 &other) {
+  LIBC_INLINE constexpr BFloat16 &operator-=(Bfloat16 other) {
     *this = *this - other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator/=(const BFloat16 &other) {
+  LIBC_INLINE constexpr BFloat16 &operator/=(Bfloat16 other) {
     *this = *this / other;
     return *this;
   }

>From 78930eeeaa7803c6dd567879dfaae1052124d589 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 17:15:19 +0530
Subject: [PATCH 3/4] chore: rename

---
 libc/test/src/__support/FPUtil/bfloat16_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/__support/FPUtil/bfloat16_test.cpp b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
index 9ea97ad842d5f..28333cfc18441 100644
--- a/libc/test/src/__support/FPUtil/bfloat16_test.cpp
+++ b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
@@ -68,7 +68,7 @@ TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
   }
 }
 
-TEST_F(LlvmLibcBfloat16ConversionTest, shortHandOperators) {
+TEST_F(LlvmLibcBfloat16ConversionTest, compoundAssignmentOperators) {
 
   constexpr BFloat16 VAL[] = {zero,           neg_zero,        inf,
                               neg_inf,        min_normal,      max_normal,

>From 6ce243b008771897c038622739cb6811577fb383 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 17:22:24 +0530
Subject: [PATCH 4/4] nit

---
 libc/src/__support/FPUtil/bfloat16.h | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index eae6b6e27a6d2..ce4e3160a0963 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -68,27 +68,27 @@ struct BFloat16 {
     return static_cast<T>(static_cast<float>(*this));
   }
 
-  LIBC_INLINE constexpr bool operator==(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator==(BFloat16 other) const {
     return fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator!=(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator!=(BFloat16 other) const {
     return !fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator<(BFloat16 other) const {
     return fputil::less_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<=(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator<=(BFloat16 other) const {
     return fputil::less_than_or_equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator>(BFloat16 other) const {
     return fputil::greater_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>=(Bfloat16 other) const {
+  LIBC_INLINE constexpr bool operator>=(BFloat16 other) const {
     return fputil::greater_than_or_equals(*this, other);
   }
 
@@ -98,35 +98,35 @@ struct BFloat16 {
     return result.get_val();
   }
 
-  LIBC_INLINE constexpr BFloat16 operator+(Bfloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator+(BFloat16 other) const {
     return fputil::generic::add<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator-(Bfloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator-(BFloat16 other) const {
     return fputil::generic::sub<BFloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator*(Bfloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator*(BFloat16 other) const {
     return fputil::generic::mul<bfloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 operator/(Bfloat16 other) const {
+  LIBC_INLINE constexpr BFloat16 operator/(BFloat16 other) const {
     return fputil::generic::div<bfloat16>(*this, other);
   }
 
-  LIBC_INLINE constexpr BFloat16 &operator*=(Bfloat16 other) {
+  LIBC_INLINE constexpr BFloat16 &operator*=(BFloat16 other) {
     *this = *this * other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator+=(Bfloat16 other) {
+  LIBC_INLINE constexpr BFloat16 &operator+=(BFloat16 other) {
     *this = *this + other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator-=(Bfloat16 other) {
+  LIBC_INLINE constexpr BFloat16 &operator-=(BFloat16 other) {
     *this = *this - other;
     return *this;
   }
-  LIBC_INLINE constexpr BFloat16 &operator/=(Bfloat16 other) {
+  LIBC_INLINE constexpr BFloat16 &operator/=(BFloat16 other) {
     *this = *this / other;
     return *this;
   }



More information about the libc-commits mailing list