Differential Revision: http://reviews.llvm.org/D19040
llvm-svn: 267229
diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp
index c8af972..d02a99f 100644
--- a/llvm/lib/Target/X86/X86Subtarget.cpp
+++ b/llvm/lib/Target/X86/X86Subtarget.cpp
@@ -83,8 +83,12 @@
} else if (!isTargetWin64()) {
assert(isTargetELF() && "Unknown rip-relative target");
- // Extra load is needed for all externally visible globals.
- if (!GV->hasLocalLinkage() && GV->hasDefaultVisibility())
+ // Extra load is needed for all externally visible globals except with
+ // PIE as the definition of the global in an executable is not
+ // overridden.
+
+ if (!GV->hasLocalLinkage() && GV->hasDefaultVisibility() &&
+ !isGlobalDefinedInPIE(GV, TM))
return X86II::MO_GOTPCREL;
}
@@ -92,8 +96,11 @@
}
if (isPICStyleGOT()) { // 32-bit ELF targets.
- // Extra load is needed for all externally visible.
- if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
+ // Extra load is needed for all externally visible globals except with
+ // PIE as the definition of the global in an executable is not overridden.
+
+ if (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
+ isGlobalDefinedInPIE(GV, TM))
return X86II::MO_GOTOFF;
return X86II::MO_GOT;
}
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index 7713656..170e5c3 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -548,6 +548,14 @@
}
}
+ /// Determine if this global is defined in a Position Independent
+ /// Executable (PIE) where its definition cannot be interposed.
+ bool isGlobalDefinedInPIE(const GlobalValue *GV,
+ const TargetMachine &TM) const {
+ return TM.Options.PositionIndependentExecutable &&
+ !GV->isDeclarationForLinker();
+ }
+
/// ClassifyGlobalReference - Classify a global variable reference for the
/// current subtarget according to how we should reference it in a non-pcrel
/// context.