[PATCH] D70422: [APFloat] Fix fusedMultiplyAdd when `this` equals to `Addend`

Ehud Katz via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 00:22:21 PST 2019


ekatz created this revision.
ekatz added reviewers: chandlerc, scanon, efriedma, hfinkel, arsenm, kbarton.
ekatz added a project: LLVM.
Herald added subscribers: llvm-commits, dexonsmith, hiraditya, wdng.

The arguments to fusedMultiplyAdd are passed by reference. We must save the Addend value on the beginning of the function, before we this `this`, as they may be the same reference.

Fix PR44051.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70422

Files:
  llvm/lib/Support/APFloat.cpp
  llvm/unittests/ADT/APFloatTest.cpp


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) {
Index: llvm/lib/Support/APFloat.cpp
===================================================================
--- llvm/lib/Support/APFloat.cpp
+++ llvm/lib/Support/APFloat.cpp
@@ -986,9 +986,15 @@
   integerPart *fullSignificand;
   lostFraction lost_fraction;
   bool ignored;
+  IEEEFloat extendedAddend(*semantics, 0);
 
   assert(semantics == rhs.semantics);
 
+  // Save the addend now, before we change our properties, as it may be equal to
+  // 'this' pointer.
+  if (addend)
+    extendedAddend = *addend;
+
   precision = semantics->precision;
 
   // Allocate space for twice as many bits as the original significand, plus one
@@ -1022,7 +1028,7 @@
   // toward left by two bits, and adjust exponent accordingly.
   exponent += 2;
 
-  if (addend && addend->isNonZero()) {
+  if (extendedAddend.isNonZero()) {
     // The intermediate result of the multiplication has "2 * precision"
     // signicant bit; adjust the addend to be consistent with mul result.
     //
@@ -1051,7 +1057,6 @@
       significand.parts = fullSignificand;
     semantics = &extendedSemantics;
 
-    IEEEFloat extendedAddend(*addend);
     status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
     assert(status == opOK);
     (void)status;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70422.229985.patch
Type: text/x-patch
Size: 1758 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191119/9ca9d75c/attachment.bin>


More information about the llvm-commits mailing list