diff options
-rw-r--r-- | llvm/lib/Target/TargetMachine.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 18 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll | 13 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/weak-undef.ll | 4 |
4 files changed, 27 insertions, 22 deletions
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index dd6c288607c..1b05e6ce9f4 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -128,6 +128,15 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M, if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO())) return true; + // Most PIC code sequences that assume that a symbol is local cannot + // produce a 0 if it turns out the symbol is undefined. While this + // is ABI and relocation depended, it seems worth it to handle it + // here. + // FIXME: this is probably not ELF specific. + if (GV && isPositionIndependent() && TT.isOSBinFormatELF() && + GV->hasExternalWeakLinkage()) + return false; + if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility() || GV->isDSOLocal())) return true; @@ -149,9 +158,8 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M, return true; bool IsTLS = GV && GV->isThreadLocal(); - bool IsAccessViaCopyRelocs = Options.MCOptions.MCPIECopyRelocations && GV && - isa<GlobalVariable>(GV) && - !GV->hasExternalWeakLinkage(); + bool IsAccessViaCopyRelocs = + Options.MCOptions.MCPIECopyRelocations && GV && isa<GlobalVariable>(GV); Triple::ArchType Arch = TT.getArch(); bool IsPPC = Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::ppc64le; diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 0de5619cff2..b0ce1335bd3 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -99,22 +99,6 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const { return X86II::MO_GOTOFF; } -static bool shouldAssumeGlobalReferenceLocal(const X86Subtarget *ST, - const TargetMachine &TM, - const Module &M, - const GlobalValue *GV) { - if (!TM.shouldAssumeDSOLocal(M, GV)) - return false; - // A weak reference can end up being 0. If the code can be more that 4g away - // from zero and we are using the small code model we have to treat it as non - // local. - if (GV && GV->hasExternalWeakLinkage() && - TM.getCodeModel() == CodeModel::Small && TM.isPositionIndependent() && - ST->is64Bit() && ST->isTargetELF()) - return false; - return true; -} - unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV, const Module &M) const { // Large model never uses stubs. @@ -134,7 +118,7 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV, } } - if (shouldAssumeGlobalReferenceLocal(this, TM, M, GV)) + if (TM.shouldAssumeDSOLocal(M, GV)) return classifyLocalReference(GV); if (isTargetCOFF()) diff --git a/llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll b/llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll index b370c4eeca9..0918793a4d2 100644 --- a/llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll +++ b/llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll @@ -77,6 +77,19 @@ entry: ret i32* @e } +; ExternalWeak hidden Linkage +@he = extern_weak hidden global i32, align 4 + +define i32* @my_access_global_he() #0 { +; X32-LABEL: my_access_global_he: +; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax +; X32: movl he@GOT(%eax), %eax +; X64-LABEL: my_access_global_he: +; X64: movq he@GOTPCREL(%rip), %rax + ret i32* @he +} + + ; External Linkage, only declaration, store a value. define i32 @my_access_global_store_d() #0 { diff --git a/llvm/test/CodeGen/X86/weak-undef.ll b/llvm/test/CodeGen/X86/weak-undef.ll index 7a71d980aaf..863fea43b16 100644 --- a/llvm/test/CodeGen/X86/weak-undef.ll +++ b/llvm/test/CodeGen/X86/weak-undef.ll @@ -8,7 +8,7 @@ define i32* @bar1() { ; CHECK: bar1: ; CHECK: movq foo1@GOTPCREL(%rip), %rax ; I386: bar1: -; I386: leal foo1@GOTOFF(%eax), %eax +; I386: movl foo1@GOT(%eax), %eax @foo2 = external hidden global i32, align 4 define i32* @bar2() { @@ -46,7 +46,7 @@ define i32()* @bar5() { ; CHECK: bar5: ; CHECK: movq foo5@GOTPCREL(%rip), %rax ; I386: bar5: -; I386: leal foo5@GOTOFF(%eax), %eax +; I386: movl foo5@GOT(%eax), %eax declare external hidden i32 @foo6() define i32()* @bar6() { |