[llvm] r285354 - Revert "[APFloat] Add DoubleAPFloat mode to APFloat. NFC."

Tim Shen via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 27 14:54:30 PDT 2016


Author: timshen
Date: Thu Oct 27 16:54:29 2016
New Revision: 285354

URL: http://llvm.org/viewvc/llvm-project?rev=285354&view=rev
Log:
Revert "[APFloat] Add DoubleAPFloat mode to APFloat. NFC."

This reverts r285351, since it breaks the build.

Modified:
    llvm/trunk/include/llvm/ADT/APFloat.h
    llvm/trunk/lib/Support/APFloat.cpp

Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=285354&r1=285353&r2=285354&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Thu Oct 27 16:54:29 2016
@@ -18,15 +18,12 @@
 #define LLVM_ADT_APFLOAT_H
 
 #include "llvm/ADT/APInt.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <memory>
 
 namespace llvm {
 
 struct fltSemantics;
 class APSInt;
 class StringRef;
-class APFloat;
 
 template <typename T> class SmallVectorImpl;
 
@@ -209,12 +206,13 @@ struct APFloatBase {
 
 namespace detail {
 
-class IEEEFloat final : public APFloatBase {
+class IEEEFloat : public APFloatBase {
 public:
   /// \name Constructors
   /// @{
 
   IEEEFloat(const fltSemantics &); // Default construct to 0.0
+  IEEEFloat(const fltSemantics &, StringRef);
   IEEEFloat(const fltSemantics &, integerPart);
   IEEEFloat(const fltSemantics &, uninitializedTag);
   IEEEFloat(const fltSemantics &, const APInt &);
@@ -232,10 +230,74 @@ public:
   /// \name Convenience "constructors"
   /// @{
 
+  /// Factory for Positive and Negative Zero.
+  ///
+  /// \param Negative True iff the number should be negative.
+  static IEEEFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+    IEEEFloat Val(Sem, uninitialized);
+    Val.makeZero(Negative);
+    return Val;
+  }
+
+  /// Factory for Positive and Negative Infinity.
+  ///
+  /// \param Negative True iff the number should be negative.
+  static IEEEFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+    IEEEFloat Val(Sem, uninitialized);
+    Val.makeInf(Negative);
+    return Val;
+  }
+
+  /// Factory for QNaN values.
+  ///
+  /// \param Negative - True iff the NaN generated should be negative.
+  /// \param type - The unspecified fill bits for creating the NaN, 0 by
+  /// default.  The value is truncated as necessary.
+  static IEEEFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+                          unsigned type = 0) {
+    if (type) {
+      APInt fill(64, type);
+      return getQNaN(Sem, Negative, &fill);
+    } else {
+      return getQNaN(Sem, Negative, nullptr);
+    }
+  }
+
+  /// Factory for QNaN values.
+  static IEEEFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
+                           const APInt *payload = nullptr) {
+    return makeNaN(Sem, false, Negative, payload);
+  }
+
+  /// Factory for SNaN values.
+  static IEEEFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
+                           const APInt *payload = nullptr) {
+    return makeNaN(Sem, true, Negative, payload);
+  }
+
+  /// Returns the largest finite number in the given semantics.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static IEEEFloat getLargest(const fltSemantics &Sem, bool Negative = false);
+
+  /// Returns the smallest (by magnitude) finite number in the given semantics.
+  /// Might be denormalized, which implies a relative loss of precision.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static IEEEFloat getSmallest(const fltSemantics &Sem, bool Negative = false);
+
+  /// Returns the smallest (by magnitude) normalized finite number in the given
+  /// semantics.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static IEEEFloat getSmallestNormalized(const fltSemantics &Sem,
+                                         bool Negative = false);
+
   /// Returns a float which is bitcasted from an all one value int.
   ///
   /// \param BitWidth - Select float type
-  static IEEEFloat getAllOnesValue(unsigned BitWidth);
+  /// \param isIEEE   - If 128 bit number, select between PPC and IEEE
+  static IEEEFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
 
   /// @}
 
@@ -465,25 +527,6 @@ public:
 
   friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
 
-  /// \name Special value setters.
-  /// @{
-
-  void makeLargest(bool Neg = false);
-  void makeSmallest(bool Neg = false);
-  void makeNaN(bool SNaN = false, bool Neg = false,
-               const APInt *fill = nullptr);
-  void makeInf(bool Neg = false);
-  void makeZero(bool Neg = false);
-  void makeQuiet();
-
-  /// Returns the smallest (by magnitude) normalized finite number in the given
-  /// semantics.
-  ///
-  /// \param Negative - True iff the number should be negative
-  void makeSmallestNormalized(bool Negative = false);
-
-  /// @}
-
 private:
   /// \name Simple Queries
   /// @{
@@ -526,6 +569,21 @@ private:
 
   /// @}
 
