[llvm] r325962 - Intrinsics calls should avoid the PLT when "RtLibUseGOT" metadata is present.

Sriraman Tallam via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 13:32:06 PST 2018


Author: tmsriram
Date: Fri Feb 23 13:32:06 2018
New Revision: 325962

URL: http://llvm.org/viewvc/llvm-project?rev=325962&view=rev
Log:
Intrinsics calls should avoid the PLT when "RtLibUseGOT" metadata is present.

Differential Revision: https://reviews.llvm.org/D42216

Modified:
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86Subtarget.cpp
    llvm/trunk/test/CodeGen/X86/no-plt.ll

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=325962&r1=325961&r2=325962&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Fri Feb 23 13:32:06 2018
@@ -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);
 };

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=325962&r1=325961&r2=325962&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Fri Feb 23 13:32:06 2018
@@ -510,6 +510,15 @@ void Module::setOwnedMemoryBuffer(std::u
   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";

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=325962&r1=325961&r2=325962&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Feb 23 13:32:06 2018
@@ -3779,6 +3779,14 @@ X86TargetLowering::LowerCall(TargetLower
 
     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

Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=325962&r1=325961&r2=325962&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Fri Feb 23 13:32:06 2018
@@ -157,8 +157,11 @@ X86Subtarget::classifyGlobalFunctionRefe
       // 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;
   }
 

Modified: llvm/trunk/test/CodeGen/X86/no-plt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/no-plt.ll?rev=325962&r1=325961&r2=325962&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/no-plt.ll (original)
+++ llvm/trunk/test/CodeGen/X86/no-plt.ll Fri Feb 23 13:32:06 2018
@@ -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 at 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 at 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 at GOTPCREL(%rip)
 ; PIC:    callq bar at 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}




More information about the llvm-commits mailing list