[libc] [llvm] [libc][math][c23] Add {,u}fromfp{,x}{,f,l,f128} functions (PR #86003)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 20 14:18:40 PDT 2024


================
@@ -0,0 +1,452 @@
+//===-- Utility class to test different flavors of fromfpx ------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef T (*FromfpxFunc)(T, int, unsigned int);
+
+  void testSpecialNumbersNonzeroWidth(FromfpxFunc func) {
+    for (int rnd : MATH_ROUNDING_DIRECTIONS) {
+      EXPECT_FP_EQ(zero, func(zero, rnd, 32U));
+      EXPECT_FP_EQ(neg_zero, func(neg_zero, rnd, 32U));
+
+      EXPECT_FP_EQ(aNaN, func(inf, rnd, 32U));
+      EXPECT_FP_EQ(aNaN, func(neg_inf, rnd, 32U));
+
+      EXPECT_FP_EQ(aNaN, func(aNaN, rnd, 32U));
+    }
+  }
+
+  void testSpecialNumbersZeroWidth(FromfpxFunc func) {
+    for (int rnd : MATH_ROUNDING_DIRECTIONS) {
+      EXPECT_FP_EQ(aNaN, func(zero, rnd, 0U));
+      EXPECT_FP_EQ(aNaN, func(neg_zero, rnd, 0U));
+
+      EXPECT_FP_EQ(aNaN, func(inf, rnd, 0U));
+      EXPECT_FP_EQ(aNaN, func(neg_inf, rnd, 0U));
+
+      EXPECT_FP_EQ(aNaN, func(aNaN, rnd, 0U));
+    }
+  }
+
+  void testRoundedNumbersWithinRange(FromfpxFunc func) {
+    for (int rnd : MATH_ROUNDING_DIRECTIONS) {
+      EXPECT_FP_EQ(T(1.0), func(T(1.0), rnd, 2U));
+      EXPECT_FP_EQ(T(-1.0), func(T(-1.0), rnd, 1U));
+      EXPECT_FP_EQ(T(10.0), func(T(10.0), rnd, 5U));
+      EXPECT_FP_EQ(T(-10.0), func(T(-10.0), rnd, 5U));
+      EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 12U));
+      EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0), rnd, 12U));
+    }
+  }
+
+  void testRoundedNumbersOutsideRange(FromfpxFunc func) {
+    for (int rnd : MATH_ROUNDING_DIRECTIONS) {
+      EXPECT_FP_EQ(aNaN, func(T(1.0), rnd, 1U));
+      EXPECT_FP_EQ(aNaN, func(T(10.0), rnd, 4U));
+      EXPECT_FP_EQ(aNaN, func(T(-10.0), rnd, 4U));
+      EXPECT_FP_EQ(aNaN, func(T(1234.0), rnd, 11U));
+      EXPECT_FP_EQ(aNaN, func(T(-1234.0), rnd, 11U));
+    }
+  }
+
+  void testFractionsUpwardWithinRange(FromfpxFunc func) {
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.5), FP_INT_UPWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.115), FP_INT_UPWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.715), FP_INT_UPWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.715), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.3), FP_INT_UPWARD, 3U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.3), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.5), FP_INT_UPWARD, 3U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.5), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.75), FP_INT_UPWARD, 3U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.75), FP_INT_UPWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.32), FP_INT_UPWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.32), FP_INT_UPWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_UPWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.38), FP_INT_UPWARD, 12U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(-1234.0), func(T(-1234.38), FP_INT_UPWARD, 12U), FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 12U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(-1234.0), func(T(-1234.96), FP_INT_UPWARD, 12U), FE_INEXACT);
+  }
+
+  void testFractionsUpwardOutsideRange(FromfpxFunc func) {
+    EXPECT_FP_EQ(aNaN, func(T(0.5), FP_INT_UPWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(0.115), FP_INT_UPWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(0.715), FP_INT_UPWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(1.3), FP_INT_UPWARD, 2U));
+    EXPECT_FP_EQ(aNaN, func(T(1.5), FP_INT_UPWARD, 2U));
+    EXPECT_FP_EQ(aNaN, func(T(1.75), FP_INT_UPWARD, 2U));
+    EXPECT_FP_EQ(aNaN, func(T(10.32), FP_INT_UPWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(-10.32), FP_INT_UPWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(10.65), FP_INT_UPWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(-10.65), FP_INT_UPWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(1234.38), FP_INT_UPWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(-1234.38), FP_INT_UPWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(1234.96), FP_INT_UPWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(-1234.96), FP_INT_UPWARD, 11U));
+  }
+
+  void testFractionsDownwardWithinRange(FromfpxFunc func) {
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.5), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.115), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.715), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.715), FP_INT_DOWNWARD, 1U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.3), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.5), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.5), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.75), FP_INT_DOWNWARD, 2U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.32), FP_INT_DOWNWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U),
+                                FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(-1235.0), func(T(-1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+    EXPECT_FP_EQ_WITH_EXCEPTION(
+        T(-1235.0), func(T(-1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+  }
+
+  void testFractionsDownwardOutsideRange(FromfpxFunc func) {
+    EXPECT_FP_EQ(aNaN, func(T(1.3), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(-1.3), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(1.5), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(-1.5), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(1.75), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(-1.75), FP_INT_DOWNWARD, 1U));
+    EXPECT_FP_EQ(aNaN, func(T(10.32), FP_INT_DOWNWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(-10.32), FP_INT_DOWNWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(10.65), FP_INT_DOWNWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 4U));
+    EXPECT_FP_EQ(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 11U));
+    EXPECT_FP_EQ(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U));
+  }
+
+  void testFractionsTowardZeroWithinRange(FromfpxFunc func) {
----------------
overmighty wrote:

The formatting for the tests that use `EXPECT_FP_EQ_WITH_EXCEPTION` isn't great but I'm not sure if it's a problem.

Note that FromfpxTest.h is pretty much a copy-paste of FromfpTest.h with `testFractions*WithinRange` tests changed to use `EXPECT_FP_EQ_WITH_EXCEPTION`. Same for UfromfpxTest.h vs UfromfpTest.h. I'm not sure if something should be done about this either.

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


More information about the llvm-commits mailing list