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;
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;
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.
}
}
- if (shouldAssumeGlobalReferenceLocal(this, TM, M, GV))
+ if (TM.shouldAssumeDSOLocal(M, GV))
return classifyLocalReference(GV);
if (isTargetCOFF())
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 {
; 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() {
; 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() {