[libc-commits] [libc] Bfloat16 `*= (Multiply assign)` operator support (PR #182882)

via libc-commits libc-commits at lists.llvm.org
Mon Feb 23 08:27:22 PST 2026


https://github.com/Sukumarsawant created https://github.com/llvm/llvm-project/pull/182882

This PR intends to add *= operator support for Bfloat16 and tests for it .


>From 2b6c56d51810ef0f5e9f830dfc4aa04022530cd3 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Mon, 23 Feb 2026 21:29:54 +0530
Subject: [PATCH 1/2] initial commit for Bfloat16 changes

---
 libc/src/__support/FPUtil/bfloat16.h          |   5 +
 .../src/__support/FPUtil/bfloat16_test.cpp    | 154 ++++++++++--------
 2 files changed, 90 insertions(+), 69 deletions(-)

diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 13e151208567d..7d64b441bf9b2 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -113,6 +113,11 @@ struct BFloat16 {
   LIBC_INLINE BFloat16 operator/(BFloat16 other) const {
     return fputil::generic::div<bfloat16>(*this, other);
   }
+
+  LIBC_INLINE 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 a71d971a9ad3d..820e384e20285 100644
--- a/libc/test/src/__support/FPUtil/bfloat16_test.cpp
+++ b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
@@ -1,69 +1,85 @@
-//===-- Unit tests for bfloat16 type --------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/FPUtil/bfloat16.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPCommon.h"
-
-using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;
-using LlvmLibcBfloat16ConversionTest =
-    LIBC_NAMESPACE::testing::FPTest<BFloat16>;
-
-// range: [0, inf]
-static constexpr uint16_t POS_START = 0x0000U;
-static constexpr uint16_t POS_STOP = 0x7f80U;
-
-// range: [-0, -inf]
-static constexpr uint16_t NEG_START = 0x8000U;
-static constexpr uint16_t NEG_STOP = 0xff80U;
-
-using MPFRNumber = LIBC_NAMESPACE::testing::mpfr::MPFRNumber;
-
-TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatPositiveRange) {
-  for (uint16_t bits = POS_START; bits <= POS_STOP; bits++) {
-    BFloat16 bf16_num{bits};
-    MPFRNumber mpfr_num{bf16_num};
-
-    // bfloat16 to float
-    float mpfr_float = mpfr_num.as<float>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
-
-    // float to bfloat16
-    BFloat16 bf16_from_float{mpfr_float};
-    MPFRNumber mpfr_num_2{mpfr_float};
-    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
-  }
-}
-
-TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatNegativeRange) {
-  for (uint16_t bits = NEG_START; bits <= NEG_STOP; bits++) {
-    BFloat16 bf16_num{bits};
-    MPFRNumber mpfr_num{bf16_num};
-
-    // bfloat16 to float
-    float mpfr_float = mpfr_num.as<float>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
-
-    // float to bfloat16
-    BFloat16 bf16_from_float{mpfr_float};
-    MPFRNumber mpfr_num_2{mpfr_float};
-    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
-  }
-}
-
-TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
-  constexpr int RANGE = 100'000;
-  for (int i = -RANGE; i <= RANGE; i++) {
-    BFloat16 mpfr_bfloat = MPFRNumber(i).as<BFloat16>();
-    BFloat16 libc_bfloat{i};
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
-  }
-}
+//===-- Unit tests for bfloat16 type --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+
+using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;
+using LlvmLibcBfloat16ConversionTest =
+    LIBC_NAMESPACE::testing::FPTest<BFloat16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+using MPFRNumber = LIBC_NAMESPACE::testing::mpfr::MPFRNumber;
+
+TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatPositiveRange) {
+  for (uint16_t bits = POS_START; bits <= POS_STOP; bits++) {
+    BFloat16 bf16_num{bits};
+    MPFRNumber mpfr_num{bf16_num};
+
+    // bfloat16 to float
+    float mpfr_float = mpfr_num.as<float>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
+
+    // float to bfloat16
+    BFloat16 bf16_from_float{mpfr_float};
+    MPFRNumber mpfr_num_2{mpfr_float};
+    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatNegativeRange) {
+  for (uint16_t bits = NEG_START; bits <= NEG_STOP; bits++) {
+    BFloat16 bf16_num{bits};
+    MPFRNumber mpfr_num{bf16_num};
+
+    // bfloat16 to float
+    float mpfr_float = mpfr_num.as<float>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
+
+    // float to bfloat16
+    BFloat16 bf16_from_float{mpfr_float};
+    MPFRNumber mpfr_num_2{mpfr_float};
+    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
+  constexpr int RANGE = 100'000;
+  for (int i = -RANGE; i <= RANGE; i++) {
+    BFloat16 mpfr_bfloat = MPFRNumber(i).as<BFloat16>();
+    BFloat16 libc_bfloat{i};
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, MultiplyAssign) {
+  for(uint16_t i = POS_START; i<=POS_STOP; i++){
+    for(uint16_t j = POS_START; j<=POS_STOP; j++){
+      BFloat16 a{i}, b{j};
+      MPFRNumber mpfr_a{a}, mpfr_b{j};
+      MPFRNumber mpfr_c = mpfr_a;
+      mpfr_c.mul(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 bf06aeacbfb1ca0608affd4f582ac683f0d53c10 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Mon, 23 Feb 2026 21:30:51 +0530
Subject: [PATCH 2/2] clang-format

---
 .../src/__support/FPUtil/bfloat16_test.cpp    | 169 +++++++++---------
 1 file changed, 84 insertions(+), 85 deletions(-)

diff --git a/libc/test/src/__support/FPUtil/bfloat16_test.cpp b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
index 820e384e20285..48b2dfd5c4f3b 100644
--- a/libc/test/src/__support/FPUtil/bfloat16_test.cpp
+++ b/libc/test/src/__support/FPUtil/bfloat16_test.cpp
@@ -1,85 +1,84 @@
-//===-- Unit tests for bfloat16 type --------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/FPUtil/bfloat16.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPCommon.h"
-
-using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;
-using LlvmLibcBfloat16ConversionTest =
-    LIBC_NAMESPACE::testing::FPTest<BFloat16>;
-
-// range: [0, inf]
-static constexpr uint16_t POS_START = 0x0000U;
-static constexpr uint16_t POS_STOP = 0x7f80U;
-
-// range: [-0, -inf]
-static constexpr uint16_t NEG_START = 0x8000U;
-static constexpr uint16_t NEG_STOP = 0xff80U;
-
-using MPFRNumber = LIBC_NAMESPACE::testing::mpfr::MPFRNumber;
-
-TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatPositiveRange) {
-  for (uint16_t bits = POS_START; bits <= POS_STOP; bits++) {
-    BFloat16 bf16_num{bits};
-    MPFRNumber mpfr_num{bf16_num};
-
-    // bfloat16 to float
-    float mpfr_float = mpfr_num.as<float>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
-
-    // float to bfloat16
-    BFloat16 bf16_from_float{mpfr_float};
-    MPFRNumber mpfr_num_2{mpfr_float};
-    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
-  }
-}
-
-TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatNegativeRange) {
-  for (uint16_t bits = NEG_START; bits <= NEG_STOP; bits++) {
-    BFloat16 bf16_num{bits};
-    MPFRNumber mpfr_num{bf16_num};
-
-    // bfloat16 to float
-    float mpfr_float = mpfr_num.as<float>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
-
-    // float to bfloat16
-    BFloat16 bf16_from_float{mpfr_float};
-    MPFRNumber mpfr_num_2{mpfr_float};
-    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
-  }
-}
-
-TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
-  constexpr int RANGE = 100'000;
-  for (int i = -RANGE; i <= RANGE; i++) {
-    BFloat16 mpfr_bfloat = MPFRNumber(i).as<BFloat16>();
-    BFloat16 libc_bfloat{i};
-    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
-  }
-}
-
-TEST_F(LlvmLibcBfloat16ConversionTest, MultiplyAssign) {
-  for(uint16_t i = POS_START; i<=POS_STOP; i++){
-    for(uint16_t j = POS_START; j<=POS_STOP; j++){
-      BFloat16 a{i}, b{j};
-      MPFRNumber mpfr_a{a}, mpfr_b{j};
-      MPFRNumber mpfr_c = mpfr_a;
-      mpfr_c.mul(mpfr_b);
-      BFloat16 mpfr_bfloat = mpfr_c.as<BFloat16>();
-      a *= b;
-      BFloat16 libc_bfloat = a;
-      EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
-
-    }
-  }
-}
+//===-- Unit tests for bfloat16 type --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+
+using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;
+using LlvmLibcBfloat16ConversionTest =
+    LIBC_NAMESPACE::testing::FPTest<BFloat16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+using MPFRNumber = LIBC_NAMESPACE::testing::mpfr::MPFRNumber;
+
+TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatPositiveRange) {
+  for (uint16_t bits = POS_START; bits <= POS_STOP; bits++) {
+    BFloat16 bf16_num{bits};
+    MPFRNumber mpfr_num{bf16_num};
+
+    // bfloat16 to float
+    float mpfr_float = mpfr_num.as<float>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
+
+    // float to bfloat16
+    BFloat16 bf16_from_float{mpfr_float};
+    MPFRNumber mpfr_num_2{mpfr_float};
+    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, ToFloatNegativeRange) {
+  for (uint16_t bits = NEG_START; bits <= NEG_STOP; bits++) {
+    BFloat16 bf16_num{bits};
+    MPFRNumber mpfr_num{bf16_num};
+
+    // bfloat16 to float
+    float mpfr_float = mpfr_num.as<float>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_float, static_cast<float>(bf16_num));
+
+    // float to bfloat16
+    BFloat16 bf16_from_float{mpfr_float};
+    MPFRNumber mpfr_num_2{mpfr_float};
+    BFloat16 mpfr_bfloat = mpfr_num_2.as<BFloat16>();
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, bf16_from_float);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, FromInteger) {
+  constexpr int RANGE = 100'000;
+  for (int i = -RANGE; i <= RANGE; i++) {
+    BFloat16 mpfr_bfloat = MPFRNumber(i).as<BFloat16>();
+    BFloat16 libc_bfloat{i};
+    EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+  }
+}
+
+TEST_F(LlvmLibcBfloat16ConversionTest, MultiplyAssign) {
+  for (uint16_t i = POS_START; i <= POS_STOP; i++) {
+    for (uint16_t j = POS_START; j <= POS_STOP; j++) {
+      BFloat16 a{i}, b{j};
+      MPFRNumber mpfr_a{a}, mpfr_b{j};
+      MPFRNumber mpfr_c = mpfr_a;
+      mpfr_c.mul(mpfr_b);
+      BFloat16 mpfr_bfloat = mpfr_c.as<BFloat16>();
+      a *= b;
+      BFloat16 libc_bfloat = a;
+      EXPECT_FP_EQ_ALL_ROUNDING(mpfr_bfloat, libc_bfloat);
+    }
+  }
+}



More information about the libc-commits mailing list