diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index cbb800e..5fbe791 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1212,11 +1212,13 @@ public:
 };
 
 class APFloatStorage : private APNumericStorage {
+  const llvm::fltSemantics *Semantics;
 public:
-  llvm::APFloat getValue(bool IsIEEE) const {
-    return llvm::APFloat(getIntValue(), IsIEEE);
+  llvm::APFloat getValue() const {
+    return llvm::APFloat(*Semantics, getIntValue());
   }
   void setValue(ASTContext &C, const llvm::APFloat &Val) {
+    Semantics = &Val.getSemantics();
     setIntValue(C, Val.bitcastToAPInt());
   }
 };
@@ -1321,7 +1323,7 @@ public:
   static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
 
   llvm::APFloat getValue() const {
-    return APFloatStorage::getValue(FloatingLiteralBits.IsIEEE);
+    return APFloatStorage::getValue();
   }
   void setValue(ASTContext &C, const llvm::APFloat &Val) {
     APFloatStorage::setValue(C, Val);
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index e475c38..1a3492a 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -178,7 +178,6 @@ protected:
     friend class FloatingLiteral;
     unsigned : NumExprBits;
 
-    unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128.
     unsigned IsExact : 1;
   };
 
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 5689d9c..c3412e0 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -646,16 +646,12 @@ FloatingLiteral::FloatingLiteral(ASTContext &C, const llvm::APFloat &V,
                                  bool isexact, QualType Type, SourceLocation L)
   : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
          false, false), Loc(L) {
-  FloatingLiteralBits.IsIEEE =
-    &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad;
   FloatingLiteralBits.IsExact = isexact;
   setValue(C, V);
 }
 
 FloatingLiteral::FloatingLiteral(ASTContext &C, EmptyShell Empty)
   : Expr(FloatingLiteralClass, Empty) {
-  FloatingLiteralBits.IsIEEE =
-    &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad;
   FloatingLiteralBits.IsExact = false;
 }
 
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 338cd74..ddc06d6 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -3630,7 +3630,6 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
     SmallVector<APValue, 4> Elts;
     if (EltTy->isRealFloatingType()) {
       const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
-      bool isIEESem = &Sem != &APFloat::PPCDoubleDouble;
       unsigned FloatEltSize = EltSize;
       if (&Sem == &APFloat::x87DoubleExtended)
         FloatEltSize = 80;
@@ -3640,7 +3639,7 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
           Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
         else
           Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
-        Elts.push_back(APValue(APFloat(Elt, isIEESem)));
+        Elts.push_back(APValue(APFloat(Sem, Elt)));
       }
     } else if (EltTy->isIntegerType()) {
       for (unsigned i = 0; i < NElts; i++) {
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 643deb2..5ec6257 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -28,6 +28,15 @@ enum DeclUpdateKind {
   UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER
 };
 
+enum APFloatSemantics {
+  IEEEhalf,
+  IEEEsingle,
+  IEEEdouble,
+  x87DoubleExtended,
+  IEEEquad,
+  PPCDoubleDouble
+};
+
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
 
 template <typename IdxForTypeTy>
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index eca9918..28c70bc 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6717,7 +6717,30 @@ llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
 
 /// \brief Read a floating-point value
 llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
-  return llvm::APFloat(ReadAPInt(Record, Idx));
+  APFloatSemantics Semantics = static_cast<APFloatSemantics>(Record[Idx++]);
+  const llvm::fltSemantics *Sem;
+  switch (Semantics) {
+  case IEEEhalf:
+    Sem = &llvm::APFloat::IEEEhalf;
+    break;
+  case IEEEsingle:
+    Sem = &llvm::APFloat::IEEEsingle;
+    break;
+  case IEEEdouble:
+    Sem = &llvm::APFloat::IEEEdouble;
+    break;
+  case x87DoubleExtended:
+    Sem = &llvm::APFloat::x87DoubleExtended;
+    break;
+  case IEEEquad:
+    Sem = &llvm::APFloat::IEEEquad;
+    break;
+  case PPCDoubleDouble:
+    Sem = &llvm::APFloat::PPCDoubleDouble;
+    break;
+  }
+
+  return llvm::APFloat(*Sem, ReadAPInt(Record, Idx));
 }
 
 // \brief Read a string
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index ac24098..b2c6049 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3935,6 +3935,24 @@ void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) {
 }
 
 void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) {
+  APFloatSemantics Semantics;
+  const llvm::fltSemantics *Sem = &Value.getSemantics();
+  if (Sem == &llvm::APFloat::IEEEhalf)
+    Semantics = IEEEhalf;
+  else if (Sem == &llvm::APFloat::IEEEsingle)
+    Semantics = IEEEsingle;
+  else if (Sem == &llvm::APFloat::IEEEdouble)
+    Semantics = IEEEdouble;
+  else if (Sem == &llvm::APFloat::x87DoubleExtended)
+    Semantics = x87DoubleExtended;
+  else if (Sem == &llvm::APFloat::IEEEquad)
+    Semantics = IEEEquad;
+  else if (Sem == &llvm::APFloat::PPCDoubleDouble)
+    Semantics = PPCDoubleDouble;
+  else
+    llvm_unreachable("Unknown floating semantics");
+
+  Record.push_back(Semantics);
   AddAPInt(Value.bitcastToAPInt(), Record);
 }
 
