Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -1545,22 +1545,18 @@ /* 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; - lost_fraction = lfExactlyZero; - } else if (bits > 0) { + if (bits > 0) { lost_fraction = temp_rhs.shiftSignificandRight(bits - 1); shiftSignificandLeft(1); - reverse = false; - } else { + } else if (bits < 0) { lost_fraction = shiftSignificandRight(-bits - 1); temp_rhs.shiftSignificandLeft(1); - reverse = true; - } + } else + lost_fraction = lfExactlyZero; - if (reverse) { + // Should we reverse the subtraction. + if (compareAbsoluteValue(temp_rhs) == cmpLessThan) { carry = temp_rhs.subtractSignificand (*this, lost_fraction != lfExactlyZero); copySignificand(temp_rhs); Index: llvm/unittests/ADT/APFloatTest.cpp =================================================================== --- llvm/unittests/ADT/APFloatTest.cpp +++ llvm/unittests/ADT/APFloatTest.cpp @@ -538,6 +538,16 @@ EXPECT_FALSE(losesInfo); EXPECT_EQ(4.0f, M1.convertToFloat()); } + + // Test addition of a subnormal number with a negative normal. + // This used to trigger an assert failure. + { + APFloat f1(123.456); + APFloat f2(APFloat::IEEEdouble(), "-0x1p-1074"); + APFloat f3(APFloat::IEEEdouble(), "+0x1p-1074"); + + f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven); + } } TEST(APFloatTest, MinNum) {