[libc-commits] [libc] [libc][stdfix] Implement fxdivi functions (rdivi) (PR #154914)
via libc-commits
libc-commits at lists.llvm.org
Tue Sep 2 10:39:06 PDT 2025
================
@@ -0,0 +1,65 @@
+//===-- Utility class to test fxdivi functions ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "test/UnitTest/Test.h"
+
+template <typename XType> XType get_epsilon() = delete;
+template <> fract get_epsilon() { return FRACT_EPSILON; }
+template <> unsigned fract get_epsilon() { return UFRACT_EPSILON; }
+template <> long fract get_epsilon() { return LFRACT_EPSILON; }
+
+template <typename XType>
+class DivITest : public LIBC_NAMESPACE::testing::Test {
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<XType>;
+ using FXBits = LIBC_NAMESPACE::fixed_point::FXBits<XType>;
+
+public:
+ typedef XType (*DivIFunc)(int, int);
+
+ void testBasic(DivIFunc func) {
+ XType epsilon = get_epsilon<XType>();
+ EXPECT_LT((func(2, 3) - 0.666656494140625r), epsilon);
+ EXPECT_LT((func(3, 4) - 0.75r), epsilon);
+ EXPECT_LT((func(1043, 2764) - 0.3773516643r), epsilon);
+ EXPECT_LT((func(60000, 720293) - 0.08329943509r), epsilon);
+
+ EXPECT_EQ(func(128, 256), 0.5r);
+ EXPECT_EQ(func(1, 2), 0.5r);
+ EXPECT_EQ(func(1, 4), 0.25r);
+ EXPECT_EQ(func(1, 8), 0.125r);
+ EXPECT_EQ(func(1, 16), 0.0625r);
+
+ EXPECT_EQ(func(-1, 2), -0.5r);
+ EXPECT_EQ(func(1, -4), -0.25r);
+ EXPECT_EQ(func(-1, 8), -0.125r);
+ EXPECT_EQ(func(1, -16), -0.0625r);
+ }
+
+ void testSpecial(DivIFunc func) {
+ EXPECT_EQ(func(0,10), 0.r);
+ EXPECT_EQ(func(0,-10), 0.r);
+ EXPECT_EQ(func(-32768,32768), FRACT_MIN);
+ EXPECT_EQ(func(32767,32768), FRACT_MAX);
+ EXPECT_EQ(func(INT_MAX,INT_MAX), 1.0r);
----------------
PiJoules wrote:
This is correct but it had me second guessing a little because of some nuances with the spec I had to look up.
Per `7.18a.6.1`
```
For functions returning a fixed-point value, the return value is saturated on overflow.
```
so `rdivi(INT_MAX,INT_MAX)` should definitely return `FRACT_MAX`, and per `Clause 6.4.4`:
```
The value of a constant shall be in the range of representable values for its type, with exception for constants of a fract type with a value of exactly 1; such a constant shall denote the maximal value for the type.
```
so `1.0r` should also resolve to `FRACT_MAX` hence the comparison is correct. Just to make things clearer, could you add these as comments above this check, or alternatively make the RHS `FRACT_MAX` while keeping the `rdivi` saturation comment?
https://github.com/llvm/llvm-project/pull/154914
More information about the libc-commits
mailing list