diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h --- a/llvm/include/llvm/IR/AutoUpgrade.h +++ b/llvm/include/llvm/IR/AutoUpgrade.h @@ -87,6 +87,10 @@ /// Upgrade the loop attachment metadata node. MDNode *upgradeInstructionLoopAttachment(MDNode &N); + /// Upgrade the datalayout string by adding a section for address space + /// pointers. + StringRef UpgradeDataLayoutString(StringRef DL, StringRef Triple); + } // End llvm namespace #endif diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -157,7 +157,7 @@ /// The LLVM Module owns a DataLayout that is used for the target independent /// optimizations and code generation. This hook provides a target specific /// check on the validity of this DataLayout. - virtual bool isCompatibleDataLayout(const DataLayout &Candidate) const { + bool isCompatibleDataLayout(const DataLayout &Candidate) const { return DL == Candidate; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3649,6 +3649,11 @@ } Record.clear(); } + + // Upgrade data layout string. + StringRef DL = llvm::UpgradeDataLayoutString(TheModule->getDataLayoutStr(), + TheModule->getTargetTriple()); + TheModule->setDataLayout(DL); } Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata, diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -4113,3 +4113,23 @@ return MDTuple::get(T->getContext(), Ops); } + +StringRef llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { + std::string AddrSpaces = "-p270:32:32-p271:32:32-p272:64:64"; + + // If X86, and the datalayout matches the expected format, add pointer size + // address spaces to the datalayout. + Triple::ArchType Arch = Triple(TT).getArch(); + if ((Arch != llvm::Triple::x86 && Arch != llvm::Triple::x86_64) || + DL.contains(AddrSpaces)) + return DL; + + SmallVector Groups; + Regex R("(e-m:[a-z](-p:32:32)?)(-[if]64:.*$)"); + if (!R.match(DL, &Groups)) + return DL; + + SmallString<1024> Buf; + StringRef Res = (Groups[1] + AddrSpaces + Groups[3]).toStringRef(Buf); + return Res; +} diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h --- a/llvm/lib/Target/X86/X86TargetMachine.h +++ b/llvm/lib/Target/X86/X86TargetMachine.h @@ -30,7 +30,6 @@ class X86TargetMachine final : public LLVMTargetMachine { std::unique_ptr TLOF; mutable StringMap> SubtargetMap; - const DataLayout DLNoAddrSpaces; public: X86TargetMachine(const Target &T, const Triple &TT, StringRef CPU, @@ -53,8 +52,6 @@ TargetLoweringObjectFile *getObjFileLowering() const override { return TLOF.get(); } - - bool isCompatibleDataLayout(const DataLayout &Candidate) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -106,8 +106,7 @@ llvm_unreachable("unknown subtarget type"); } -static std::string computeDataLayout(const Triple &TT, - bool AddressSpaces = true) { +static std::string computeDataLayout(const Triple &TT) { // X86 is little endian std::string Ret = "e"; @@ -119,8 +118,7 @@ Ret += "-p:32:32"; // Address spaces for 32 bit signed, 32 bit unsigned, and 64 bit pointers. - if (AddressSpaces) - Ret += "-p270:32:32-p271:32:32-p272:64:64"; + Ret += "-p270:32:32-p271:32:32-p272:64:64"; // Some ABIs align 64 bit integers and doubles to 64 bits, others to 32. if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl()) @@ -223,8 +221,7 @@ getEffectiveRelocModel(TT, JIT, RM), getEffectiveX86CodeModel(CM, JIT, TT.getArch() == Triple::x86_64), OL), - TLOF(createTLOF(getTargetTriple())), - DLNoAddrSpaces(computeDataLayout(TT, /*AddressSpaces=*/false)) { + TLOF(createTLOF(getTargetTriple())) { // On PS4, the "return address" of a 'noreturn' call must still be within // the calling function, and TrapUnreachable is an easy way to get that. if (TT.isPS4() || TT.isOSBinFormatMachO()) { @@ -318,13 +315,6 @@ return I.get(); } -bool X86TargetMachine::isCompatibleDataLayout( - const DataLayout &Candidate) const { - // Maintain compatibility with datalayouts that don't have address space - // pointer sizes. - return DL == Candidate || DLNoAddrSpaces == Candidate; -} - //===----------------------------------------------------------------------===// // Command line options for x86 //===----------------------------------------------------------------------===// diff --git a/llvm/test/Bitcode/upgrade-datalayout.ll b/llvm/test/Bitcode/upgrade-datalayout.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-datalayout.ll @@ -0,0 +1,9 @@ +; Test to make sure datalayout is automatically upgraded. +; +; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + diff --git a/llvm/test/Bitcode/upgrade-datalayout2.ll b/llvm/test/Bitcode/upgrade-datalayout2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-datalayout2.ll @@ -0,0 +1,10 @@ +; Test to make sure datalayout is not automatically upgraded if it does not +; match a possible x86 datalayout. +; +; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" + diff --git a/llvm/test/Bitcode/upgrade-datalayout3.ll b/llvm/test/Bitcode/upgrade-datalayout3.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-datalayout3.ll @@ -0,0 +1,8 @@ +; Test to make sure datalayout is automatically upgraded. +; +; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s + +target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32" +target triple = "i686-pc-windows-msvc" + +; CHECK: target datalayout = "e-m:w-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-S32"