[llvm] r310152 - [X86] Teach fastisel to select calls to dllimport functions

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 4 17:10:43 PDT 2017


Author: rnk
Date: Fri Aug  4 17:10:43 2017
New Revision: 310152

URL: http://llvm.org/viewvc/llvm-project?rev=310152&view=rev
Log:
[X86] Teach fastisel to select calls to dllimport functions

Summary:
Direct calls to dllimport functions are very common Windows. We should
add them to the -O0 fast path.

Reviewers: rafael

Subscribers: llvm-commits, hiraditya

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

Added:
    llvm/trunk/test/CodeGen/X86/fast-isel-call-cleanup.ll
Modified:
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/lib/Target/X86/X86Subtarget.cpp
    llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll
    llvm/trunk/test/CodeGen/X86/dllimport.ll
    llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=310152&r1=310151&r2=310152&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Fri Aug  4 17:10:43 2017
@@ -1077,10 +1077,6 @@ bool X86FastISel::X86SelectCallAddress(c
         (AM.Base.Reg != 0 || AM.IndexReg != 0))
       return false;
 
-    // Can't handle DLL Import.
-    if (GV->hasDLLImportStorageClass())
-      return false;
-
     // Can't handle TLS.
     if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
       if (GVar->isThreadLocal())
@@ -1089,8 +1085,9 @@ bool X86FastISel::X86SelectCallAddress(c
     // Okay, we've committed to selecting this global. Set up the basic address.
     AM.GV = GV;
 
-    // No ABI requires an extra load for anything other than DLLImport, which
-    // we rejected above. Return a direct reference to the global.
+    // Return a direct reference to the global. Fastisel can handle calls to
+    // functions that require loads, such as dllimport and nonlazybind
+    // functions.
     if (Subtarget->isPICStyleRIPRel()) {
       // Use rip-relative addressing if we can.  Above we verified that the
       // base and index registers are unused.
@@ -3455,19 +3452,28 @@ bool X86FastISel::fastLowerCall(CallLowe
   } else {
     // Direct call.
     assert(GV && "Not a direct call");
-    unsigned CallOpc = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32;
-
     // See if we need any target-specific flags on the GV operand.
     unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
     // Ignore NonLazyBind attribute in FastISel
     if (OpFlags == X86II::MO_GOTPCREL)
       OpFlags = 0;
 
+    // This will be a direct call, or an indirect call through memory for
+    // NonLazyBind calls or dllimport calls.
+    bool NeedLoad = OpFlags == X86II::MO_DLLIMPORT;
+    unsigned CallOpc = NeedLoad
+                           ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
+                           : (Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32);
+
     MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOpc));
+    if (NeedLoad)
+      MIB.addReg(Is64Bit ? X86::RIP : 0).addImm(1).addReg(0);
     if (Symbol)
       MIB.addSym(Symbol, OpFlags);
     else
       MIB.addGlobalAddress(GV, 0, OpFlags);
+    if (NeedLoad)
+      MIB.addReg(0);
   }
 
   // Add a register mask operand representing the call-preserved registers.

Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=310152&r1=310151&r2=310152&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Fri Aug  4 17:10:43 2017
@@ -147,7 +147,12 @@ X86Subtarget::classifyGlobalFunctionRefe
   if (TM.shouldAssumeDSOLocal(M, GV))
     return X86II::MO_NO_FLAG;
 
