aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ADT/APFloatTest.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@igalia.com>2024-10-01 12:47:55 +0100
committerGitHub <noreply@github.com>2024-10-01 12:47:55 +0100
commita88901838aad686002bb4bcc4da4625b45fb7606 (patch)
treeae2c3dbcac8f6b35d06e34c54e74515c785d4466 /llvm/unittests/ADT/APFloatTest.cpp
parent574e2dc5f14bd1ac8a557d5e31f4fe7d2d6cb5ae (diff)
downloadllvm-a88901838aad686002bb4bcc4da4625b45fb7606.zip
llvm-a88901838aad686002bb4bcc4da4625b45fb7606.tar.gz
llvm-a88901838aad686002bb4bcc4da4625b45fb7606.tar.bz2
[APFloat] Correct semantics of minimum/maximum for signaling NaN arguments (#109976)
The minimum and maximum operations were introduced in https://reviews.llvm.org/D52764 alongside the intrinsics. The question of NaN propagation was discussed at the time, but the resulting semantics don't seem to match what was ultimately agreed in IEEE754-2019 or the description we now have in the LangRef at <https://llvm.org/docs/LangRef.html#llvm-min-intrinsics-comparation>. Essentially, the APFloat implementation doesn't quiet a signaling NaN input when it should in order to match the LangRef and IEEE spec.
Diffstat (limited to 'llvm/unittests/ADT/APFloatTest.cpp')
-rw-r--r--llvm/unittests/ADT/APFloatTest.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 6c49d78e..cd8a00f 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -607,6 +607,7 @@ TEST(APFloatTest, Minimum) {
APFloat zp(0.0);
APFloat zn(-0.0);
APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
+ APFloat snan = APFloat::getSNaN(APFloat::IEEEdouble());
EXPECT_EQ(1.0, minimum(f1, f2).convertToDouble());
EXPECT_EQ(1.0, minimum(f2, f1).convertToDouble());
@@ -614,6 +615,10 @@ TEST(APFloatTest, Minimum) {
EXPECT_EQ(-0.0, minimum(zn, zp).convertToDouble());
EXPECT_TRUE(std::isnan(minimum(f1, nan).convertToDouble()));
EXPECT_TRUE(std::isnan(minimum(nan, f1).convertToDouble()));
+ EXPECT_TRUE(maximum(snan, f1).isNaN());
+ EXPECT_TRUE(maximum(f1, snan).isNaN());
+ EXPECT_FALSE(maximum(snan, f1).isSignaling());
+ EXPECT_FALSE(maximum(f1, snan).isSignaling());
}
TEST(APFloatTest, Maximum) {
@@ -622,6 +627,7 @@ TEST(APFloatTest, Maximum) {
APFloat zp(0.0);
APFloat zn(-0.0);
APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
+ APFloat snan = APFloat::getSNaN(APFloat::IEEEdouble());
EXPECT_EQ(2.0, maximum(f1, f2).convertToDouble());
EXPECT_EQ(2.0, maximum(f2, f1).convertToDouble());
@@ -629,6 +635,10 @@ TEST(APFloatTest, Maximum) {
EXPECT_EQ(0.0, maximum(zn, zp).convertToDouble());
EXPECT_TRUE(std::isnan(maximum(f1, nan).convertToDouble()));
EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble()));
+ EXPECT_TRUE(maximum(snan, f1).isNaN());
+ EXPECT_TRUE(maximum(f1, snan).isNaN());
+ EXPECT_FALSE(maximum(snan, f1).isSignaling());
+ EXPECT_FALSE(maximum(f1, snan).isSignaling());
}
TEST(APFloatTest, MinimumNumber) {