From e62555c129d535d524354351791c5474c9929582 Mon Sep 17 00:00:00 2001 From: Ehud Katz Date: Sun, 3 Nov 2019 17:28:54 +0200 Subject: [PATCH] [APFloat] Fix subtraction of subnormal numbers 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 --- llvm/lib/Support/APFloat.cpp | 11 ++++------- llvm/unittests/ADT/APFloatTest.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index b79baf1834a78a..c7500acaa7292e 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -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); diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index c76347ed0564b9..a6398bbb684635 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -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) {