Skip to content

Commit

Permalink
[APFloat] Fix subtraction of subnormal numbers
Browse files Browse the repository at this point in the history
Fix incorrect determination of the bigger number out of the two
subtracted, while subnormal numbers are involved.
Fixes PR44010.

Differential Revision: https://reviews.llvm.org/D69772
  • Loading branch information
ekatz committed Nov 22, 2019
1 parent 718d68e commit e62555c
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
11 changes: 4 additions & 7 deletions llvm/lib/Support/APFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1484,22 +1484,19 @@ lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs,
/* Subtraction is more subtle than one might naively expect. */
if (subtract) {
IEEEFloat temp_rhs(rhs);
bool reverse;

if (bits == 0) {
reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan;
if (bits == 0)
lost_fraction = lfExactlyZero;
} else if (bits > 0) {
else if (bits > 0) {
lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
shiftSignificandLeft(1);
reverse = false;
} else {
lost_fraction = shiftSignificandRight(-bits - 1);
temp_rhs.shiftSignificandLeft(1);
reverse = true;
}

if (reverse) {
// Should we reverse the subtraction.
if (compareAbsoluteValue(temp_rhs) == cmpLessThan) {
carry = temp_rhs.subtractSignificand
(*this, lost_fraction != lfExactlyZero);
copySignificand(temp_rhs);
Expand Down
9 changes: 9 additions & 0 deletions llvm/unittests/ADT/APFloatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,15 @@ TEST(APFloatTest, FMA) {
EXPECT_FALSE(losesInfo);
EXPECT_EQ(4.0f, M1.convertToFloat());
}

// Regression test that failed an assertion.
{
APFloat f1(-8.85242279E-41f);
APFloat f2(2.0f);
APFloat f3(8.85242279E-41f);
f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
EXPECT_EQ(-8.85242279E-41f, f1.convertToFloat());
}
}

TEST(APFloatTest, MinNum) {
Expand Down

0 comments on commit e62555c

Please sign in to comment.