-  assert(!isTargetCOFF());
+  if (isTargetCOFF()) {
+    assert(GV->hasDLLImportStorageClass() &&
+           "shouldAssumeDSOLocal gave inconsistent answer");
+    return X86II::MO_DLLIMPORT;
+  }
+
   const Function *F = dyn_cast_or_null<Function>(GV);
 
   if (isTargetELF()) {

Modified: llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll?rev=310152&r1=310151&r2=310152&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll Fri Aug  4 17:10:43 2017
@@ -1,7 +1,8 @@
 ; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s
 ; RUN: llc -mtriple x86_64-pc-mingw32 < %s | FileCheck %s
 ;
-; RUN: llc -mtriple x86_64-pc-mingw32 -O0 < %s | FileCheck %s -check-prefix=FAST
+; RUN: llc -mtriple x86_64-pc-mingw32 -O0 < %s | FileCheck %s
+; RUN: llc -mtriple x86_64-pc-windows-msvc -O0 < %s | FileCheck %s
 ; PR6275
 ;
 ; RUN: opt -mtriple x86_64-pc-win32 -O3 -S < %s | FileCheck %s -check-prefix=OPT
@@ -23,8 +24,6 @@ declare void @dummy(...)
 
 define void @use() nounwind {
 ; CHECK:     callq *__imp_fun(%rip)
-; FAST:      movq  __imp_fun(%rip), [[R:%[a-z]{3}]]
-; FAST-NEXT: callq *[[R]]
   call void @fun()
 
 ; CHECK: callq *__imp_inline1(%rip)

Modified: llvm/trunk/test/CodeGen/X86/dllimport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllimport.ll?rev=310152&r1=310151&r2=310152&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllimport.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dllimport.ll Fri Aug  4 17:10:43 2017
@@ -1,7 +1,8 @@
 ; RUN: llc -mtriple i386-pc-win32 < %s | FileCheck %s
 ; RUN: llc -mtriple i386-pc-mingw32 < %s | FileCheck %s
 ;
-; RUN: llc -mtriple i386-pc-mingw32 -O0 < %s | FileCheck %s -check-prefix=FAST
+; RUN: llc -mtriple i386-pc-mingw32 -O0 < %s | FileCheck %s
+; RUN: llc -mtriple i386-pc-windows-msvc -O0 < %s | FileCheck %s
 ; PR6275
 ;
 ; RUN: opt -mtriple i386-pc-win32 -O3 -S < %s | FileCheck %s -check-prefix=OPT
@@ -27,8 +28,6 @@ declare void @dummy(...)
 
 define void @use() nounwind {
 ; CHECK:     calll *__imp__fun
-; FAST:      movl  __imp__fun, [[R:%[a-z]{3}]]
-; FAST-NEXT: calll *[[R]]
   call void @fun()
 
 ; CHECK: calll *__imp__inline1

Added: llvm/trunk/test/CodeGen/X86/fast-isel-call-cleanup.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-call-cleanup.ll?rev=310152&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-call-cleanup.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-call-cleanup.ll Fri Aug  4 17:10:43 2017
@@ -0,0 +1,19 @@
+; RUN: llc -fast-isel -O0 -code-model=large -mcpu=generic -mtriple=x86_64-apple-darwin10 -relocation-model=pic < %s | FileCheck %s
+
+; Check that fast-isel cleans up when it fails to lower a call instruction.
+define void @fastiselcall() {
+entry:
+  %call = call i32 @targetfn(i32 42)
+  ret void
+; CHECK-LABEL: test5:
+; Local value area is still there:
+; CHECK: movl $42, {{%[a-z]+}}
+; Fast-ISel's arg mov is not here:
+; CHECK-NOT: movl $42, (%esp)
+; SDag-ISel's arg mov:
+; CHECK: movabsq $_targetfn, %[[REG:[^ ]*]]
+; CHECK: movl $42, %edi
+; CHECK: callq *%[[REG]]
+
+}
+declare i32 @targetfn(i32)

Modified: llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll?rev=310152&r1=310151&r2=310152&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll Fri Aug  4 17:10:43 2017
@@ -88,22 +88,3 @@ entry:
 ; CHECK: addl $28
 }
 declare fastcc void @test4fastccsret(%struct.a* sret)
-
-
-; Check that fast-isel cleans up when it fails to lower a call instruction.
-define void @test5() {
-entry:
-  %call = call i32 @test5dllimport(i32 42)
-  ret void
-; CHECK-LABEL: test5:
-; Local value area is still there:
-; CHECK: movl $42, {{%[a-z]+}}
-; Fast-ISel's arg push is not here:
-; CHECK-NOT: movl $42, (%esp)
-; SDag-ISel's arg push:
-; CHECK: movl %esp, [[REGISTER:%[a-z]+]]
-; CHECK: movl $42, ([[REGISTER]])
-; CHECK: movl L_test5dllimport$non_lazy_ptr-L8$pb(%eax), %eax
-
-}
-declare dllimport i32 @test5dllimport(i32)




More information about the llvm-commits mailing list