Skip to content

Commit

Permalink
Fix APFloat mod sign
Browse files Browse the repository at this point in the history
fmod specification requires the sign of the remainder is
the same as numerator in case remainder is zero.

Reviewers: gottesmm, scanon, arsenm, davide, craig.topper
Reviewed By: scanon
Subscribers: wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D39225

llvm-svn: 317081
  • Loading branch information
Serguei Katkov committed Nov 1, 2017
1 parent 82f0c42 commit f2c2851
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
3 changes: 3 additions & 0 deletions llvm/lib/Support/APFloat.cpp
Expand Up @@ -1743,6 +1743,7 @@ IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
opStatus fs;
fs = modSpecials(rhs);
unsigned int origSign = sign;

while (isFiniteNonZero() && rhs.isFiniteNonZero() &&
compareAbsoluteValue(rhs) != cmpLessThan) {
Expand All @@ -1754,6 +1755,8 @@ IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
fs = subtract(V, rmNearestTiesToEven);
assert(fs==opOK);
}
if (isZero())
sign = origSign; // fmod requires this
return fs;
}

Expand Down
14 changes: 14 additions & 0 deletions llvm/unittests/ADT/APFloatTest.cpp
Expand Up @@ -3289,6 +3289,20 @@ TEST(APFloatTest, mod) {
EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
EXPECT_TRUE(f1.isNaN());
}
{
APFloat f1(APFloat::IEEEdouble(), "-4.0");
APFloat f2(APFloat::IEEEdouble(), "-2.0");
APFloat expected(APFloat::IEEEdouble(), "-0.0");
EXPECT_EQ(f1.mod(f2), APFloat::opOK);
EXPECT_TRUE(f1.bitwiseIsEqual(expected));
}
{
APFloat f1(APFloat::IEEEdouble(), "-4.0");
APFloat f2(APFloat::IEEEdouble(), "2.0");
APFloat expected(APFloat::IEEEdouble(), "-0.0");
EXPECT_EQ(f1.mod(f2), APFloat::opOK);
EXPECT_TRUE(f1.bitwiseIsEqual(expected));
}
}

TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {
Expand Down

0 comments on commit f2c2851

Please sign in to comment.