[PATCH] D75246: Fix reporting inexact status in IEEEFloat::roundToIntegral
Serge Pavlov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 27 05:27:25 PST 2020
sepavloff created this revision.
sepavloff added reviewers: timshen, scanon, skatkov, craig.topper, andrew.w.kaylor.
Herald added subscribers: dexonsmith, hiraditya.
Herald added a project: LLVM.
Rounding is made by adding a large integer number and then subtracting
it. Usually the first addition reports inexact result but only the
status of the subtraction were returned. Now inexact result is reported
if either of these operations returns inexact result.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D75246
Files:
llvm/lib/Support/APFloat.cpp
llvm/unittests/ADT/APFloatTest.cpp
Index: llvm/unittests/ADT/APFloatTest.cpp
===================================================================
--- llvm/unittests/ADT/APFloatTest.cpp
+++ llvm/unittests/ADT/APFloatTest.cpp
@@ -1525,6 +1525,62 @@
P = APFloat::getInf(APFloat::IEEEdouble(), true);
P.roundToIntegral(APFloat::rmTowardZero);
EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
+
+ APFloat::opStatus St;
+
+ P = APFloat(10.0);
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_EQ(10.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opOK, St);
+
+ P = APFloat::getNaN(APFloat::IEEEdouble());
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_TRUE(P.isNaN());
+ EXPECT_FALSE(P.isNegative());
+ EXPECT_EQ(APFloat::opOK, St);
+
+ P = APFloat::getNaN(APFloat::IEEEdouble(), true);
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_TRUE(P.isNaN());
+ EXPECT_TRUE(P.isNegative());
+ EXPECT_EQ(APFloat::opOK, St);
+
+ P = APFloat::getInf(APFloat::IEEEdouble());
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_TRUE(P.isInfinity());
+ EXPECT_FALSE(P.isNegative());
+ EXPECT_EQ(APFloat::opOK, St);
+
+ P = APFloat::getInf(APFloat::IEEEdouble(), true);
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_TRUE(P.isInfinity());
+ EXPECT_TRUE(P.isNegative());
+ EXPECT_EQ(APFloat::opOK, St);
+
+ P = APFloat(10.5);
+ St = P.roundToIntegral(APFloat::rmTowardZero);
+ EXPECT_EQ(10.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opInexact, St);
+
+ P = APFloat(10.5);
+ St = P.roundToIntegral(APFloat::rmTowardPositive);
+ EXPECT_EQ(11.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opInexact, St);
+
+ P = APFloat(10.5);
+ St = P.roundToIntegral(APFloat::rmTowardNegative);
+ EXPECT_EQ(10.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opInexact, St);
+
+ P = APFloat(10.5);
+ St = P.roundToIntegral(APFloat::rmNearestTiesToAway);
+ EXPECT_EQ(11.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opInexact, St);
+
+ P = APFloat(10.5);
+ St = P.roundToIntegral(APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(10.0, P.convertToDouble());
+ EXPECT_EQ(APFloat::opInexact, St);
}
TEST(APFloatTest, isInteger) {
Index: llvm/lib/Support/APFloat.cpp
===================================================================
--- llvm/lib/Support/APFloat.cpp
+++ llvm/lib/Support/APFloat.cpp
@@ -1977,7 +1977,7 @@
return fs;
}
-/* Rounding-mode corrrect round to integral value. */
+/* Rounding-mode correct round to integral value. */
IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) {
opStatus fs;
@@ -2007,7 +2007,8 @@
bool inputSign = isNegative();
fs = add(MagicConstant, rounding_mode);
- if (fs != opOK && fs != opInexact)
+ opStatus IsInexact = static_cast<opStatus>(fs & opInexact);
+ if (fs != opOK && !IsInexact)
return fs;
fs = subtract(MagicConstant, rounding_mode);
@@ -2016,7 +2017,7 @@
if (inputSign != isNegative())
changeSign();
- return fs;
+ return fs == opOK ? IsInexact : fs;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75246.246922.patch
Type: text/x-patch
Size: 3030 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200227/0450ca99/attachment.bin>
More information about the llvm-commits
mailing list