Index: include/llvm/IR/DataLayout.h =================================================================== --- include/llvm/IR/DataLayout.h +++ include/llvm/IR/DataLayout.h @@ -107,6 +107,7 @@ ManglingModeT ManglingMode; SmallVector LegalIntWidths; + SmallVector LegalFloatWidths; ///< Legal Floats. /// \brief Primitive type alignment data. SmallVector 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; }