<div dir="ltr">I think this breaks ubsan:<div><br></div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/1361/steps/check-llvm%20ubsan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/1361/steps/check-llvm%20ubsan/logs/stdio</a><br></div><div><br></div><div><div>FAILED: unittests/ADT/CMakeFiles/ADTTests.dir/APFloatTest.cpp.o </div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build0/bin/clang++   -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iunittests/ADT -I/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT -Iinclude -I/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include -I/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/include -fsanitize=undefined -w -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Werror=date-time -std=c++11 -fno-omit-frame-pointer -O1 -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all -fcolor-diagnostics -g    -Wno-variadic-macros -fno-exceptions -fno-rtti -MMD -MT unittests/ADT/CMakeFiles/ADTTests.dir/APFloatTest.cpp.o -MF unittests/ADT/CMakeFiles/ADTTests.dir/APFloatTest.cpp.o.d -o unittests/ADT/CMakeFiles/ADTTests.dir/APFloatTest.cpp.o -c /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3179:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0, APFloat::fcZero,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3182:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7948000000000000ull,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3188:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7947ffffffffffffull,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3191:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7fefffffffffffffull,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3195:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0, APFloat::fcNaN,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/ADT/APFloatTest.cpp:3218:7: error: chosen constructor is explicit in copy-initialization</div><div>      {0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,</div><div>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/tuple:406:19: note: constructor declared here</div><div>        constexpr tuple(_UElements&&... __elements)</div><div>                  ^</div></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Dec 12, 2016 at 2:09 PM Tim Shen via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: timshen<br class="gmail_msg">
Date: Mon Dec 12 15:59:30 2016<br class="gmail_msg">
New Revision: 289472<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=289472&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=289472&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
[APFloat] Implement PPCDoubleDouble add and subtract.<br class="gmail_msg">
<br class="gmail_msg">
Summary:<br class="gmail_msg">
I looked at libgcc's implementation (which is based on the paper,<br class="gmail_msg">
Software for Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,<br class="gmail_msg">
ACM TOMS vol 7 no 3, September 1981, pages 272-283.) and made it generic to<br class="gmail_msg">
arbitrary IEEE floats.<br class="gmail_msg">
<br class="gmail_msg">
Differential Revision: <a href="https://reviews.llvm.org/D26817" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D26817</a><br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    llvm/trunk/include/llvm/ADT/APFloat.h<br class="gmail_msg">
    llvm/trunk/lib/Support/APFloat.cpp<br class="gmail_msg">
    llvm/trunk/unittests/ADT/APFloatTest.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/ADT/APFloat.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=289472&r1=289471&r2=289472&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=289472&r1=289471&r2=289472&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/ADT/APFloat.h Mon Dec 12 15:59:30 2016<br class="gmail_msg">
@@ -27,6 +27,7 @@ struct fltSemantics;<br class="gmail_msg">
 class APSInt;<br class="gmail_msg">
 class StringRef;<br class="gmail_msg">
 class APFloat;<br class="gmail_msg">
+class raw_ostream;<br class="gmail_msg">
<br class="gmail_msg">
 template <typename T> class SmallVectorImpl;<br class="gmail_msg">
<br class="gmail_msg">
@@ -479,6 +480,8 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   /// @}<br class="gmail_msg">
<br class="gmail_msg">
+  cmpResult compareAbsoluteValue(const IEEEFloat &) const;<br class="gmail_msg">
+<br class="gmail_msg">
 private:<br class="gmail_msg">
   /// \name Simple Queries<br class="gmail_msg">
   /// @{<br class="gmail_msg">
@@ -527,7 +530,6 @@ private:<br class="gmail_msg">
   bool convertFromStringSpecials(StringRef str);<br class="gmail_msg">
   opStatus normalize(roundingMode, lostFraction);<br class="gmail_msg">
   opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);<br class="gmail_msg">
-  cmpResult compareAbsoluteValue(const IEEEFloat &) const;<br class="gmail_msg">
   opStatus handleOverflow(roundingMode);<br class="gmail_msg">
   bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;<br class="gmail_msg">
   opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,<br class="gmail_msg">
