Index: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -163,6 +163,16 @@ void emitLinkerFlagsForUsed(raw_ostream &OS, const GlobalValue *GV) const override; + + const MCExpr *lowerRelativeReference(const GlobalValue *LHS, + const GlobalValue *RHS, + const TargetMachine &TM) const override; + + /// Given a mergeable constant with the specified size and relocation + /// information, return a section that it should be placed in. + MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, + const Constant *C, + unsigned &Align) const override; }; class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile { Index: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1274,6 +1274,111 @@ emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler()); } +const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( + const GlobalValue *LHS, const GlobalValue *RHS, + const TargetMachine &TM) const { + const Triple &T = TM.getTargetTriple(); + if (!T.isKnownWindowsMSVCEnvironment() && + !T.isWindowsItaniumEnvironment() && + !T.isWindowsCoreCLREnvironment()) + return nullptr; + + // Our symbols should exist in address space zero, cowardly no-op if + // otherwise. + if (LHS->getType()->getPointerAddressSpace() != 0 || + RHS->getType()->getPointerAddressSpace() != 0) + return nullptr; + + // Both ptrtoint instructions must wrap global objects: + // - Only global variables are eligible for image relative relocations. + // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. + // We expect __ImageBase to be a global variable without a section, externally + // defined. + // + // It should look something like this: @__ImageBase = external constant i8 + if (!isa(LHS) || !isa(RHS) || + LHS->isThreadLocal() || RHS->isThreadLocal() || + RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || + cast(RHS)->hasInitializer() || RHS->hasSection()) + return nullptr; + + return MCSymbolRefExpr::create(TM.getSymbol(LHS), + MCSymbolRefExpr::VK_COFF_IMGREL32, + getContext()); +} + +static std::string APIntToHexString(const APInt &AI) { + unsigned Width = (AI.getBitWidth() / 8) * 2; + std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true); + unsigned Size = HexString.size(); + assert(Width >= Size && "hex string is too large!"); + HexString.insert(HexString.begin(), Width - Size, '0'); + + return HexString; +} + +static std::string scalarConstantToHexString(const Constant *C) { + Type *Ty = C->getType(); + if (isa(C)) { + return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits())); + } else if (const auto *CFP = dyn_cast(C)) { + return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); + } else if (const auto *CI = dyn_cast(C)) { + return APIntToHexString(CI->getValue()); + } else { + unsigned NumElements; + if (isa(Ty)) + NumElements = Ty->getVectorNumElements(); + else + NumElements = Ty->getArrayNumElements(); + std::string HexString; + for (int I = NumElements - 1, E = -1; I != E; --I) + HexString += scalarConstantToHexString(C->getAggregateElement(I)); + return HexString; + } +} + +MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( + const DataLayout &DL, SectionKind Kind, const Constant *C, + unsigned &Align) const { + if (Kind.isMergeableConst() && C) { + const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_LNK_COMDAT; + std::string COMDATSymName; + if (Kind.isMergeableConst4()) { + if (Align <= 4) { + COMDATSymName = "__real@" + scalarConstantToHexString(C); + Align = 4; + } + } else if (Kind.isMergeableConst8()) { + if (Align <= 8) { + COMDATSymName = "__real@" + scalarConstantToHexString(C); + Align = 8; + } + } else if (Kind.isMergeableConst16()) { + // FIXME: These may not be appropriate for non-x86 architectures. + if (Align <= 16) { + COMDATSymName = "__xmm@" + scalarConstantToHexString(C); + Align = 16; + } + } else if (Kind.isMergeableConst32()) { + if (Align <= 32) { + COMDATSymName = "__ymm@" + scalarConstantToHexString(C); + Align = 32; + } + } + + if (!COMDATSymName.empty()) + return getContext().getCOFFSection(".rdata", Characteristics, Kind, + COMDATSymName, + COFF::IMAGE_COMDAT_SELECT_ANY); + } + + return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align); +} + + //===----------------------------------------------------------------------===// // Wasm //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp @@ -105,8 +105,6 @@ return llvm::make_unique(); if (TT.isOSBinFormatELF()) return llvm::make_unique(); - if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment()) - return llvm::make_unique(); if (TT.isOSBinFormatCOFF()) return llvm::make_unique(); llvm_unreachable("unknown subtarget type"); Index: llvm/trunk/lib/Target/X86/X86TargetObjectFile.h =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetObjectFile.h +++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.h @@ -71,19 +71,6 @@ void Initialize(MCContext &Ctx, const TargetMachine &TM) override; }; - /// This implementation is used for Windows targets on x86 and x86-64. - class X86WindowsTargetObjectFile : public TargetLoweringObjectFileCOFF { - const MCExpr * - lowerRelativeReference(const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const override; - - /// Given a mergeable constant with the specified size and relocation - /// information, return a section that it should be placed in. - MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, - const Constant *C, - unsigned &Align) const override; - }; - } // end namespace llvm #endif Index: llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp +++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp @@ -91,100 +91,3 @@ TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(TM.Options.UseInitArray); } - -const MCExpr *X86WindowsTargetObjectFile::lowerRelativeReference( - const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const { - // Our symbols should exist in address space zero, cowardly no-op if - // otherwise. - if (LHS->getType()->getPointerAddressSpace() != 0 || - RHS->getType()->getPointerAddressSpace() != 0) - return nullptr; - - // Both ptrtoint instructions must wrap global objects: - // - Only global variables are eligible for image relative relocations. - // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. - // We expect __ImageBase to be a global variable without a section, externally - // defined. - // - // It should look something like this: @__ImageBase = external constant i8 - if (!isa(LHS) || !isa(RHS) || - LHS->isThreadLocal() || RHS->isThreadLocal() || - RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || - cast(RHS)->hasInitializer() || RHS->hasSection()) - return nullptr; - - return MCSymbolRefExpr::create(TM.getSymbol(LHS), - MCSymbolRefExpr::VK_COFF_IMGREL32, - getContext()); -} - -static std::string APIntToHexString(const APInt &AI) { - unsigned Width = (AI.getBitWidth() / 8) * 2; - std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true); - unsigned Size = HexString.size(); - assert(Width >= Size && "hex string is too large!"); - HexString.insert(HexString.begin(), Width - Size, '0'); - - return HexString; -} - -static std::string scalarConstantToHexString(const Constant *C) { - Type *Ty = C->getType(); - if (isa(C)) { - return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits())); - } else if (const auto *CFP = dyn_cast(C)) { - return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); - } else if (const auto *CI = dyn_cast(C)) { - return APIntToHexString(CI->getValue()); - } else { - unsigned NumElements; - if (isa(Ty)) - NumElements = Ty->getVectorNumElements(); - else - NumElements = Ty->getArrayNumElements(); - std::string HexString; - for (int I = NumElements - 1, E = -1; I != E; --I) - HexString += scalarConstantToHexString(C->getAggregateElement(I)); - return HexString; - } -} - -MCSection *X86WindowsTargetObjectFile::getSectionForConstant( - const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { - if (Kind.isMergeableConst() && C) { - const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_LNK_COMDAT; - std::string COMDATSymName; - if (Kind.isMergeableConst4()) { - if (Align <= 4) { - COMDATSymName = "__real@" + scalarConstantToHexString(C); - Align = 4; - } - } else if (Kind.isMergeableConst8()) { - if (Align <= 8) { - COMDATSymName = "__real@" + scalarConstantToHexString(C); - Align = 8; - } - } else if (Kind.isMergeableConst16()) { - if (Align <= 16) { - COMDATSymName = "__xmm@" + scalarConstantToHexString(C); - Align = 16; - } - } else if (Kind.isMergeableConst32()) { - if (Align <= 32) { - COMDATSymName = "__ymm@" + scalarConstantToHexString(C); - Align = 32; - } - } - - if (!COMDATSymName.empty()) - return getContext().getCOFFSection(".rdata", Characteristics, Kind, - COMDATSymName, - COFF::IMAGE_COMDAT_SELECT_ANY); - } - - return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align); -} Index: llvm/trunk/test/MC/AArch64/ir-to-imgrel.ll =================================================================== --- llvm/trunk/test/MC/AArch64/ir-to-imgrel.ll +++ llvm/trunk/test/MC/AArch64/ir-to-imgrel.ll @@ -0,0 +1,11 @@ +; RUN: llc -mtriple=aarch64-pc-win32 %s -o - | FileCheck %s --check-prefix=AARCH64 + +@__ImageBase = external global i8 + +; AARCH64: .xword "?x@@3HA"@IMGREL +@"\01?x@@3HA" = global i64 sub nsw (i64 ptrtoint (i64* @"\01?x@@3HA" to i64), i64 ptrtoint (i8* @__ImageBase to i64)), align 8 + +declare void @f() + +; AARCH64: .xword f@IMGREL +@fp = global i64 sub nsw (i64 ptrtoint (void ()* @f to i64), i64 ptrtoint (i8* @__ImageBase to i64)), align 8