summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp9
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h3
-rw-r--r--llvm/test/CodeGen/X86/no-plt.ll6
3 files changed, 15 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 488666acdde..1870a668c98 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -15502,7 +15502,8 @@ static SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, const X86Subtarget &Subtarget,
}
// Returns the appropriate wrapper opcode for a global reference.
-unsigned X86TargetLowering::getGlobalWrapperKind(const GlobalValue *GV) const {
+unsigned X86TargetLowering::getGlobalWrapperKind(
+ const GlobalValue *GV, const unsigned char OpFlags) const {
// References to absolute symbols are never PC-relative.
if (GV && GV->isAbsoluteSymbolRef())
return X86ISD::Wrapper;
@@ -15512,6 +15513,10 @@ unsigned X86TargetLowering::getGlobalWrapperKind(const GlobalValue *GV) const {
(M == CodeModel::Small || M == CodeModel::Kernel))
return X86ISD::WrapperRIP;
+ // GOTPCREL references must always use RIP.
+ if (OpFlags == X86II::MO_GOTPCREL)
+ return X86ISD::WrapperRIP;
+
return X86ISD::Wrapper;
}
@@ -15635,7 +15640,7 @@ SDValue X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV,
Result = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, OpFlags);
}
- Result = DAG.getNode(getGlobalWrapperKind(GV), dl, PtrVT, Result);
+ Result = DAG.getNode(getGlobalWrapperKind(GV, OpFlags), dl, PtrVT, Result);
// With PIC, the address is actually $g + Offset.
if (isGlobalRelativeToPICBase(OpFlags)) {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 517ac3a1123..dfd2bb19258 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1199,7 +1199,8 @@ namespace llvm {
SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
- unsigned getGlobalWrapperKind(const GlobalValue *GV = nullptr) const;
+ unsigned getGlobalWrapperKind(const GlobalValue *GV = nullptr,
+ const unsigned char OpFlags = 0) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalAddress(const GlobalValue *GV, const SDLoc &dl,
diff --git a/llvm/test/CodeGen/X86/no-plt.ll b/llvm/test/CodeGen/X86/no-plt.ll
index 8aa60f60169..1094c0623d6 100644
--- a/llvm/test/CodeGen/X86/no-plt.ll
+++ b/llvm/test/CodeGen/X86/no-plt.ll
@@ -3,6 +3,12 @@
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu \
; RUN: | FileCheck -check-prefix=X64 --check-prefix=STATIC %s
+define i32 @fp_weakfunc() {
+; X64: weakfunc@GOTPCREL(%rip)
+ ret i32 select (i1 icmp ne (i32 ()* @weakfunc, i32 ()* null), i32 1, i32 0)
+}
+declare extern_weak i32 @weakfunc() nonlazybind
+
define void @memset_call(i8* nocapture %a, i8 %c, i32 %n) {
; X64: callq *memset@GOTPCREL(%rip)
call void @llvm.memset.p0i8.i32(i8* %a, i8 %c, i32 %n, i1 false)
OpenPOWER on IntegriCloud