[PATCH] D45460: With -fno-plt, GOTPCREL references must use RIP
Sriraman Tallam via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 9 15:04:20 PDT 2018
tmsriram created this revision.
tmsriram added reviewers: rnk, espindola.
With -fno-plt, global value references can use GOTPCREL and RIP must be used.
A simple example that breaks with -fno-plt:
extern "C"
{
__attribute__((weak)) int weakfunc();
int fp_weakfunc() {
if (&weakfunc)
return 1;
return 0;
}
}
$ clang -O2 -fno-plt -S file.cc
$ cat file.s
...
fp_weakfunc: # @fp_weakfunc
.cfi_startproc
%bb.0:
======
xorl %eax, %eax
cmpq $0, weakfunc at GOTPCREL
...
That's a GOTPCREL reference without %rip. This will force the linker to only patch it with the offset in the GOT and will get the exact opposite program behavior at run-time. This patch fixes it.
https://reviews.llvm.org/D45460
Files:
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
test/CodeGen/X86/no-plt.ll
Index: test/CodeGen/X86/no-plt.ll
===================================================================
--- test/CodeGen/X86/no-plt.ll
+++ test/CodeGen/X86/no-plt.ll
@@ -3,6 +3,13 @@
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu \
; RUN: | FileCheck -check-prefix=X64 --check-prefix=STATIC %s
+define dso_local i32 @fp_weakfunc() local_unnamed_addr #0 {
+entry:
+; X64: weakfunc at 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 at GOTPCREL(%rip)
call void @llvm.memset.p0i8.i32(i8* %a, i8 %c, i32 %n, i1 false)
Index: lib/Target/X86/X86ISelLowering.h
===================================================================
--- lib/Target/X86/X86ISelLowering.h
+++ lib/Target/X86/X86ISelLowering.h
@@ -1201,7 +1201,8 @@
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,
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -15497,7 +15497,8 @@
}
// 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;
@@ -15507,6 +15508,16 @@
(M == CodeModel::Small || M == CodeModel::Kernel))
return X86ISD::WrapperRIP;
+ // GOTPCREL references are possible without PIC when using "nonlazybind"
+ // attribute. Always use RIP when this is found.
+ if (OpFlags == X86II::MO_GOTPCREL) {
+ const Function *F = dyn_cast_or_null<Function>(GV);
+ assert(((F && F->hasFnAttribute(Attribute::NonLazyBind)) ||
+ (!F && GV->getParent()->getRtLibUseGOT())) &&
+ Subtarget.is64Bit());
+ return X86ISD::WrapperRIP;
+ }
+
return X86ISD::Wrapper;
}
@@ -15630,7 +15641,7 @@
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)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45460.141747.patch
Type: text/x-patch
Size: 3020 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180409/63ab7c05/attachment.bin>
More information about the llvm-commits
mailing list