diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 8 |
2 files changed, 19 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index c8af9725f98..d02a99f081a 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -83,8 +83,12 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { } 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 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { } 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 7713656722a..170e5c383ae 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -548,6 +548,14 @@ public: } } + /// 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. |