[libc-commits] [libc] [libc][math] Fix `quick_add` incorrect exponent (PR #220374)

via libc-commits libc-commits at lists.llvm.org
Tue Sep 1 13:46:53 PDT 2026


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

>From 5dc022b61505cc7afc545f3e32a6bfb6b2299944 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 2 Sep 2026 02:01:29 +0530
Subject: [PATCH 1/2] shift_right fix + smoke test

---
 libc/src/__support/FPUtil/dyadic_float.h             |  8 +++-----
 libc/test/src/__support/FPUtil/dyadic_float_test.cpp | 12 ++++++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index e32906e3cf9cf..d0bb38564bfed 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -151,13 +151,11 @@ template <size_t Bits> struct DyadicFloat {
 
   // Used for aligning exponents.  Output might not be normalized.
   LIBC_INLINE constexpr DyadicFloat &shift_right(unsigned shift_length) {
-    if (shift_length < Bits) {
-      exponent += static_cast<int>(shift_length);
+    exponent += static_cast<int>(shift_length);
+    if (shift_length < Bits)
       mantissa >>= shift_length;
-    } else {
-      exponent = 0;
+    else
       mantissa = MantissaType(0);
-    }
     return *this;
   }
 
diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
index 720b426033dff..3575f9694ab7f 100644
--- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
+++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
@@ -44,6 +44,18 @@ TEST(LlvmLibcDyadicFloatTest, QuickAdd) {
 
   Float192 z = quick_add(x, y);
   EXPECT_FP_EQ_ALL_ROUNDING(double(x) + double(y), double(z));
+
+  DFloat128 a(0x1.0p0);
+  ASSERT_FP_EQ(0x1.0p0, double(a));
+
+  DFloat128 b(0x1.0p128);
+  ASSERT_FP_EQ(0x1.0p128, double(b));
+
+  DFloat128 c1 = quick_add(a, b);
+  EXPECT_FP_EQ(double(a) + double(b), double(c1));
+
+  DFloat128 c2 = quick_add(b, a);
+  EXPECT_FP_EQ(double(b) + double(a), double(c2));
 }
 
 TEST(LlvmLibcDyadicFloatTest, QuickMul) {

>From 85dda98ad29efe1a92f4db13a7070f069236fcd9 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 2 Sep 2026 02:16:37 +0530
Subject: [PATCH 2/2] shif_left

---
 libc/src/__support/FPUtil/dyadic_float.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index d0bb38564bfed..66fb2ea89dfe3 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -139,8 +139,8 @@ template <size_t Bits> struct DyadicFloat {
 
   // Used for aligning exponents.  Output might not be normalized.
   LIBC_INLINE constexpr DyadicFloat &shift_left(unsigned shift_length) {
+    exponent -= static_cast<int>(shift_length);
     if (shift_length < Bits) {
-      exponent -= static_cast<int>(shift_length);
       mantissa <<= shift_length;
     } else {
       exponent = 0;



More information about the libc-commits mailing list