Index: llvm/include/llvm/ADT/APFloat.h =================================================================== --- llvm/include/llvm/ADT/APFloat.h +++ llvm/include/llvm/ADT/APFloat.h @@ -486,7 +486,8 @@ integerPart addSignificand(const IEEEFloat &); integerPart subtractSignificand(const IEEEFloat &, integerPart); lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract); - lostFraction multiplySignificand(const IEEEFloat &, const IEEEFloat *); + lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat); + lostFraction multiplySignificand(const IEEEFloat&); lostFraction divideSignificand(const IEEEFloat &); void incrementSignificand(); void initialize(const fltSemantics *); Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -978,7 +978,7 @@ on to the full-precision result of the multiplication. Returns the lost fraction. */ lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, - const IEEEFloat *addend) { + IEEEFloat addend) { unsigned int omsb; // One, not zero, based MSB. unsigned int partsCount, newPartsCount, precision; integerPart *lhsSignificand; @@ -1022,7 +1022,7 @@ // toward left by two bits, and adjust exponent accordingly. exponent += 2; - if (addend && addend->isNonZero()) { + if (addend.isNonZero()) { // The intermediate result of the multiplication has "2 * precision" // signicant bit; adjust the addend to be consistent with mul result. // @@ -1051,19 +1051,18 @@ significand.parts = fullSignificand; semantics = &extendedSemantics; - IEEEFloat extendedAddend(*addend); - status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); + status = addend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); (void)status; // Shift the significand of the addend right by one bit. This guarantees // that the high bit of the significand is zero (same as fullSignificand), // so the addition will overflow (if it does overflow at all) into the top bit. - lost_fraction = extendedAddend.shiftSignificandRight(1); + lost_fraction = addend.shiftSignificandRight(1); assert(lost_fraction == lfExactlyZero && "Lost precision while shifting addend for fused-multiply-add."); - lost_fraction = addOrSubtractSignificand(extendedAddend, false); + lost_fraction = addOrSubtractSignificand(addend, false); /* Restore our state. */ if (newPartsCount == 1) @@ -1106,6 +1105,10 @@ return lost_fraction; } +lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs) { + return multiplySignificand(rhs, IEEEFloat(*semantics)); +} + /* Multiply the significands of LHS and RHS to DST. */ lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) { unsigned int bit, i, partsCount; @@ -1714,7 +1717,7 @@ fs = multiplySpecials(rhs); if (isFiniteNonZero()) { - lostFraction lost_fraction = multiplySignificand(rhs, nullptr); + lostFraction lost_fraction = multiplySignificand(rhs); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -1815,7 +1818,7 @@ addend.isFinite()) { lostFraction lost_fraction; - lost_fraction = multiplySignificand(multiplicand, &addend); + lost_fraction = multiplySignificand(multiplicand, addend); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -2424,7 +2427,7 @@ if (exp >= 0) { /* multiplySignificand leaves the precision-th bit set to 1. */ - calcLostFraction = decSig.multiplySignificand(pow5, nullptr); + calcLostFraction = decSig.multiplySignificand(pow5); powHUerr = powStatus != opOK; } else { calcLostFraction = decSig.divideSignificand(pow5); Index: llvm/unittests/ADT/APFloatTest.cpp =================================================================== --- llvm/unittests/ADT/APFloatTest.cpp +++ llvm/unittests/ADT/APFloatTest.cpp @@ -530,6 +530,14 @@ EXPECT_FALSE(losesInfo); EXPECT_EQ(4.0f, M1.convertToFloat()); } + + // Test using only a single instance of APFloat. + { + APFloat F(1.5); + + F.fusedMultiplyAdd(F, F, APFloat::rmNearestTiesToEven); + EXPECT_EQ(3.75, F.convertToDouble()); + } } TEST(APFloatTest, MinNum) {