@@ -600,6 +602,12 @@ class DoubleAPFloat final : public APFlo<br class="gmail_msg">
   const fltSemantics *Semantics;<br class="gmail_msg">
   std::unique_ptr<APFloat[]> Floats;<br class="gmail_msg">
<br class="gmail_msg">
+  opStatus addImpl(const APFloat &a, const APFloat &aa, const APFloat &c,<br class="gmail_msg">
+                   const APFloat &cc, roundingMode RM);<br class="gmail_msg">
+<br class="gmail_msg">
+  opStatus addWithSpecial(const DoubleAPFloat &LHS, const DoubleAPFloat &RHS,<br class="gmail_msg">
+                          DoubleAPFloat &Out, roundingMode RM);<br class="gmail_msg">
+<br class="gmail_msg">
 public:<br class="gmail_msg">
   DoubleAPFloat(const fltSemantics &S);<br class="gmail_msg">
   DoubleAPFloat(const fltSemantics &S, uninitializedTag);<br class="gmail_msg">
@@ -623,6 +631,19 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   APFloat &getFirst() { return Floats[0]; }<br class="gmail_msg">
   const APFloat &getFirst() const { return Floats[0]; }<br class="gmail_msg">
+  APFloat &getSecond() { return Floats[1]; }<br class="gmail_msg">
+  const APFloat &getSecond() const { return Floats[1]; }<br class="gmail_msg">
+<br class="gmail_msg">
+  opStatus add(const DoubleAPFloat &RHS, roundingMode RM);<br class="gmail_msg">
+  opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);<br class="gmail_msg">
+  void changeSign();<br class="gmail_msg">
+  cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;<br class="gmail_msg">
+<br class="gmail_msg">
+  fltCategory getCategory() const;<br class="gmail_msg">
+  bool isNegative() const;<br class="gmail_msg">
+<br class="gmail_msg">
+  void makeInf(bool Neg);<br class="gmail_msg">
+  void makeNaN(bool SNaN, bool Neg, const APInt *fill);<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
 } // End detail namespace<br class="gmail_msg">