+  /// \name Special value setters.
+  /// @{
+
+  void makeLargest(bool Neg = false);
+  void makeSmallest(bool Neg = false);
+  void makeNaN(bool SNaN = false, bool Neg = false,
+               const APInt *fill = nullptr);
+  static IEEEFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+                           const APInt *fill);
+  void makeInf(bool Neg = false);
+  void makeZero(bool Neg = false);
+  void makeQuiet();
+
+  /// @}
+
   /// \name Miscellany
   /// @{
 
@@ -566,7 +624,6 @@ private:
   void copySignificand(const IEEEFloat &);
   void freeSignificand();
 
-  /// Note: this must be the first data member.
   /// The semantics that this value obeys.
   const fltSemantics *semantics;
 
@@ -596,426 +653,213 @@ int ilogb(const IEEEFloat &Arg);
 IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode);
 IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM);
 
-// This mode implements more precise float in terms of two APFloats.
-// The interface and layout is designed for arbitray underlying semantics,
-// though currently only PPCDoubleDouble semantics are supported, whose
-// corresponding underlying semantics are IEEEdouble.
-class DoubleAPFloat final : public APFloatBase {
-  // Note: this must be the first data member.
-  const fltSemantics *Semantics;
-  std::unique_ptr<APFloat[]> Floats;
-
-public:
-  DoubleAPFloat(const fltSemantics &S);
-  DoubleAPFloat(const fltSemantics &S, uninitializedTag);
-  DoubleAPFloat(const fltSemantics &S, integerPart);
-  DoubleAPFloat(const fltSemantics &S, const APInt &I);
-  DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second);
-  DoubleAPFloat(const DoubleAPFloat &RHS);
-  DoubleAPFloat(DoubleAPFloat &&RHS);
-
-  DoubleAPFloat &operator=(const DoubleAPFloat &RHS);
-
-  DoubleAPFloat &operator=(DoubleAPFloat &&RHS) {
-    if (this != &RHS) {
-      this->~DoubleAPFloat();
-      new (this) DoubleAPFloat(std::move(RHS));
-    }
-    return *this;
-  }
-
-  bool needsCleanup() const { return Floats != nullptr; }
-
-  APFloat &getFirst() { return Floats[0]; }
-  const APFloat &getFirst() const { return Floats[0]; }
-};
-
 } // End detail namespace
 
 // This is a interface class that is currently forwarding functionalities from
 // detail::IEEEFloat.
 class APFloat : public APFloatBase {
   typedef detail::IEEEFloat IEEEFloat;
-  typedef detail::DoubleAPFloat DoubleAPFloat;
 
   static_assert(std::is_standard_layout<IEEEFloat>::value, "");
 
-  union Storage {
+  union {
     const fltSemantics *semantics;
     IEEEFloat IEEE;
-    DoubleAPFloat Double;
-
-    explicit Storage(IEEEFloat F) : IEEE(std::move(F)) {}
-    explicit Storage(DoubleAPFloat F) : Double(std::move(F)) {}
-
-    template <typename... ArgTypes>
-    Storage(const fltSemantics &Semantics, ArgTypes &&... Args) {
-      if (usesLayout<IEEEFloat>(Semantics)) {
-        new (&IEEE) IEEEFloat(Semantics, std::forward<ArgTypes>(Args)...);
-      } else if (usesLayout<DoubleAPFloat>(Semantics)) {
-        new (&Double) DoubleAPFloat(Semantics, std::forward<ArgTypes>(Args)...);
-      } else {
-        llvm_unreachable("Unexpected semantics");
-      }
-    }
-
-    ~Storage() {
-      if (usesLayout<IEEEFloat>(*semantics)) {
-        IEEE.~IEEEFloat();
-      } else if (usesLayout<DoubleAPFloat>(*semantics)) {
-        Double.~DoubleAPFloat();
-      } else {
-        llvm_unreachable("Unexpected semantics");
-      }
-    }
-
-    Storage(const Storage &RHS) {
-      if (usesLayout<IEEEFloat>(*RHS.semantics)) {
-        new (this) IEEEFloat(RHS.IEEE);
-      } else if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
-        new (this) DoubleAPFloat(RHS.Double);
-      } else {
-        llvm_unreachable("Unexpected semantics");
-      }
-    }
-
-    Storage(Storage &&RHS) {
-      if (usesLayout<IEEEFloat>(*RHS.semantics)) {
-        new (this) IEEEFloat(std::move(RHS.IEEE));
-      } else if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
-        new (this) DoubleAPFloat(std::move(RHS.Double));
-      } else {
-        llvm_unreachable("Unexpected semantics");
-      }
-    }
-
-    Storage &operator=(const Storage &RHS) {
-      if (usesLayout<IEEEFloat>(*semantics) &&
-          usesLayout<IEEEFloat>(*RHS.semantics)) {
-        IEEE = RHS.IEEE;
-      } else if (usesLayout<DoubleAPFloat>(*semantics) &&
-                 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
-        Double = RHS.Double;
-      } else if (this != &RHS) {
-        this->~Storage();
-        new (this) Storage(RHS);
-      }
-      return *this;
-    }
-
-    Storage &operator=(Storage &&RHS) {
-      if (usesLayout<IEEEFloat>(*semantics) &&
-          usesLayout<IEEEFloat>(*RHS.semantics)) {
-        IEEE = std::move(RHS.IEEE);
-      } else if (usesLayout<DoubleAPFloat>(*semantics) &&
-                 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
-        Double = std::move(RHS.Double);
-      } else if (this != &RHS) {
-        this->~Storage();
-        new (this) Storage(RHS);
-      }
-      return *this;
-    }
-  } U;
-
-  template <typename T> static bool usesLayout(const fltSemantics &Semantics) {
-    static_assert(std::is_same<T, IEEEFloat>::value ||
-                  std::is_same<T, DoubleAPFloat>::value, "");
-    if (std::is_same<T, DoubleAPFloat>::value) {
-      return &Semantics == &PPCDoubleDouble;
-    }
-    return &Semantics != &PPCDoubleDouble;
-  }
-
-  IEEEFloat &getIEEE() {
-    if (usesLayout<IEEEFloat>(*U.semantics)) {
-      return U.IEEE;
-    } else if (usesLayout<DoubleAPFloat>(*U.semantics)) {
-      return U.Double.getFirst().U.IEEE;
-    } else {
-      llvm_unreachable("Unexpected semantics");
-    }
-  }
-
-  const IEEEFloat &getIEEE() const {
-    if (usesLayout<IEEEFloat>(*U.semantics)) {
-      return U.IEEE;
-    } else if (usesLayout<DoubleAPFloat>(*U.semantics)) {
-      return U.Double.getFirst().U.IEEE;
-    } else {
-      llvm_unreachable("Unexpected semantics");
-    }
-  }
-
-  void makeZero(bool Neg) { getIEEE().makeZero(Neg); }
-
-  void makeInf(bool Neg) { getIEEE().makeInf(Neg); }
-
-  void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
-    getIEEE().makeNaN(SNaN, Neg, fill);
-  }
-
-  void makeLargest(bool Neg) { getIEEE().makeLargest(Neg); }
-
-  void makeSmallest(bool Neg) { getIEEE().makeSmallest(Neg); }
-
-  void makeSmallestNormalized(bool Neg) {
-    getIEEE().makeSmallestNormalized(Neg);
-  }
+  };
 
