Index: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp @@ -196,25 +196,22 @@ if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return AArch64II::MO_GOT; - unsigned Flags = AArch64II::MO_NO_FLAG; - if (GV->hasDLLImportStorageClass()) - Flags = AArch64II::MO_DLLIMPORT; - else if (getTargetTriple().isWindowsGNUEnvironment() && - !GV->isDSOLocal() && GV->isDeclarationForLinker() && - isa(GV)) - Flags = AArch64II::MO_COFFSTUB | AArch64II::MO_GOT; - - if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) - return AArch64II::MO_GOT | Flags; + if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) { + if (GV->hasDLLImportStorageClass()) + return AArch64II::MO_GOT | AArch64II::MO_DLLIMPORT; + if (getTargetTriple().isOSWindows()) + return AArch64II::MO_GOT | AArch64II::MO_COFFSTUB; + return AArch64II::MO_GOT; + } // The small code model's direct accesses use ADRP, which cannot // necessarily produce the value 0 (if the code is above 4GB). // Same for the tiny code model, where we have a pc relative LDR. if ((useSmallAddressing() || TM.getCodeModel() == CodeModel::Tiny) && GV->hasExternalWeakLinkage()) - return AArch64II::MO_GOT | Flags; + return AArch64II::MO_GOT; - return Flags; + return AArch64II::MO_NO_FLAG; } unsigned char AArch64Subtarget::classifyGlobalFunctionReference( Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -3317,13 +3317,12 @@ assert(!Subtarget->isROPI() && !Subtarget->isRWPI() && "ROPI/RWPI not currently supported for Windows"); + const TargetMachine &TM = getTargetMachine(); const GlobalValue *GV = cast(Op)->getGlobal(); ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG; if (GV->hasDLLImportStorageClass()) TargetFlags = ARMII::MO_DLLIMPORT; - else if (Subtarget->getTargetTriple().isWindowsGNUEnvironment() && - !GV->isDSOLocal() && GV->isDeclarationForLinker() && - isa(GV)) + else if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) TargetFlags = ARMII::MO_COFFSTUB; EVT PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Result; Index: llvm/trunk/lib/Target/TargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/TargetMachine.cpp +++ llvm/trunk/lib/Target/TargetMachine.cpp @@ -141,6 +141,15 @@ if (GV && GV->hasDLLImportStorageClass()) return false; + // On MinGW, variables that haven't been declared with DLLImport may still + // end up automatically imported by the linker. To make this feasible, + // don't assume the variables to be DSO local unless we actually know + // that for sure. This only has to be done for variables; for functions + // the linker can insert thunks for calling functions from another DLL. + if (TT.isWindowsGNUEnvironment() && GV && GV->isDeclarationForLinker() && + isa(GV)) + return false; + // Every other GV is local on COFF. // Make an exception for windows OS in the triple: Some firmware builds use // *-win32-macho triples. This (accidentally?) produced windows relocations Index: llvm/trunk/lib/Target/X86/X86Subtarget.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp @@ -138,19 +138,14 @@ } } - // For MinGW, if a data reference isn't marked as DSO local or DLLImport, - // and it's a pure declaration without a definition, it might potentially - // be automatically imported from another DLL, thus route accesses via a stub. - if (isTargetWindowsGNU() && GV && !GV->isDSOLocal() && - !GV->hasDLLImportStorageClass() && GV->isDeclarationForLinker() && - isa(GV)) - return X86II::MO_COFFSTUB; - if (TM.shouldAssumeDSOLocal(M, GV)) return classifyLocalReference(GV); - if (isTargetCOFF()) - return X86II::MO_DLLIMPORT; + if (isTargetCOFF()) { + if (GV->hasDLLImportStorageClass()) + return X86II::MO_DLLIMPORT; + return X86II::MO_COFFSTUB; + } if (is64Bit()) { // ELF supports a large, truly PIC code model with non-PC relative GOT