[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