-  explicit APFloat(IEEEFloat F) : U(std::move(F)) {}
-  explicit APFloat(DoubleAPFloat F) : U(std::move(F)) {}
+  explicit APFloat(IEEEFloat F) : IEEE(std::move(F)) {}
 
 public:
-  APFloat(const fltSemantics &Semantics) : U(Semantics) {}
+  APFloat(const fltSemantics &Semantics) : APFloat(IEEEFloat(Semantics)) {}
   APFloat(const fltSemantics &Semantics, StringRef S);
-  APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
-  APFloat(const fltSemantics &Semantics, uninitializedTag)
-      : U(Semantics, uninitialized) {}
-  APFloat(const fltSemantics &Semantics, const APInt &I) : U(Semantics, I) {}
-  explicit APFloat(double d) : U(IEEEFloat(d)) {}
-  explicit APFloat(float f) : U(IEEEFloat(f)) {}
-  APFloat(const APFloat &RHS) = default;
-  APFloat(APFloat &&RHS) = default;
-
-  ~APFloat() = default;
-
-  bool needsCleanup() const {
-    if (usesLayout<IEEEFloat>(getSemantics())) {
-      return U.IEEE.needsCleanup();
-    } else if (usesLayout<DoubleAPFloat>(getSemantics())) {
-      return U.Double.needsCleanup();
-    } else {
-      llvm_unreachable("Unexpected semantics");
-    }
-  }
+  APFloat(const fltSemantics &Semantics, integerPart I)
+      : APFloat(IEEEFloat(Semantics, I)) {}
+  APFloat(const fltSemantics &Semantics, uninitializedTag U)
+      : APFloat(IEEEFloat(Semantics, U)) {}
+  APFloat(const fltSemantics &Semantics, const APInt &I)
+      : APFloat(IEEEFloat(Semantics, I)) {}
+  explicit APFloat(double d) : APFloat(IEEEFloat(d)) {}
+  explicit APFloat(float f) : APFloat(IEEEFloat(f)) {}
+  APFloat(const APFloat &RHS) : APFloat(IEEEFloat(RHS.IEEE)) {}
+  APFloat(APFloat &&RHS) : APFloat(IEEEFloat(std::move(RHS.IEEE))) {}
+
+  ~APFloat() { IEEE.~IEEEFloat(); }
+
+  bool needsCleanup() const { return IEEE.needsCleanup(); }
 
