[libc-commits] [libc] [libc][math][c23] fmul correcly rounded to all rounding modes (PR #91537)

via libc-commits libc-commits at lists.llvm.org
Sat Jun 1 09:23:17 PDT 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff 42d99013bd6b7ed4a085e39c94ab86938d633f8a f00264caf86d1ba451f669d2c51c81a681df8f3e -- libc/src/math/dmull.h libc/src/math/fmul.h libc/src/math/fmull.h libc/src/math/generic/dmull.cpp libc/src/math/generic/fmul.cpp libc/src/math/generic/fmull.cpp libc/test/src/math/smoke/FMulTest.h libc/test/src/math/smoke/dmull_test.cpp libc/test/src/math/smoke/fmul_test.cpp libc/test/src/math/smoke/fmull_test.cpp libc/src/__support/FPUtil/BasicOperations.h
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 58dc5c7276..1926659e5f 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -180,26 +180,25 @@ LIBC_INLINE T fdim(T x, T y) {
 
 // helpers for fmul
 
-uint64_t maxu(uint64_t A, uint64_t B) {
-  return A > B ? A : B;
-}
+uint64_t maxu(uint64_t A, uint64_t B) { return A > B ? A : B; }
 
 uint64_t mul(uint64_t a, uint64_t b) {
-    __uint128_t product = static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b);
-    return static_cast<uint64_t>(product >> 64);
+  __uint128_t product =
+      static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b);
+  return static_cast<uint64_t>(product >> 64);
 }
 
-
 uint64_t mullow(uint64_t a, uint64_t b) {
-    __uint128_t product = static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b);
-    return static_cast<uint64_t>(product);
+  __uint128_t product =
+      static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b);
+  return static_cast<uint64_t>(product);
 }
 
