Index: include/llvm/IR/DataLayout.h
===================================================================
--- include/llvm/IR/DataLayout.h
+++ include/llvm/IR/DataLayout.h
@@ -107,6 +107,7 @@
   ManglingModeT ManglingMode;
 
   SmallVector<unsigned char, 8> LegalIntWidths;
+  SmallVector<unsigned char, 8> LegalFloatWidths; ///< Legal Floats.
 
   /// \brief Primitive type alignment data.
   SmallVector<LayoutAlignElem, 16> Alignments;
@@ -184,6 +185,7 @@
     StackNaturalAlign = DL.StackNaturalAlign;
     ManglingMode = DL.ManglingMode;
     LegalIntWidths = DL.LegalIntWidths;
+    LegalFloatWidths = DL.LegalFloatWidths,
     Alignments = DL.Alignments;
     Pointers = DL.Pointers;
     return *this;
@@ -223,6 +225,24 @@
 
   bool isIllegalInteger(unsigned Width) const { return !isLegalInteger(Width); }
 
+	/// isLegalFloat - This function returns true if the specified type is
+	/// known to be a native float type supported by the CPU.  For example,
+	/// f32 is not native on most ARM Thumb CPUs and f37 is not native on any known
+	/// one.  This returns false if the float width is not legal.
+	///
+	/// The width is specified in bits.
+	///
+	bool isLegalFloat(unsigned Width) const {
+		for (unsigned i = 0, e = LegalFloatWidths.size(); i != e; ++i)
+			if (LegalFloatWidths[i] == Width)
+				return true;
+		return false;
+	}
+
+	bool isIllegalFloat(unsigned Width) const {
+		return !isLegalFloat(Width);
+	}
+
   /// Returns true if the given alignment exceeds the natural stack alignment.
   bool exceedsNaturalStackAlignment(unsigned Align) const {
     return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
Index: lib/IR/DataLayout.cpp
===================================================================
--- lib/IR/DataLayout.cpp
+++ lib/IR/DataLayout.cpp
@@ -316,13 +316,23 @@
 
       break;
     }
-    case 'n':  // Native integer types.
+    case 'n':  // Native integer and float types.
       for (;;) {
-        unsigned Width = getInt(Tok);
-        if (Width == 0)
-          report_fatal_error(
-              "Zero width native integer type in datalayout string");
-        LegalIntWidths.push_back(Width);
+		  if (Tok.front() == 'f') {
+			  unsigned Width = getInt(Tok.drop_front());
+              if (Width == 0)
+                report_fatal_error(
+                    "Zero width native float type in datalayout string");
+			  LegalFloatWidths.push_back(Width);
+		  } else {
+			  if (Tok.front() == 'i')
+				  Tok = Tok.drop_front();
+              unsigned Width = getInt(Tok);
+              if (Width == 0)
+                report_fatal_error(
+                    "Zero width native integer type in datalayout string");
+              LegalIntWidths.push_back(Width);
+		  }
         if (Rest.empty())
           break;
         Split = split(Rest, ':');
Index: lib/Target/AArch64/AArch64Subtarget.cpp
===================================================================
--- lib/Target/AArch64/AArch64Subtarget.cpp
+++ lib/Target/AArch64/AArch64Subtarget.cpp
@@ -55,8 +55,8 @@
       // before TLInfo is constructed.
       DL(isTargetMachO()
              ? "e-m:o-i64:64-i128:128-n32:64-S128"
-             : (LittleEndian ? "e-m:e-i64:64-i128:128-n32:64-S128"
-                             : "E-m:e-i64:64-i128:128-n32:64-S128")),
+             : (LittleEndian ? "e-m:e-i64:64-i128:128-n32:64-S128-nf32:f64"
+                             : "E-m:e-i64:64-i128:128-n32:64-S128-nf32:f64")),
       FrameLowering(), InstrInfo(initializeSubtargetDependencies(FS)),
       TSInfo(&DL), TLInfo(TM) {}
 
Index: lib/Target/ARM/ARMSubtarget.h
===================================================================
--- lib/Target/ARM/ARMSubtarget.h
+++ lib/Target/ARM/ARMSubtarget.h
@@ -313,7 +313,9 @@
   bool hasCRC() const { return HasCRC; }
   bool hasVirtualization() const { return HasVirtualization; }
   bool useNEONForSinglePrecisionFP() const {
-    return hasNEON() && UseNEONForSinglePrecisionFP; }
+    return hasNEON() && UseNEONForSinglePrecisionFP;
+  }
+  bool hasFloatingPoint() const { return HasVFPv2 || HasVFPv3 || HasVFPv4 || HasFPARMv8 || HasNEON; }
 
   bool hasDivide() const { return HasHardwareDivide; }
   bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
Index: lib/Target/ARM/ARMSubtarget.cpp
===================================================================
--- lib/Target/ARM/ARMSubtarget.cpp
+++ lib/Target/ARM/ARMSubtarget.cpp
@@ -134,6 +134,15 @@
   else
     Ret += "-S32";
 
+  if (ST.hasFloatingPoint()) {
+    if (ST.hasFP16())
+      Ret += "-nf16";
+    else if (ST.useNEONForSinglePrecisionFP())
+      Ret += "-nf32";
+    else
+      Ret += "-nf32:f64";
+  }
+
   return Ret;
 }
 