-  /// Factory for Positive and Negative Zero.
-  ///
-  /// \param Negative True iff the number should be negative.
   static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeZero(Negative);
-    return Val;
+    return APFloat(IEEEFloat::getZero(Sem, Negative));
   }
 
-  /// Factory for Positive and Negative Infinity.
-  ///
-  /// \param Negative True iff the number should be negative.
   static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeInf(Negative);
-    return Val;
+    return APFloat(IEEEFloat::getInf(Sem, Negative));
   }
 
-  /// Factory for NaN values.
-  ///
-  /// \param Negative - True iff the NaN generated should be negative.
-  /// \param type - The unspecified fill bits for creating the NaN, 0 by
-  /// default.  The value is truncated as necessary.
   static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
                         unsigned type = 0) {
-    if (type) {
-      APInt fill(64, type);
-      return getQNaN(Sem, Negative, &fill);
-    } else {
-      return getQNaN(Sem, Negative, nullptr);
-    }
+    return APFloat(IEEEFloat::getNaN(Sem, Negative, type));
   }
 
-  /// Factory for QNaN values.
   static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
                          const APInt *payload = nullptr) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeNaN(false, Negative, payload);
-    return Val;
+    return APFloat(IEEEFloat::getQNaN(Sem, Negative, payload));
   }
 
-  /// Factory for SNaN values.
   static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
                          const APInt *payload = nullptr) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeNaN(true, Negative, payload);
-    return Val;
+    return APFloat(IEEEFloat::getSNaN(Sem, Negative, payload));
   }
 
-  /// Returns the largest finite number in the given semantics.
-  ///
-  /// \param Negative - True iff the number should be negative
   static APFloat getLargest(const fltSemantics &Sem, bool Negative = false) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeLargest(Negative);
-    return Val;
+    return APFloat(IEEEFloat::getLargest(Sem, Negative));
   }
 
-  /// Returns the smallest (by magnitude) finite number in the given semantics.
-  /// Might be denormalized, which implies a relative loss of precision.
-  ///
-  /// \param Negative - True iff the number should be negative
   static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeSmallest(Negative);
-    return Val;
+    return APFloat(IEEEFloat::getSmallest(Sem, Negative));
   }
 
-  /// Returns the smallest (by magnitude) normalized finite number in the given
-  /// semantics.
-  ///
-  /// \param Negative - True iff the number should be negative
   static APFloat getSmallestNormalized(const fltSemantics &Sem,
                                        bool Negative = false) {
-    APFloat Val(Sem, uninitialized);
-    Val.makeSmallestNormalized(Negative);
-    return Val;
+    return APFloat(IEEEFloat::getSmallestNormalized(Sem, Negative));
   }
 
-  /// Returns a float which is bitcasted from an all one value int.
-  ///
-  /// \param BitWidth - Select float type
-  /// \param isIEEE   - If 128 bit number, select between PPC and IEEE
   static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false) {
-    if (isIEEE) {
-      return APFloat(IEEEFloat::getAllOnesValue(BitWidth));
-    } else {
-      assert(BitWidth == 128);
-      return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
-    }
+    return APFloat(IEEEFloat::getAllOnesValue(BitWidth, isIEEE));
   }
 
-  void Profile(FoldingSetNodeID &NID) const { getIEEE().Profile(NID); }
+  void Profile(FoldingSetNodeID &NID) const { IEEE.Profile(NID); }
 
   opStatus add(const APFloat &RHS, roundingMode RM) {
-    return getIEEE().add(RHS.getIEEE(), RM);
+    return IEEE.add(RHS.IEEE, RM);
   }
   opStatus subtract(const APFloat &RHS, roundingMode RM) {
-    return getIEEE().subtract(RHS.getIEEE(), RM);
+    return IEEE.subtract(RHS.IEEE, RM);
   }
   opStatus multiply(const APFloat &RHS, roundingMode RM) {
-    return getIEEE().multiply(RHS.getIEEE(), RM);
+    return IEEE.multiply(RHS.IEEE, RM);
   }
   opStatus divide(const APFloat &RHS, roundingMode RM) {
-    return getIEEE().divide(RHS.getIEEE(), RM);
-  }
-  opStatus remainder(const APFloat &RHS) {
-    return getIEEE().remainder(RHS.getIEEE());
+    return IEEE.divide(RHS.IEEE, RM);
   }
-  opStatus mod(const APFloat &RHS) { return getIEEE().mod(RHS.getIEEE()); }
+  opStatus remainder(const APFloat &RHS) { return IEEE.remainder(RHS.IEEE); }
+  opStatus mod(const APFloat &RHS) { return IEEE.mod(RHS.IEEE); }
   opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend,
                             roundingMode RM) {
-    return getIEEE().fusedMultiplyAdd(Multiplicand.getIEEE(), Addend.getIEEE(),
-                                      RM);
+    return IEEE.fusedMultiplyAdd(Multiplicand.IEEE, Addend.IEEE, RM);
   }
