aboutsummaryrefslogtreecommitdiff
path: root/flang/unittests
diff options
context:
space:
mode:
authorSlava Zakharin <szakharin@nvidia.com>2024-04-03 10:19:06 -0700
committerGitHub <noreply@github.com>2024-04-03 10:19:06 -0700
commit315c88c5fbdb2b27cebf23c87fb502f7a567d84b (patch)
tree5bb30ba9acf70483f4a805658d1323736eff8566 /flang/unittests
parent07a566793b2f94d0de6b95b7e6d1146b0d7ffe49 (diff)
downloadllvm-315c88c5fbdb2b27cebf23c87fb502f7a567d84b.zip
llvm-315c88c5fbdb2b27cebf23c87fb502f7a567d84b.tar.gz
llvm-315c88c5fbdb2b27cebf23c87fb502f7a567d84b.tar.bz2
[flang] Fixed MODULO(x, inf) to produce NaN. (#86145)
Straightforward computation of `A − FLOOR (A / P) * P` should produce NaN, when P is infinity. The -menable-no-infs lowering can still use the relaxed operations sequence.
Diffstat (limited to 'flang/unittests')
-rw-r--r--flang/unittests/Runtime/Numeric.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index 43263d1..b69ff21 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -65,6 +65,30 @@ TEST(Numeric, Mod) {
EXPECT_EQ(RTNAME(ModReal4)(Real<4>{-8.0}, Real<4>(5.0)), -3.0);
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{8.0}, Real<8>(-5.0)), 3.0);
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
+ EXPECT_EQ(
+ RTNAME(ModReal4)(Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity()),
+ 0.5);
+ EXPECT_EQ(
+ RTNAME(ModReal4)(Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity()),
+ -0.5);
+ EXPECT_EQ(
+ RTNAME(ModReal4)(Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity()),
+ 0.5);
+ EXPECT_EQ(RTNAME(ModReal4)(
+ Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity()),
+ -0.5);
+ EXPECT_EQ(
+ RTNAME(ModReal8)(Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity()),
+ 0.5);
+ EXPECT_EQ(
+ RTNAME(ModReal8)(Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity()),
+ -0.5);
+ EXPECT_EQ(
+ RTNAME(ModReal8)(Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity()),
+ 0.5);
+ EXPECT_EQ(RTNAME(ModReal8)(
+ Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity()),
+ -0.5);
}
TEST(Numeric, Modulo) {
@@ -76,6 +100,28 @@ TEST(Numeric, Modulo) {
EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-8.0}, Real<4>(5.0)), 2.0);
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{8.0}, Real<8>(-5.0)), -2.0);
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
+ // MODULO(x, INF) == NaN
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
+ Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
+ Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
+ Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
+ Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
+ Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
+ Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
+ Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity())));
+ EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
+ Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity())));
+ // MODULO(x, y) for integer values of x and y with 0 remainder.
+ EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(1.0)), 0.0);
+ EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(-1.0)), -0.0);
+ EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(1.0)), 0.0);
+ EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(-1.0)), -0.0);
}
TEST(Numeric, Nearest) {