diff options
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 7 | ||||
-rw-r--r-- | llvm/lib/IR/Module.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 7 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/no-plt.ll | 17 |
5 files changed, 46 insertions, 2 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 196e32e3615..58e4bc4494f 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -838,6 +838,13 @@ public: Metadata *getProfileSummary(); /// @} + /// Returns true if PLT should be avoided for RTLib calls. + bool getRtLibUseGOT() const; + + /// Set that PLT should be avoid for RTLib calls. + void setRtLibUseGOT(); + + /// Take ownership of the given memory buffer. void setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB); }; diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index c230a50044c..9f1e6096932 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -510,6 +510,15 @@ void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) { OwnedMemoryBuffer = std::move(MB); } +bool Module::getRtLibUseGOT() const { + auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("RtLibUseGOT")); + return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0); +} + +void Module::setRtLibUseGOT() { + addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); +} + GlobalVariable *llvm::collectUsedGlobalVariables( const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) { const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 956de5539d9..537434f5cba 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3779,6 +3779,14 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, Callee = DAG.getTargetExternalSymbol( S->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlags); + + if (OpFlags == X86II::MO_GOTPCREL) { + Callee = DAG.getNode(X86ISD::WrapperRIP, dl, + getPointerTy(DAG.getDataLayout()), Callee); + Callee = DAG.getLoad( + getPointerTy(DAG.getDataLayout()), dl, DAG.getEntryNode(), Callee, + MachinePointerInfo::getGOT(DAG.getMachineFunction())); + } } else if (Subtarget.isTarget64BitILP32() && Callee->getValueType(0) == MVT::i32) { // Zero-extend the 32-bit Callee address into a 64-bit according to x32 ABI diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 0a6eda7e243..c6ebaef587d 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -157,8 +157,11 @@ X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV, // In Regcall calling convention those registers are used for passing // parameters. Thus we need to prevent lazy binding in Regcall. return X86II::MO_GOTPCREL; - if (F && F->hasFnAttribute(Attribute::NonLazyBind) && is64Bit()) - return X86II::MO_GOTPCREL; + // If PLT must be avoided then the call should be via GOTPCREL. + if (((F && F->hasFnAttribute(Attribute::NonLazyBind)) || + (!F && M.getRtLibUseGOT())) && + is64Bit()) + return X86II::MO_GOTPCREL; return X86II::MO_PLT; } diff --git a/llvm/test/CodeGen/X86/no-plt.ll b/llvm/test/CodeGen/X86/no-plt.ll index 9688a2e6f5b..8aa60f60169 100644 --- a/llvm/test/CodeGen/X86/no-plt.ll +++ b/llvm/test/CodeGen/X86/no-plt.ll @@ -3,6 +3,18 @@ ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu \ ; RUN: | FileCheck -check-prefix=X64 --check-prefix=STATIC %s +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) + ret void +} + +define void @memcpy_call(i8* nocapture %a, i8* nocapture readonly %b, i64 %n) { +; X64: callq *memcpy@GOTPCREL(%rip) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i32 1, i1 false) + ret void +} + define i32 @main() { ; X64: callq *foo@GOTPCREL(%rip) ; PIC: callq bar@PLT @@ -20,3 +32,8 @@ define i32 @main() { declare i32 @foo() nonlazybind declare i32 @bar() declare hidden i32 @baz() nonlazybind +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) + +!llvm.module.flags = !{!1} +!1 = !{i32 7, !"RtLibUseGOT", i32 1} |