-  opStatus roundToIntegral(roundingMode RM) {
-    return getIEEE().roundToIntegral(RM);
-  }
-  opStatus next(bool nextDown) { return getIEEE().next(nextDown); }
+  opStatus roundToIntegral(roundingMode RM) { return IEEE.roundToIntegral(RM); }
+  opStatus next(bool nextDown) { return IEEE.next(nextDown); }
 
   APFloat operator+(const APFloat &RHS) const {
-    return APFloat(getIEEE() + RHS.getIEEE());
+    return APFloat(IEEE + RHS.IEEE);
   }
 
   APFloat operator-(const APFloat &RHS) const {
-    return APFloat(getIEEE() - RHS.getIEEE());
+    return APFloat(IEEE - RHS.IEEE);
   }
 
   APFloat operator*(const APFloat &RHS) const {
-    return APFloat(getIEEE() * RHS.getIEEE());
+    return APFloat(IEEE * RHS.IEEE);
   }
 
   APFloat operator/(const APFloat &RHS) const {
-    return APFloat(getIEEE() / RHS.getIEEE());
+    return APFloat(IEEE / RHS.IEEE);
   }
 
-  void changeSign() { getIEEE().changeSign(); }
-  void clearSign() { getIEEE().clearSign(); }
-  void copySign(const APFloat &RHS) { getIEEE().copySign(RHS.getIEEE()); }
+  void changeSign() { IEEE.changeSign(); }
+  void clearSign() { IEEE.clearSign(); }
+  void copySign(const APFloat &RHS) { IEEE.copySign(RHS.IEEE); }
 
   static APFloat copySign(APFloat Value, const APFloat &Sign) {
-    return APFloat(IEEEFloat::copySign(Value.getIEEE(), Sign.getIEEE()));
+    return APFloat(IEEEFloat::copySign(Value.IEEE, Sign.IEEE));
   }
 
   opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
-                   bool *losesInfo);
+                   bool *losesInfo) {
+    return IEEE.convert(ToSemantics, RM, losesInfo);
+  }
   opStatus convertToInteger(integerPart *Input, unsigned int Width,
                             bool IsSigned, roundingMode RM,
                             bool *IsExact) const {
-    return getIEEE().convertToInteger(Input, Width, IsSigned, RM, IsExact);
+    return IEEE.convertToInteger(Input, Width, IsSigned, RM, IsExact);
   }
   opStatus convertToInteger(APSInt &Result, roundingMode RM,
                             bool *IsExact) const {
-    return getIEEE().convertToInteger(Result, RM, IsExact);
+    return IEEE.convertToInteger(Result, RM, IsExact);
   }
   opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
                             roundingMode RM) {
-    return getIEEE().convertFromAPInt(Input, IsSigned, RM);
+    return IEEE.convertFromAPInt(Input, IsSigned, RM);
   }
   opStatus convertFromSignExtendedInteger(const integerPart *Input,
                                           unsigned int InputSize, bool IsSigned,
                                           roundingMode RM) {
-    return getIEEE().convertFromSignExtendedInteger(Input, InputSize, IsSigned,
-                                                    RM);
+    return IEEE.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM);
   }
   opStatus convertFromZeroExtendedInteger(const integerPart *Input,
                                           unsigned int InputSize, bool IsSigned,
                                           roundingMode RM) {
-    return getIEEE().convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
-                                                    RM);
+    return IEEE.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM);
   }
   opStatus convertFromString(StringRef, roundingMode);
-  APInt bitcastToAPInt() const { return getIEEE().bitcastToAPInt(); }
-  double convertToDouble() const { return getIEEE().convertToDouble(); }
-  float convertToFloat() const { return getIEEE().convertToFloat(); }
+  APInt bitcastToAPInt() const { return IEEE.bitcastToAPInt(); }
+  double convertToDouble() const { return IEEE.convertToDouble(); }
+  float convertToFloat() const { return IEEE.convertToFloat(); }
 
   bool operator==(const APFloat &) const = delete;
 
-  cmpResult compare(const APFloat &RHS) const {
-    return getIEEE().compare(RHS.getIEEE());
-  }
+  cmpResult compare(const APFloat &RHS) const { return IEEE.compare(RHS.IEEE); }
 
   bool bitwiseIsEqual(const APFloat &RHS) const {
-    return getIEEE().bitwiseIsEqual(RHS.getIEEE());
+    return IEEE.bitwiseIsEqual(RHS.IEEE);
   }
 
   unsigned int convertToHexString(char *DST, unsigned int HexDigits,
                                   bool UpperCase, roundingMode RM) const {
-    return getIEEE().convertToHexString(DST, HexDigits, UpperCase, RM);
+    return IEEE.convertToHexString(DST, HexDigits, UpperCase, RM);
   }
 
   bool isZero() const { return getCategory() == fcZero; }
   bool isInfinity() const { return getCategory() == fcInfinity; }
   bool isNaN() const { return getCategory() == fcNaN; }
 
