aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ADT/APFloatTest.cpp
diff options
context:
space:
mode:
authorYunQiang Su <syq@debian.org>2024-06-26 07:10:43 +0800
committerGitHub <noreply@github.com>2024-06-26 07:10:43 +0800
commit0d533665054c3a04681c46f3ed88960f28777be1 (patch)
tree226585cd8fac85ee330223690226df5f909a2af1 /llvm/unittests/ADT/APFloatTest.cpp
parent847235bbef153c6d805d415cea8494297eaf2bdb (diff)
downloadllvm-0d533665054c3a04681c46f3ed88960f28777be1.zip
llvm-0d533665054c3a04681c46f3ed88960f28777be1.tar.gz
llvm-0d533665054c3a04681c46f3ed88960f28777be1.tar.bz2
APFloat: Add minimumnum and maximumnum (#96304)
They implements IEEE754-2019 minimumNumber and maximumNumber semantics. Newer libc also has these 2 functions with names fminimum_num fmaximum_num We are planning add minimumnum and maximumnum intrinsic. This is a step to the goal.
Diffstat (limited to 'llvm/unittests/ADT/APFloatTest.cpp')
-rw-r--r--llvm/unittests/ADT/APFloatTest.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index f6af4b0..cf6bbd31 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -631,6 +631,100 @@ TEST(APFloatTest, Maximum) {
EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble()));
}
+TEST(APFloatTest, MinimumNumber) {
+ APFloat f1(1.0);
+ APFloat f2(2.0);
+ APFloat zp(0.0);
+ APFloat zn(-0.0);
+ APInt intPayload_89ab(64, 0x89ab);
+ APInt intPayload_cdef(64, 0xcdef);
+ APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),
+ APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};
+ APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),
+ APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};
+ APFloat nan_89ab[2] = {
+ APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),
+ APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};
+ APFloat mnan_cdef[2] = {
+ APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),
+ APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};
+
+ EXPECT_TRUE(f1.bitwiseIsEqual(minimumnum(f1, f2)));
+ EXPECT_TRUE(f1.bitwiseIsEqual(minimumnum(f2, f1)));
+ EXPECT_TRUE(zn.bitwiseIsEqual(minimumnum(zp, zn)));
+ EXPECT_TRUE(zn.bitwiseIsEqual(minimumnum(zn, zp)));
+
+ EXPECT_TRUE(minimumnum(zn, zp).isNegative());
+ EXPECT_TRUE(minimumnum(zp, zn).isNegative());
+ EXPECT_TRUE(minimumnum(zn, zn).isNegative());
+ EXPECT_FALSE(minimumnum(zp, zp).isNegative());
+
+ for (APFloat n : {nan_0123[0], mnan_4567[0], nan_89ab[0], mnan_cdef[0]})
+ for (APFloat f : {f1, f2, zn, zp}) {
+ APFloat res = minimumnum(f, n);
+ EXPECT_FALSE(res.isNaN());
+ EXPECT_TRUE(res.bitwiseIsEqual(f));
+ res = minimumnum(n, f);
+ EXPECT_FALSE(res.isNaN());
+ EXPECT_TRUE(res.bitwiseIsEqual(f));
+ }
+
+ // When NaN vs NaN, we should keep payload/sign of either one.
+ for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})
+ for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {
+ APFloat res = minimumnum(n1[0], n2[0]);
+ EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));
+ EXPECT_FALSE(res.isSignaling());
+ }
+}
+
+TEST(APFloatTest, MaximumNumber) {
+ APFloat f1(1.0);
+ APFloat f2(2.0);
+ APFloat zp(0.0);
+ APFloat zn(-0.0);
+ APInt intPayload_89ab(64, 0x89ab);
+ APInt intPayload_cdef(64, 0xcdef);
+ APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),
+ APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};
+ APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),
+ APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};
+ APFloat nan_89ab[2] = {
+ APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),
+ APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};
+ APFloat mnan_cdef[2] = {
+ APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),
+ APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};
+
+ EXPECT_TRUE(f2.bitwiseIsEqual(maximumnum(f1, f2)));
+ EXPECT_TRUE(f2.bitwiseIsEqual(maximumnum(f2, f1)));
+ EXPECT_TRUE(zp.bitwiseIsEqual(maximumnum(zp, zn)));
+ EXPECT_TRUE(zp.bitwiseIsEqual(maximumnum(zn, zp)));
+
+ EXPECT_FALSE(maximumnum(zn, zp).isNegative());
+ EXPECT_FALSE(maximumnum(zp, zn).isNegative());
+ EXPECT_TRUE(maximumnum(zn, zn).isNegative());
+ EXPECT_FALSE(maximumnum(zp, zp).isNegative());
+
+ for (APFloat n : {nan_0123[0], mnan_4567[0], nan_89ab[0], mnan_cdef[0]})
+ for (APFloat f : {f1, f2, zn, zp}) {
+ APFloat res = maximumnum(f, n);
+ EXPECT_FALSE(res.isNaN());
+ EXPECT_TRUE(res.bitwiseIsEqual(f));
+ res = maximumnum(n, f);
+ EXPECT_FALSE(res.isNaN());
+ EXPECT_TRUE(res.bitwiseIsEqual(f));
+ }
+
+ // When NaN vs NaN, we should keep payload/sign of either one.
+ for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})
+ for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {
+ APFloat res = maximumnum(n1[0], n2[0]);
+ EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));
+ EXPECT_FALSE(res.isSignaling());
+ }
+}
+
TEST(APFloatTest, Denormal) {
APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;