summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/TargetMachine.cpp14
-rw-r--r--llvm/lib/Target/X86/X86Subtarget.cpp18
-rw-r--r--llvm/test/CodeGen/X86/global-access-pie-copyrelocs.ll13
-rw-r--r--llvm/test/CodeGen/X86/weak-undef.ll4
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() {
OpenPOWER on IntegriCloud