-  bool isNegative() const { return getIEEE().isNegative(); }
-  bool isDenormal() const { return getIEEE().isDenormal(); }
-  bool isSignaling() const { return getIEEE().isSignaling(); }
+  bool isNegative() const { return IEEE.isNegative(); }
+  bool isDenormal() const { return IEEE.isDenormal(); }
+  bool isSignaling() const { return IEEE.isSignaling(); }
 
   bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
   bool isFinite() const { return !isNaN() && !isInfinity(); }
 
-  fltCategory getCategory() const { return getIEEE().getCategory(); }
-  const fltSemantics &getSemantics() const { return *U.semantics; }
+  fltCategory getCategory() const { return IEEE.getCategory(); }
+  const fltSemantics &getSemantics() const { return *semantics; }
   bool isNonZero() const { return !isZero(); }
   bool isFiniteNonZero() const { return isFinite() && !isZero(); }
   bool isPosZero() const { return isZero() && !isNegative(); }
   bool isNegZero() const { return isZero() && isNegative(); }
-  bool isSmallest() const { return getIEEE().isSmallest(); }
-  bool isLargest() const { return getIEEE().isLargest(); }
-  bool isInteger() const { return getIEEE().isInteger(); }
+  bool isSmallest() const { return IEEE.isSmallest(); }
+  bool isLargest() const { return IEEE.isLargest(); }
+  bool isInteger() const { return IEEE.isInteger(); }
 
-  APFloat &operator=(const APFloat &RHS) = default;
-  APFloat &operator=(APFloat &&RHS) = default;
+  APFloat &operator=(const APFloat &RHS) {
+    IEEE = RHS.IEEE;
+    return *this;
+  }
+  APFloat &operator=(APFloat &&RHS) {
+    IEEE = std::move(RHS.IEEE);
+    return *this;
+  }
 
   void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
                 unsigned FormatMaxPadding = 3) const {
-    return getIEEE().toString(Str, FormatPrecision, FormatMaxPadding);
+    return IEEE.toString(Str, FormatPrecision, FormatMaxPadding);
   }
 
   bool getExactInverse(APFloat *inv) const {
-    return getIEEE().getExactInverse(inv ? &inv->getIEEE() : nullptr);
+    return IEEE.getExactInverse(inv ? &inv->IEEE : nullptr);
   }
 
   friend hash_code hash_value(const APFloat &Arg);
-  friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); }
+  friend int ilogb(const APFloat &Arg) { return ilogb(Arg.IEEE); }
   friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
   friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);
 };
@@ -1026,7 +870,7 @@ public:
 /// xlC compiler.
 hash_code hash_value(const APFloat &Arg);
 inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) {
-  return APFloat(scalbn(X.getIEEE(), Exp, RM));
+  return APFloat(scalbn(X.IEEE, Exp, RM));
 }
 
 /// \brief Equivalent of C standard library function.