-
 uint64_t nlz(uint64_t x) {
   uint64_t z = 0;
 
-  if (x == 0) return 64;
+  if (x == 0)
+    return 64;
   if (x <= 0x00000000FFFFFFFF) {
     z = z + 32;
     x = x << 32;
@@ -225,10 +224,9 @@ uint64_t nlz(uint64_t x) {
   }
   return z;
 }
-  
+
 LIBC_INLINE float fmul(double x, double y) {
-  
-  
+
   auto x_bits = FPBits<double>(x);
   uint64_t x_u = x_bits.uintval();
 
@@ -241,26 +239,26 @@ LIBC_INLINE float fmul(double x, double y) {
   uint64_t exponent_x = absx >> 52;
   uint64_t exponent_y = absy >> 52;
 
-  //uint64_t x_normal_bit = absx >= 0x10000000000000;
-  //uint64_t y_normal_bit = absy >= 0x10000000000000;
+  // uint64_t x_normal_bit = absx >= 0x10000000000000;
+  // uint64_t y_normal_bit = absy >= 0x10000000000000;
 
   uint64_t mx, my;
-  
-  mx = maxu(nlz(absx), 11); 
 
-  //lambdax = mx - 11;  
+  mx = maxu(nlz(absx), 11);
+
+  // lambdax = mx - 11;
 
   my = maxu(nlz(absy), 11);
 
-  //lambday = my - 11;
+  // lambday = my - 11;
 
   int32_t dm1;
-  uint64_t mpx, mpy, highs,lows, b;
-  uint64_t  g, hight, lowt, morlowt, c, m;
+  uint64_t mpx, mpy, highs, lows, b;
+  uint64_t g, hight, lowt, morlowt, c, m;
   mpx = (x_u << mx) | 0x8000000000000000;
-  mpy = (y_u << my) |  0x8000000000000000;
-  highs = mul(mpx, mpy); 
-  c = highs >= 0x8000000000000000; 
+  mpy = (y_u << my) | 0x8000000000000000;
+  highs = mul(mpx, mpy);
+  c = highs >= 0x8000000000000000;
   lows = mullow(mpx, mpy);
 
   lowt = (lows != 0);
@@ -275,62 +273,61 @@ LIBC_INLINE float fmul(double x, double y) {
 
   if (dm1 >= 255) {
     dm1 = 255;
-    
+
     m = 0;
-  }
-  else if (dm1<=0) {
+  } else if (dm1 <= 0) {
     m = static_cast<uint32_t>((highs >> (39 + c)) >> (1 - dm1));
     dm1 = 0;
     morlowt = m | lowt;
     b = g & (morlowt | hight);
-  }
-  else  {
+  } else {
     m = static_cast<uint32_t>(highs >> (39 + c));
     morlowt = m | lowt;
     b = g & (morlowt | hight);
   }
 
   uint32_t sr = static_cast<uint32_t>((x_u ^ y_u) & 0x8000000000000000);
-  
 
   uint32_t exp16 = sr | (static_cast<uint32_t>(dm1) << 23);
   if (dm1 == 0) {
     uint32_t m2 = static_cast<uint32_t>(m);
-    uint32_t result = (static_cast<uint32_t>(exp16) + m2) + static_cast<uint32_t>(b);
-   
-    
+    uint32_t result =
+        (static_cast<uint32_t>(exp16) + m2) + static_cast<uint32_t>(b);
+
     float result32 = cpp::bit_cast<float>(result);
-    
+
     return result32;
-      
- } else {
-   constexpr uint32_t FLOAT32_MANTISSA_MASK = 0b00000000011111111111111111111111;
-   uint32_t m2 = static_cast<uint32_t>(m) & FLOAT32_MANTISSA_MASK;
-   
-   uint32_t result = (static_cast<uint32_t>(exp16) + m2) + static_cast<uint32_t>(b);
-  
-  float result16 = cpp::bit_cast<float>(result);
-  // std::memcpy(&result16, &result, sizeof(result16));  
-  //result = *reinterpret_cast<_Float16*>(&result);
-  
-  return result16;
- }
+
+  } else {
+    constexpr uint32_t FLOAT32_MANTISSA_MASK =
+        0b00000000011111111111111111111111;
+    uint32_t m2 = static_cast<uint32_t>(m) & FLOAT32_MANTISSA_MASK;
+
+    uint32_t result =
+        (static_cast<uint32_t>(exp16) + m2) + static_cast<uint32_t>(b);
+
+    float result16 = cpp::bit_cast<float>(result);
+    // std::memcpy(&result16, &result, sizeof(result16));
+    // result = *reinterpret_cast<_Float16*>(&result);
+
+    return result16;
+  }
 }
-  /*
+/*
 LIBC_INLINE float fmul(double x, double y){
-  FPBits<double> bitx(x), bity(y);
-
-  long long int product;
-  long long int p;
-  
-  if (bitx.is_normal() && bity.is_normal()) {
-    product = bitx.get_mantissa() * bity.get_mantissa();
-    p = product & ((1ULL << 24) -1);
-    sr = bitx.sign() ^ bity.sign();
-    return pow(-1, sr) * pow(p, p.biased_exponent());
-  }
+FPBits<double> bitx(x), bity(y);
+
+long long int product;
+long long int p;
+
+if (bitx.is_normal() && bity.is_normal()) {
+  product = bitx.get_mantissa() * bity.get_mantissa();
+  p = product & ((1ULL << 24) -1);
+  sr = bitx.sign() ^ bity.sign();
+  return pow(-1, sr) * pow(p, p.biased_exponent());
+}
 }
-  */
+*/
 LIBC_INLINE float fmull(long double x, long double y) {
   return static_cast<float>(x * y);
 }
diff --git a/libc/test/src/math/smoke/FMulTest.h b/libc/test/src/math/smoke/FMulTest.h
index afaca64d86..44cab1e256 100644
--- a/libc/test/src/math/smoke/FMulTest.h
+++ b/libc/test/src/math/smoke/FMulTest.h
@@ -21,9 +21,9 @@ public:
 
   void testMul(FMulFunc func) {
     EXPECT_FP_EQ(T(15.0), func(3.0, 5.0));
-    EXPECT_FP_EQ(T(7.34684e-40), func(0x1.0p1,0x1.0p-131));
+    EXPECT_FP_EQ(T(7.34684e-40), func(0x1.0p1, 0x1.0p-131));
     EXPECT_FP_EQ(T(5.87747e-39), func(0x1.0p2, 0x1.0p-129));
-}
+  }
 };
 
 #define LIST_FMUL_TESTS(T, R, func)                                            \

``````````

</details>


https://github.com/llvm/llvm-project/pull/91537


More information about the libc-commits mailing list