Index: lib/Target/Hexagon/HexagonSubtarget.cpp
===================================================================
--- lib/Target/Hexagon/HexagonSubtarget.cpp
+++ lib/Target/Hexagon/HexagonSubtarget.cpp
@@ -48,6 +48,16 @@
     cl::Hidden, cl::ZeroOrMore, cl::init(false),
     cl::desc("Generate non-chopped conversion from fp to int."));
 
+static std::string computeDataLayout(const HexagonSubtarget &ST) {
+  std::string Ret = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32";
+
+  // Add floating point.
+  if (ST.hasV5TOps())
+    Ret += "-nf32";
+
+  return Ret;
+}
+
 HexagonSubtarget &
 HexagonSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
   // If the programmer has not specified a Hexagon version, default to -mv4.
@@ -74,8 +84,8 @@
 HexagonSubtarget::HexagonSubtarget(StringRef TT, StringRef CPU, StringRef FS,
                                    const TargetMachine &TM)
     : HexagonGenSubtargetInfo(TT, CPU, FS), CPUString(CPU.str()),
-      DL("e-m:e-p:32:32-i1:32-i64:64-a:0-n32"),
-      InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM),
+      DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS))),
+      InstrInfo(*this), TLInfo(TM),
       TSInfo(DL), FrameLowering() {
 
   // Initialize scheduling itinerary for the specified CPU.
Index: lib/Target/Mips/MipsSubtarget.cpp
===================================================================
--- lib/Target/Mips/MipsSubtarget.cpp
+++ lib/Target/Mips/MipsSubtarget.cpp
@@ -103,6 +103,9 @@
   else
     Ret += "-n32-S64";
 
+  // 32 and 64 bit floating points are valid.
+  Ret += "-nf32:f64";
+
   return Ret;
 }
 
Index: lib/Target/NVPTX/NVPTXSubtarget.cpp
===================================================================
--- lib/Target/NVPTX/NVPTXSubtarget.cpp
+++ lib/Target/NVPTX/NVPTXSubtarget.cpp
@@ -25,14 +25,20 @@
 // Pin the vtable to this file.
 void NVPTXSubtarget::anchor() {}
 
-static std::string computeDataLayout(bool is64Bit) {
+static std::string computeDataLayout(const NVPTXSubtarget &ST) {
   std::string Ret = "e";
 
-  if (!is64Bit)
+  if (!ST.is64Bit())
     Ret += "-p:32:32";
 
   Ret += "-i64:64-v16:16-v32:32-n16:32:64";
 
+  // Add floating point.
+  Ret += "-nf32";
+
+  if (ST.hasDouble())
+    Ret += ":f64";
+
   return Ret;
 }
 
@@ -57,8 +63,8 @@
                                const std::string &FS, const TargetMachine &TM,
                                bool is64Bit)
     : NVPTXGenSubtargetInfo(TT, CPU, FS), Is64Bit(is64Bit), PTXVersion(0),
-      SmVersion(20), DL(computeDataLayout(is64Bit)),
-      InstrInfo(initializeSubtargetDependencies(CPU, FS)),
+      SmVersion(20), DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS))),
+      InstrInfo(*this),
       TLInfo((const NVPTXTargetMachine &)TM), TSInfo(&DL),
       FrameLowering(*this) {
 
Index: lib/Target/PowerPC/PPCSubtarget.cpp
===================================================================
--- lib/Target/PowerPC/PPCSubtarget.cpp
+++ lib/Target/PowerPC/PPCSubtarget.cpp
@@ -63,6 +63,12 @@
   else
     Ret += "-n32";
 
+  Ret += "-nf32:f64";
+
+  // PPC64 has support for 128-bit floating point (long double)
+  if (is64Bit)
+    Ret += ":f128";
+
   return Ret;
 }
 
Index: lib/Target/R600/AMDGPUSubtarget.cpp
===================================================================
--- lib/Target/R600/AMDGPUSubtarget.cpp
+++ lib/Target/R600/AMDGPUSubtarget.cpp
@@ -42,6 +42,11 @@
   Ret += "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256"
          "-v512:512-v1024:1024-v2048:2048-n32:64";
 
+  // Add floating point.
+  Ret += "-nf32";
+
+  if (ST.hasHWFP64())
+    Ret += ":f64";
   return Ret;
 }
 
Index: lib/Target/Sparc/SparcSubtarget.cpp
===================================================================
--- lib/Target/Sparc/SparcSubtarget.cpp
+++ lib/Target/Sparc/SparcSubtarget.cpp
@@ -49,6 +49,9 @@
   else
     Ret += "-S64";
 
+  // 32 and 64 bit floating points are valid.
+  Ret += "-nf32:f64";
+
   return Ret;
 }
 
Index: lib/Target/SystemZ/SystemZSubtarget.cpp
===================================================================
--- lib/Target/SystemZ/SystemZSubtarget.cpp
+++ lib/Target/SystemZ/SystemZSubtarget.cpp
@@ -48,7 +48,7 @@
       // Make sure that global data has at least 16 bits of alignment by
       // default, so that we can refer to it using LARL.  We don't have any
       // special requirements for stack variables though.
-      DL("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"),
+      DL("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64-nf32:f64"),
       InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM),
       TSInfo(DL), FrameLowering() {}
 
Index: lib/Target/X86/X86Subtarget.cpp
===================================================================
--- lib/Target/X86/X86Subtarget.cpp
+++ lib/Target/X86/X86Subtarget.cpp
@@ -319,6 +319,9 @@
   else
     Ret += "-S128";
 
+  // 32, 64, and 80 bit floating points are valid.
+  Ret += "-nf32:f64:f80";
+
   return Ret;
 }