@@ -1034,7 +878,7 @@ inline APFloat scalbn(APFloat X, int Exp
 /// While the C standard says Exp is an unspecified value for infinity and nan,
 /// this returns INT_MAX for infinities, and INT_MIN for NaNs.
 inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) {
-  return APFloat(frexp(X.getIEEE(), Exp, RM));
+  return APFloat(frexp(X.IEEE, Exp, RM));
 }
 /// \brief Returns the absolute value of the argument.
 inline APFloat abs(APFloat X) {

Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=285354&r1=285353&r2=285354&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Thu Oct 27 16:54:29 2016
@@ -75,18 +75,8 @@ namespace llvm {
      to represent all possible values held by a PPC double-double number,
      for example: (long double) 1.0 + (long double) 0x1p-106
      Should this be replaced by a full emulation of PPC double-double?  */
-  const fltSemantics APFloatBase::PPCDoubleDouble = {0, 0, 0, 0};
-
-  /* There are temporary semantics for the real PPCDoubleDouble implementation.
-     Currently, APFloat of PPCDoubleDouble holds one PPCDoubleDoubleImpl as the
-     high part of double double, and one IEEEdouble as the low part, so that
-     the old operations operate on PPCDoubleDoubleImpl, while the newly added
-     operations also populate the IEEEdouble.
-
-     TODO: Once all functions support DoubleAPFloat mode, we'll change all
-     PPCDoubleDoubleImpl to IEEEdouble and remove PPCDoubleDoubleImpl.  */
-  static const fltSemantics PPCDoubleDoubleImpl = {1023, -1022 + 53, 53 + 53,
-                                                   128};
+  const fltSemantics APFloatBase::PPCDoubleDouble = {1023, -1022 + 53, 53 + 53,
+                                                     128};
 
   /* A tight upper bound on number of parts required to hold the value
      pow(5, power) is
@@ -687,6 +677,13 @@ void IEEEFloat::makeNaN(bool SNaN, bool
     APInt::tcSetBit(significand, QNaNBit + 1);
 }
 
+IEEEFloat IEEEFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+                             const APInt *fill) {
+  IEEEFloat value(Sem, uninitialized);
+  value.makeNaN(SNaN, Negative, fill);
+  return value;
+}
+
 IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) {
   if (this != &rhs) {
     if (semantics != rhs.semantics) {
@@ -823,6 +820,11 @@ IEEEFloat::IEEEFloat(const fltSemantics
   initialize(&ourSemantics);
 }
 
+IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, StringRef text) {
+  initialize(&ourSemantics);
+  convertFromString(text, rmNearestTiesToEven);
+}
+
 IEEEFloat::IEEEFloat(const IEEEFloat &rhs) {
   initialize(rhs.semantics);
   assign(rhs);
@@ -2364,8 +2366,7 @@ IEEEFloat::roundSignificandWithExponent(
     excessPrecision = calcSemantics.precision - semantics->precision;
     truncatedBits = excessPrecision;
 
-    IEEEFloat decSig(calcSemantics, uninitialized);
-    decSig.makeZero(sign);
+    IEEEFloat decSig = IEEEFloat::getZero(calcSemantics, sign);
     IEEEFloat pow5(calcSemantics);
 
     sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
@@ -2820,7 +2821,7 @@ APInt IEEEFloat::convertF80LongDoubleAPF
 }
 
 APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
-  assert(semantics == (const llvm::fltSemantics *)&PPCDoubleDoubleImpl);
+  assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
   assert(partCount()==2);
 
   uint64_t words[2];
@@ -3001,7 +3002,7 @@ APInt IEEEFloat::bitcastToAPInt() const
   if (semantics == (const llvm::fltSemantics*)&IEEEquad)
     return convertQuadrupleAPFloatToAPInt();
 
-  if (semantics == (const llvm::fltSemantics *)&PPCDoubleDoubleImpl)
+  if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
     return convertPPCDoubleDoubleAPFloatToAPInt();
 
   assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended &&
@@ -3071,14 +3072,14 @@ void IEEEFloat::initFromPPCDoubleDoubleA
 
   // Get the first double and convert to our format.
   initFromDoubleAPInt(APInt(64, i1));
-  fs = convert(PPCDoubleDoubleImpl, rmNearestTiesToEven, &losesInfo);
+  fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
   assert(fs == opOK && !losesInfo);
   (void)fs;
 
   // Unless we have a special case, add in second double.
   if (isFiniteNonZero()) {
     IEEEFloat v(IEEEdouble, APInt(64, i2));
-    fs = v.convert(PPCDoubleDoubleImpl, rmNearestTiesToEven, &losesInfo);
+    fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
     assert(fs == opOK && !losesInfo);
     (void)fs;
 
@@ -3232,13 +3233,13 @@ void IEEEFloat::initFromAPInt(const fltS
     return initFromF80LongDoubleAPInt(api);
   if (Sem == &IEEEquad)
     return initFromQuadrupleAPInt(api);
-  if (Sem == &PPCDoubleDoubleImpl)
+  if (Sem == &PPCDoubleDouble)
     return initFromPPCDoubleDoubleAPInt(api);
 
   llvm_unreachable(nullptr);
 }
 
-IEEEFloat IEEEFloat::getAllOnesValue(unsigned BitWidth) {
+IEEEFloat IEEEFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) {
   switch (BitWidth) {
   case 16:
     return IEEEFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
@@ -3249,7 +3250,9 @@ IEEEFloat IEEEFloat::getAllOnesValue(uns
   case 80:
     return IEEEFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
   case 128:
-    return IEEEFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
+    if (isIEEE)
+      return IEEEFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
+    return IEEEFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
   default:
     llvm_unreachable("Unknown floating bit width");
   }
@@ -3293,18 +3296,43 @@ void IEEEFloat::makeSmallest(bool Negati
   APInt::tcSet(significandParts(), 1, partCount());
 }
 
-void IEEEFloat::makeSmallestNormalized(bool Negative) {
+IEEEFloat IEEEFloat::getLargest(const fltSemantics &Sem, bool Negative) {
+  // We want (in interchange format):
+  //   sign = {Negative}
+  //   exponent = 1..10
+  //   significand = 1..1
+  IEEEFloat Val(Sem, uninitialized);
+  Val.makeLargest(Negative);
+  return Val;
+}
+
+IEEEFloat IEEEFloat::getSmallest(const fltSemantics &Sem, bool Negative) {
+  // We want (in interchange format):
+  //   sign = {Negative}
+  //   exponent = 0..0
+  //   significand = 0..01
+  IEEEFloat Val(Sem, uninitialized);
+  Val.makeSmallest(Negative);
+  return Val;
+}
+
+IEEEFloat IEEEFloat::getSmallestNormalized(const fltSemantics &Sem,
+                                           bool Negative) {
+  IEEEFloat Val(Sem, uninitialized);
+
   // We want (in interchange format):
   //   sign = {Negative}
   //   exponent = 0..0
   //   significand = 10..0
 
-  category = fcNormal;
-  zeroSignificand();
-  sign = Negative;
-  exponent = semantics->minExponent;
-  significandParts()[partCountForBits(semantics->precision) - 1] |=
-      (((integerPart)1) << ((semantics->precision - 1) % integerPartWidth));
+  Val.category = fcNormal;
+  Val.zeroSignificand();
+  Val.sign = Negative;
+  Val.exponent = Sem.minExponent;
+  Val.significandParts()[partCountForBits(Sem.precision)-1] |=
+    (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
+
+  return Val;
 }
 
 IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) {
@@ -3840,99 +3868,15 @@ IEEEFloat frexp(const IEEEFloat &Val, in
   return scalbn(Val, -Exp, RM);
 }
 
-DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
-    : Semantics(&S), Floats(new APFloat[2]{APFloat(PPCDoubleDoubleImpl),
-                                           APFloat(IEEEdouble)}) {
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
-    : Semantics(&S),
-      Floats(new APFloat[2]{APFloat(PPCDoubleDoubleImpl, uninitialized),
-                            APFloat(IEEEdouble, uninitialized)}) {
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
-    : Semantics(&S), Floats(new APFloat[2]{APFloat(PPCDoubleDoubleImpl, I),
-                                           APFloat(IEEEdouble)}) {
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
-    : Semantics(&S), Floats(new APFloat[2]{APFloat(PPCDoubleDoubleImpl, I),
-                                           APFloat(IEEEdouble)}) {
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
-                             APFloat &&Second)
-    : Semantics(&S),
-      Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
-  assert(Semantics == &PPCDoubleDouble);
-  // TODO Check for First == &IEEEdouble once the transition is done.
-  assert(&Floats[0].getSemantics() == &PPCDoubleDoubleImpl);
-  assert(&Floats[1].getSemantics() == &IEEEdouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
-    : Semantics(RHS.Semantics),
-      Floats(new APFloat[2]{APFloat(RHS.Floats[0]), APFloat(RHS.Floats[1])}) {
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
-    : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) {
-  RHS.Semantics = &Bogus;
-  assert(Semantics == &PPCDoubleDouble);
-}
-
-DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
-  if (Semantics == RHS.Semantics) {
-    Floats[0] = RHS.Floats[0];
-    Floats[1] = RHS.Floats[1];
-  } else if (this != &RHS) {
-    this->~DoubleAPFloat();
-    new (this) DoubleAPFloat(RHS);
-  }
-  return *this;
-}
-
 } // End detail namespace
 
 APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
-  return getIEEE().convertFromString(Str, RM);
+  return IEEE.convertFromString(Str, RM);
 }
 
-hash_code hash_value(const APFloat &Arg) { return hash_value(Arg.getIEEE()); }
+hash_code hash_value(const APFloat &Arg) { return hash_value(Arg.IEEE); }
 
 APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
-    : APFloat(Semantics) {
-  convertFromString(S, rmNearestTiesToEven);
-}
-
-APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
-                                   roundingMode RM, bool *losesInfo) {
-  if (&getSemantics() == &ToSemantics)
-    return opOK;
-  if (usesLayout<IEEEFloat>(getSemantics()) &&
-      usesLayout<IEEEFloat>(ToSemantics)) {
-    return U.IEEE.convert(ToSemantics, RM, losesInfo);
-  } else if (usesLayout<IEEEFloat>(getSemantics()) &&
-             usesLayout<DoubleAPFloat>(ToSemantics)) {
-    assert(&ToSemantics == &PPCDoubleDouble);
-    auto Ret = U.IEEE.convert(PPCDoubleDoubleImpl, RM, losesInfo);
-    *this = APFloat(
-        DoubleAPFloat(PPCDoubleDouble, std::move(*this), APFloat(IEEEdouble)));
-    return Ret;
-  } else if (usesLayout<DoubleAPFloat>(getSemantics()) &&
-             usesLayout<IEEEFloat>(ToSemantics)) {
-    auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
-    *this = APFloat(std::move(getIEEE()));
-    return Ret;
-  } else {
-    llvm_unreachable("Unexpected semantics");
-  }
-}
+    : APFloat(IEEEFloat(Semantics, S)) {}
 
 } // End llvm namespace




More information about the llvm-commits mailing list