@@ -747,7 +768,15 @@ class APFloat : public APFloatBase {<br class="gmail_msg">
<br class="gmail_msg">
   void makeZero(bool Neg) { getIEEE().makeZero(Neg); }<br class="gmail_msg">
<br class="gmail_msg">
-  void makeInf(bool Neg) { getIEEE().makeInf(Neg); }<br class="gmail_msg">
+  void makeInf(bool Neg) {<br class="gmail_msg">
+    if (usesLayout<IEEEFloat>(*U.semantics)) {<br class="gmail_msg">
+      return U.IEEE.makeInf(Neg);<br class="gmail_msg">
+    } else if (usesLayout<DoubleAPFloat>(*U.semantics)) {<br class="gmail_msg">
+      return U.Double.makeInf(Neg);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      llvm_unreachable("Unexpected semantics");<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
<br class="gmail_msg">
   void makeNaN(bool SNaN, bool Neg, const APInt *fill) {<br class="gmail_msg">
     getIEEE().makeNaN(SNaN, Neg, fill);<br class="gmail_msg">
@@ -772,6 +801,17 @@ class APFloat : public APFloatBase {<br class="gmail_msg">
   explicit APFloat(DoubleAPFloat F, const fltSemantics &S)<br class="gmail_msg">
       : U(std::move(F), S) {}<br class="gmail_msg">
<br class="gmail_msg">
+  cmpResult compareAbsoluteValue(const APFloat &RHS) const {<br class="gmail_msg">
+    assert(&getSemantics() == &RHS.getSemantics());<br class="gmail_msg">
+    if (usesLayout<IEEEFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.IEEE.compareAbsoluteValue(RHS.U.IEEE);<br class="gmail_msg">
+    } else if (usesLayout<DoubleAPFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.Double.compareAbsoluteValue(RHS.U.Double);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      llvm_unreachable("Unexpected semantics");<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
 public:<br class="gmail_msg">
   APFloat(const fltSemantics &Semantics) : U(Semantics) {}<br class="gmail_msg">
   APFloat(const fltSemantics &Semantics, StringRef S);<br class="gmail_msg">
@@ -885,10 +925,22 @@ public:<br class="gmail_msg">
   void Profile(FoldingSetNodeID &NID) const { getIEEE().Profile(NID); }<br class="gmail_msg">
<br class="gmail_msg">
   opStatus add(const APFloat &RHS, roundingMode RM) {<br class="gmail_msg">
-    return getIEEE().add(RHS.getIEEE(), RM);<br class="gmail_msg">
+    if (usesLayout<IEEEFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.IEEE.add(RHS.U.IEEE, RM);<br class="gmail_msg">
+    } else if (usesLayout<DoubleAPFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.Double.add(RHS.U.Double, RM);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      llvm_unreachable("Unexpected semantics");<br class="gmail_msg">
+    }<br class="gmail_msg">
   }<br class="gmail_msg">
   opStatus subtract(const APFloat &RHS, roundingMode RM) {<br class="gmail_msg">
-    return getIEEE().subtract(RHS.getIEEE(), RM);<br class="gmail_msg">
+    if (usesLayout<IEEEFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.IEEE.subtract(RHS.U.IEEE, RM);<br class="gmail_msg">
+    } else if (usesLayout<DoubleAPFloat>(getSemantics())) {<br class="gmail_msg">
+      return U.Double.subtract(RHS.U.Double, RM);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      llvm_unreachable("Unexpected semantics");<br class="gmail_msg">
+    }<br class="gmail_msg">
   }<br class="gmail_msg">
   opStatus multiply(const APFloat &RHS, roundingMode RM) {<br class="gmail_msg">
     return getIEEE().multiply(RHS.getIEEE(), RM);<br class="gmail_msg">
@@ -1011,14 +1063,25 @@ public:<br class="gmail_msg">
     return getIEEE().toString(Str, FormatPrecision, FormatMaxPadding);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
+  void print(raw_ostream &) const;<br class="gmail_msg">
+  void dump() const;<br class="gmail_msg">
+<br class="gmail_msg">
   bool getExactInverse(APFloat *inv) const {<br class="gmail_msg">
     return getIEEE().getExactInverse(inv ? &inv->getIEEE() : nullptr);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
+  // This is for internal test only.<br class="gmail_msg">
+  // TODO: Remove it after the PPCDoubleDouble transition.<br class="gmail_msg">
+  const APFloat &getSecondFloat() const {<br class="gmail_msg">
+    assert(&getSemantics() == &PPCDoubleDouble);<br class="gmail_msg">
+    return U.Double.getSecond();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
   friend hash_code hash_value(const APFloat &Arg);<br class="gmail_msg">
   friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); }<br class="gmail_msg">
   friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);<br class="gmail_msg">
   friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);<br class="gmail_msg">
+  friend IEEEFloat;<br class="gmail_msg">
   friend DoubleAPFloat;<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/lib/Support/APFloat.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=289472&r1=289471&r2=289472&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=289472&r1=289471&r2=289472&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/lib/Support/APFloat.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/lib/Support/APFloat.cpp Mon Dec 12 15:59:30 2016<br class="gmail_msg">
@@ -19,8 +19,10 @@<br class="gmail_msg">
 #include "llvm/ADT/Hashing.h"<br class="gmail_msg">
 #include "llvm/ADT/StringExtras.h"<br class="gmail_msg">
 #include "llvm/ADT/StringRef.h"<br class="gmail_msg">
+#include "llvm/Support/Debug.h"<br class="gmail_msg">
 #include "llvm/Support/ErrorHandling.h"<br class="gmail_msg">
 #include "llvm/Support/MathExtras.h"<br class="gmail_msg">
+#include "llvm/Support/raw_ostream.h"<br class="gmail_msg">
 #include <cstring><br class="gmail_msg">
 #include <limits.h><br class="gmail_msg">
<br class="gmail_msg">
@@ -3847,8 +3849,9 @@ DoubleAPFloat::DoubleAPFloat(const fltSe<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)<br class="gmail_msg">
-    : Semantics(&S), Floats(new APFloat[2]{APFloat(PPCDoubleDoubleImpl, I),<br class="gmail_msg">
-                                           APFloat(IEEEdouble)}) {<br class="gmail_msg">
+    : Semantics(&S), Floats(new APFloat[2]{<br class="gmail_msg">
+                         APFloat(PPCDoubleDoubleImpl, I),<br class="gmail_msg">
+                         APFloat(IEEEdouble, APInt(64, I.getRawData()[1]))}) {<br class="gmail_msg">
   assert(Semantics == &PPCDoubleDouble);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
@@ -3858,7 +3861,8 @@ DoubleAPFloat::DoubleAPFloat(const fltSe<br class="gmail_msg">
       Floats(new APFloat[2]{std::move(First), std::move(Second)}) {<br class="gmail_msg">
   assert(Semantics == &PPCDoubleDouble);<br class="gmail_msg">
   // TODO Check for First == &IEEEdouble once the transition is done.<br class="gmail_msg">
-  assert(&Floats[0].getSemantics() == &PPCDoubleDoubleImpl);<br class="gmail_msg">
+  assert(&Floats[0].getSemantics() == &PPCDoubleDoubleImpl ||<br class="gmail_msg">
+         &Floats[0].getSemantics() == &IEEEdouble);<br class="gmail_msg">
   assert(&Floats[1].getSemantics() == &IEEEdouble);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
@@ -3887,6 +3891,198 @@ DoubleAPFloat &DoubleAPFloat::operator=(<br class="gmail_msg">
   return *this;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+// "Software for Doubled-Precision Floating-Point Computations",<br class="gmail_msg">
+// by Seppo Linnainmaa, ACM TOMS vol 7 no 3, September 1981, pages 272-283.<br class="gmail_msg">
+APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,<br class="gmail_msg">
+                                         const APFloat &c, const APFloat &cc,<br class="gmail_msg">
+                                         roundingMode RM) {<br class="gmail_msg">
+  int Status = opOK;<br class="gmail_msg">
+  APFloat z = a;<br class="gmail_msg">
+  Status |= z.add(c, RM);<br class="gmail_msg">
+  if (!z.isFinite()) {<br class="gmail_msg">
+    if (!z.isInfinity()) {<br class="gmail_msg">
+      Floats[0] = std::move(z);<br class="gmail_msg">
+      Floats[1].makeZero(false);<br class="gmail_msg">
+      return (opStatus)Status;<br class="gmail_msg">
+    }<br class="gmail_msg">
+    Status = opOK;<br class="gmail_msg">
+    auto AComparedToC = a.compareAbsoluteValue(c);<br class="gmail_msg">
+    z = cc;<br class="gmail_msg">
+    Status |= z.add(aa, RM);<br class="gmail_msg">
+    if (AComparedToC == APFloat::cmpGreaterThan) {<br class="gmail_msg">
+      // z = cc + aa + c + a;<br class="gmail_msg">
+      Status |= z.add(c, RM);<br class="gmail_msg">
+      Status |= z.add(a, RM);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      // z = cc + aa + a + c;<br class="gmail_msg">
+      Status |= z.add(a, RM);<br class="gmail_msg">
+      Status |= z.add(c, RM);<br class="gmail_msg">
+    }<br class="gmail_msg">
+    if (!z.isFinite()) {<br class="gmail_msg">
+      Floats[0] = std::move(z);<br class="gmail_msg">
+      Floats[1].makeZero(false);<br class="gmail_msg">
+      return (opStatus)Status;<br class="gmail_msg">
+    }<br class="gmail_msg">
+    Floats[0] = z;<br class="gmail_msg">
+    APFloat zz = aa;<br class="gmail_msg">
+    Status |= zz.add(cc, RM);<br class="gmail_msg">
+    if (AComparedToC == APFloat::cmpGreaterThan) {<br class="gmail_msg">
+      // Floats[1] = a - z + c + zz;<br class="gmail_msg">
+      Floats[1] = a;<br class="gmail_msg">
+      Status |= Floats[1].subtract(z, RM);<br class="gmail_msg">
+      Status |= Floats[1].add(c, RM);<br class="gmail_msg">
+      Status |= Floats[1].add(zz, RM);<br class="gmail_msg">
+    } else {<br class="gmail_msg">
+      // Floats[1] = c - z + a + zz;<br class="gmail_msg">
+      Floats[1] = c;<br class="gmail_msg">
+      Status |= Floats[1].subtract(z, RM);<br class="gmail_msg">
+      Status |= Floats[1].add(a, RM);<br class="gmail_msg">
+      Status |= Floats[1].add(zz, RM);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  } else {<br class="gmail_msg">
+    // q = a - z;<br class="gmail_msg">
+    APFloat q = a;<br class="gmail_msg">
+    Status |= q.subtract(z, RM);<br class="gmail_msg">
+<br class="gmail_msg">
+    // zz = q + c + (a - (q + z)) + aa + cc;<br class="gmail_msg">
+    // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.<br class="gmail_msg">
+    auto zz = q;<br class="gmail_msg">
+    Status |= zz.add(c, RM);<br class="gmail_msg">
+    Status |= q.add(z, RM);<br class="gmail_msg">
+    Status |= q.subtract(a, RM);<br class="gmail_msg">
+    q.changeSign();<br class="gmail_msg">
+    Status |= zz.add(q, RM);<br class="gmail_msg">
+    Status |= zz.add(aa, RM);<br class="gmail_msg">
+    Status |= zz.add(cc, RM);<br class="gmail_msg">
+    if (zz.isZero() && !zz.isNegative()) {<br class="gmail_msg">
+      Floats[0] = std::move(z);<br class="gmail_msg">
+      Floats[1].makeZero(false);<br class="gmail_msg">
+      return opOK;<br class="gmail_msg">
+    }<br class="gmail_msg">
+    Floats[0] = z;<br class="gmail_msg">
+    Status |= Floats[0].add(zz, RM);<br class="gmail_msg">
+    if (!Floats[0].isFinite()) {<br class="gmail_msg">
+      Floats[1].makeZero(false);<br class="gmail_msg">
+      return (opStatus)Status;<br class="gmail_msg">
+    }<br class="gmail_msg">
+    Floats[1] = std::move(z);<br class="gmail_msg">
+    Status |= Floats[1].subtract(Floats[0], RM);<br class="gmail_msg">
+    Status |= Floats[1].add(zz, RM);<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return (opStatus)Status;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,<br class="gmail_msg">
+                                                const DoubleAPFloat &RHS,<br class="gmail_msg">
+                                                DoubleAPFloat &Out,<br class="gmail_msg">
+                                                roundingMode RM) {<br class="gmail_msg">
+  if (LHS.getCategory() == fcNaN) {<br class="gmail_msg">
+    Out = LHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (RHS.getCategory() == fcNaN) {<br class="gmail_msg">
+    Out = RHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (LHS.getCategory() == fcZero) {<br class="gmail_msg">
+    Out = RHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (RHS.getCategory() == fcZero) {<br class="gmail_msg">
+    Out = LHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity &&<br class="gmail_msg">
+      LHS.isNegative() != RHS.isNegative()) {<br class="gmail_msg">
+    Out.makeNaN(false, Out.isNegative(), nullptr);<br class="gmail_msg">
+    return opInvalidOp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (LHS.getCategory() == fcInfinity) {<br class="gmail_msg">
+    Out = LHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (RHS.getCategory() == fcInfinity) {<br class="gmail_msg">
+    Out = RHS;<br class="gmail_msg">
+    return opOK;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal);<br class="gmail_msg">
+<br class="gmail_msg">
+  // These conversions will go away once PPCDoubleDoubleImpl goes away.<br class="gmail_msg">
+  // (PPCDoubleDoubleImpl, IEEEDouble) -> (IEEEDouble, IEEEDouble)<br class="gmail_msg">
+  APFloat A(IEEEdouble,<br class="gmail_msg">
+            APInt(64, LHS.Floats[0].bitcastToAPInt().getRawData()[0])),<br class="gmail_msg">
+      AA(LHS.Floats[1]),<br class="gmail_msg">
+      C(IEEEdouble, APInt(64, RHS.Floats[0].bitcastToAPInt().getRawData()[0])),<br class="gmail_msg">
+      CC(RHS.Floats[1]);<br class="gmail_msg">
+  assert(&AA.getSemantics() == &IEEEdouble);<br class="gmail_msg">
+  assert(&CC.getSemantics() == &IEEEdouble);<br class="gmail_msg">
+  Out.Floats[0] = APFloat(IEEEdouble);<br class="gmail_msg">
+  assert(&Out.Floats[1].getSemantics() == &IEEEdouble);<br class="gmail_msg">
+<br class="gmail_msg">
+  auto Ret = Out.addImpl(A, AA, C, CC, RM);<br class="gmail_msg">
+<br class="gmail_msg">
+  // (IEEEDouble, IEEEDouble) -> (PPCDoubleDoubleImpl, IEEEDouble)<br class="gmail_msg">
+  uint64_t Buffer[] = {Out.Floats[0].bitcastToAPInt().getRawData()[0],<br class="gmail_msg">
+                       Out.Floats[1].bitcastToAPInt().getRawData()[0]};<br class="gmail_msg">
+  Out.Floats[0] = APFloat(PPCDoubleDoubleImpl, APInt(128, 2, Buffer));<br class="gmail_msg">
+  return Ret;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS,<br class="gmail_msg">
+                                     roundingMode RM) {<br class="gmail_msg">
+  return addWithSpecial(*this, RHS, *this, RM);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS,<br class="gmail_msg">
+                                          roundingMode RM) {<br class="gmail_msg">
+  changeSign();<br class="gmail_msg">
+  auto Ret = add(RHS, RM);<br class="gmail_msg">
+  changeSign();<br class="gmail_msg">
+  return Ret;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+void DoubleAPFloat::changeSign() {<br class="gmail_msg">
+  Floats[0].changeSign();<br class="gmail_msg">
+  Floats[1].changeSign();<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+APFloat::cmpResult<br class="gmail_msg">
+DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const {<br class="gmail_msg">
+  auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]);<br class="gmail_msg">
+  if (Result != cmpEqual)<br class="gmail_msg">
+    return Result;<br class="gmail_msg">
+  Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]);<br class="gmail_msg">
+  if (Result == cmpLessThan || Result == cmpGreaterThan) {<br class="gmail_msg">
+    auto Against = Floats[0].isNegative() ^ Floats[1].isNegative();<br class="gmail_msg">
+    auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative();<br class="gmail_msg">
+    if (Against && !RHSAgainst)<br class="gmail_msg">
+      return cmpLessThan;<br class="gmail_msg">
+    if (!Against && RHSAgainst)<br class="gmail_msg">
+      return cmpGreaterThan;<br class="gmail_msg">
+    if (!Against && !RHSAgainst)<br class="gmail_msg">
+      return Result;<br class="gmail_msg">
+    if (Against && RHSAgainst)<br class="gmail_msg">
+      return (cmpResult)(cmpLessThan + cmpGreaterThan - Result);<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return Result;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+APFloat::fltCategory DoubleAPFloat::getCategory() const {<br class="gmail_msg">
+  return Floats[0].getCategory();<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); }<br class="gmail_msg">
+<br class="gmail_msg">
+void DoubleAPFloat::makeInf(bool Neg) {<br class="gmail_msg">
+  Floats[0].makeInf(Neg);<br class="gmail_msg">
+  Floats[1].makeZero(false);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) {<br class="gmail_msg">
+  Floats[0].makeNaN(SNaN, Neg, fill);<br class="gmail_msg">
+  Floats[1].makeZero(false);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 } // End detail namespace<br class="gmail_msg">
<br class="gmail_msg">
 APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {<br class="gmail_msg">
@@ -3959,4 +4155,12 @@ APFloat APFloat::getAllOnesValue(unsigne<br class="gmail_msg">
   }<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+void APFloat::print(raw_ostream &OS) const {<br class="gmail_msg">
+  SmallVector<char, 16> Buffer;<br class="gmail_msg">
+  toString(Buffer);<br class="gmail_msg">
+  OS << Buffer << "\n";<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+void APFloat::dump() const { print(dbgs()); }<br class="gmail_msg">
+<br class="gmail_msg">
 } // End llvm namespace<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=289472&r1=289471&r2=289472&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=289472&r1=289471&r2=289472&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/unittests/ADT/APFloatTest.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/unittests/ADT/APFloatTest.cpp Mon Dec 12 15:59:30 2016<br class="gmail_msg">
@@ -1512,22 +1512,6 @@ TEST(APFloatTest, PPCDoubleDouble) {<br class="gmail_msg">
   EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
   EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);<br class="gmail_msg">
<br class="gmail_msg">
-  test = APFloat(APFloat::PPCDoubleDouble, "1.0");<br class="gmail_msg">
-  test.add(APFloat(APFloat::PPCDoubleDouble, "0x1p-105"), APFloat::rmNearestTiesToEven);<br class="gmail_msg">
-  EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
-  EXPECT_EQ(0x3960000000000000ull, test.bitcastToAPInt().getRawData()[1]);<br class="gmail_msg">
-<br class="gmail_msg">
-  test = APFloat(APFloat::PPCDoubleDouble, "1.0");<br class="gmail_msg">
-  test.add(APFloat(APFloat::PPCDoubleDouble, "0x1p-106"), APFloat::rmNearestTiesToEven);<br class="gmail_msg">
-  EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
-#if 0 // XFAIL<br class="gmail_msg">
-  // This is what we would expect with a true double-double implementation<br class="gmail_msg">
-  EXPECT_EQ(0x3950000000000000ull, test.bitcastToAPInt().getRawData()[1]);<br class="gmail_msg">
-#else<br class="gmail_msg">
-  // This is what we get with our 106-bit mantissa approximation<br class="gmail_msg">
-  EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);<br class="gmail_msg">
-#endif<br class="gmail_msg">
-<br class="gmail_msg">
   // PR30869<br class="gmail_msg">
   {<br class="gmail_msg">
     auto Result = APFloat(APFloat::PPCDoubleDouble, "1.0") +<br class="gmail_msg">
@@ -3186,4 +3170,123 @@ TEST(APFloatTest, frexp) {<br class="gmail_msg">
   EXPECT_EQ(52, Exp);<br class="gmail_msg">
   EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac));<br class="gmail_msg">
 }<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {<br class="gmail_msg">
+  using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,<br class="gmail_msg">
+                              APFloat::fltCategory, APFloat::roundingMode>;<br class="gmail_msg">
+  DataType Data[] = {<br class="gmail_msg">
+      // (1 + 0) + (-1 + 0) = fcZero<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0, APFloat::fcZero,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity<br class="gmail_msg">
+      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7948000000000000ull,<br class="gmail_msg">
+       0ull, APFloat::fcInfinity, APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when<br class="gmail_msg">
+      // PPCDoubleDoubleImpl is gone.<br class="gmail_msg">
+      // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -<br class="gmail_msg">
+      // 160))) = fcNormal<br class="gmail_msg">
+      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7947ffffffffffffull,<br class="gmail_msg">
+       0x75effffffffffffeull, APFloat::fcNormal, APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity<br class="gmail_msg">
+      {0x7fefffffffffffffull, 0x7c8ffffffffffffeull, 0x7fefffffffffffffull,<br class="gmail_msg">
+       0x7c8ffffffffffffeull, APFloat::fcInfinity,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // NaN + (1 + 0) = fcNaN<br class="gmail_msg">
+      {0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0, APFloat::fcNaN,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  for (auto Tp : Data) {<br class="gmail_msg">
+    uint64_t Op1[2], Op2[2];<br class="gmail_msg">
+    APFloat::fltCategory Expected;<br class="gmail_msg">
+    APFloat::roundingMode RM;<br class="gmail_msg">
+    std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;<br class="gmail_msg">
+<br class="gmail_msg">
+    APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));<br class="gmail_msg">
+    APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));<br class="gmail_msg">
+    A1.add(A2, RM);<br class="gmail_msg">
+<br class="gmail_msg">
+    EXPECT_EQ(Expected, A1.getCategory());<br class="gmail_msg">
+  }<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(APFloatTest, PPCDoubleDoubleAdd) {<br class="gmail_msg">
+  using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,<br class="gmail_msg">
+                              uint64_t, APFloat::roundingMode>;<br class="gmail_msg">
+  DataType Data[] = {<br class="gmail_msg">
+      // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x3960000000000000ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0x3950000000000000ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x3950000000000000ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0x3950000000000000ull, 0x3950000000000000ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x3960000000000000ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // (1 + 0) + (epsilon + 0) = (1 + epsilon)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0x0000000000000001ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x0000000000000001ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // TODO: change 0xf950000000000000 to 0xf940000000000000, when<br class="gmail_msg">
+      // PPCDoubleDoubleImpl is gone.<br class="gmail_msg">
+      // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +<br class="gmail_msg">
+      // 1.11111... << (1023 - 52)<br class="gmail_msg">
+      {0x7fefffffffffffffull, 0xf950000000000000ull, 0x7c90000000000000ull, 0,<br class="gmail_msg">
+       0x7fefffffffffffffull, 0x7c8ffffffffffffeull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // TODO: change 0xf950000000000000 to 0xf940000000000000, when<br class="gmail_msg">
+      // PPCDoubleDoubleImpl is gone.<br class="gmail_msg">
+      // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +<br class="gmail_msg">
+      // 1.11111... << (1023 - 52)<br class="gmail_msg">
+      {0x7c90000000000000ull, 0, 0x7fefffffffffffffull, 0xf950000000000000ull,<br class="gmail_msg">
+       0x7fefffffffffffffull, 0x7c8ffffffffffffeull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  for (auto Tp : Data) {<br class="gmail_msg">
+    uint64_t Op1[2], Op2[2], Expected[2];<br class="gmail_msg">
+    APFloat::roundingMode RM;<br class="gmail_msg">
+    std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;<br class="gmail_msg">
+<br class="gmail_msg">
+    APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));<br class="gmail_msg">
+    APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));<br class="gmail_msg">
+    A1.add(A2, RM);<br class="gmail_msg">
+<br class="gmail_msg">
+    EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
+    EXPECT_EQ(Expected[1],<br class="gmail_msg">
+              A1.getSecondFloat().bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
+  }<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(APFloatTest, PPCDoubleDoubleSubtract) {<br class="gmail_msg">
+  using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,<br class="gmail_msg">
+                              uint64_t, APFloat::roundingMode>;<br class="gmail_msg">
+  DataType Data[] = {<br class="gmail_msg">
+      // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0xb960000000000000ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x3960000000000000ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+      // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)<br class="gmail_msg">
+      {0x3ff0000000000000ull, 0, 0xb950000000000000ull, 0,<br class="gmail_msg">
+       0x3ff0000000000000ull, 0x3950000000000000ull,<br class="gmail_msg">
+       APFloat::rmNearestTiesToEven},<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  for (auto Tp : Data) {<br class="gmail_msg">
+    uint64_t Op1[2], Op2[2], Expected[2];<br class="gmail_msg">
+    APFloat::roundingMode RM;<br class="gmail_msg">
+    std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;<br class="gmail_msg">
+<br class="gmail_msg">
+    APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));<br class="gmail_msg">
+    APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));<br class="gmail_msg">
+    A1.subtract(A2, RM);<br class="gmail_msg">
+<br class="gmail_msg">
+    EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
+    EXPECT_EQ(Expected[1],<br class="gmail_msg">
+              A1.getSecondFloat().bitcastToAPInt().getRawData()[0]);<br class="gmail_msg">
+  }<br class="gmail_msg">
+}<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
llvm-commits mailing list<br class="gmail_msg">
<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg">
</blockquote></div><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature"><div dir="ltr">Mike<br>Sent from phone</div></div>