[llvm] r238487 - Disable x86 tail call optimizations that jump through GOT

Benjamin Kramer benny.kra at gmail.com
Thu May 28 14:05:11 PDT 2015


> On 28.05.2015, at 22:44, Reid Kleckner <reid at kleckner.net> wrote:
> 
> Author: rnk
> Date: Thu May 28 15:44:28 2015
> New Revision: 238487
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=238487&view=rev
> Log:
> Disable x86 tail call optimizations that jump through GOT
> 
> For x86 targets, do not do sibling call optimization when materializing
> the callee's address would require a GOT relocation. We can still do
> tail calls to internal functions, hidden functions, and protected
> functions, because they do not require this kind of relocation. It is
> still possible to get GOT relocations when the user explicitly asks for
> it with musttail or -tailcallopt, both of which are supposed to
> guarantee TCO.
> 
> Based on a patch by Chih-hung Hsieh.
> 
> Reviewers: srhines, timmurray, danalbert, enh, void, nadav, rnk
> 
> Subscribers: joerg, davidxl, llvm-commits
> 
> Differential Revision: http://reviews.llvm.org/D9799
> 
> Added:
>    llvm/trunk/test/CodeGen/X86/tailcallpic3.ll
> Modified:
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>    llvm/trunk/test/CodeGen/X86/pic.ll
>    llvm/trunk/test/CodeGen/X86/tail-call-got.ll
>    llvm/trunk/test/CodeGen/X86/tailcallpic1.ll
> 
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=238487&r1=238486&r2=238487&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu May 28 15:44:28 2015
> @@ -2780,6 +2780,24 @@ X86TargetLowering::LowerCall(TargetLower
>   if (MF.getTarget().Options.DisableTailCalls)
>     isTailCall = false;
> 
> +  if (Subtarget->isPICStyleGOT() &&
> +      !MF.getTarget().Options.GuaranteedTailCallOpt) {
> +    // If we are using a GOT, disable tail calls to external symbols with
> +    // default visibility. Tail calling such a symbol requires using a GOT
> +    // relocation, which forces early binding of the symbol. This breaks code
> +    // that require lazy function symbol resolution. Using musttail or
> +    // GuaranteedTailCallOpt will override this.
> +    GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
> +    if (!G || (!G->getGlobal()->hasLocalLinkage() &&
> +               G->getGlobal()->hasDefaultVisibility())) {
> +      isTailCall = false;
> +      if (G) {
> +        llvm::errs() << "disabling tail call for default visibility symbol\n";
> +        G->getGlobal()->dump();

printf debugging leftovers?

- Ben

> +      }
> +    }
> +  }
> +
>   bool IsMustTail = CLI.CS && CLI.CS->isMustTailCall();
>   if (IsMustTail) {
>     // Force this to be a tail call.  The verifier rules are enough to ensure
> @@ -2964,8 +2982,8 @@ X86TargetLowering::LowerCall(TargetLower
> 
>       // Note: The actual moving to ECX is done further down.
>       GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
> -      if (G && !G->getGlobal()->hasHiddenVisibility() &&
> -          !G->getGlobal()->hasProtectedVisibility())
> +      if (G && !G->getGlobal()->hasLocalLinkage() &&
> +          G->getGlobal()->hasDefaultVisibility())
>         Callee = LowerGlobalAddress(Callee, DAG);
>       else if (isa<ExternalSymbolSDNode>(Callee))
>         Callee = LowerExternalSymbol(Callee, DAG);
> 
> Modified: llvm/trunk/test/CodeGen/X86/pic.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pic.ll?rev=238487&r1=238486&r2=238487&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/pic.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/pic.ll Thu May 28 15:44:28 2015
> @@ -196,9 +196,11 @@ bb12:
> ; LINUX-NEXT: .LJTI7_0:
> ; LINUX:   .long	 .LBB7_2 at GOTOFF
> ; LINUX:   .long	 .LBB7_8 at GOTOFF
> -; LINUX:   .long	 .LBB7_14 at GOTOFF
> -; LINUX:   .long	 .LBB7_9 at GOTOFF
> -; LINUX:   .long	 .LBB7_10 at GOTOFF
> +; LINUX:   .long	 .LBB7_4 at GOTOFF
> +; LINUX:   .long	 .LBB7_6 at GOTOFF
> +; LINUX:   .long	 .LBB7_5 at GOTOFF
> +; LINUX:   .long	 .LBB7_8 at GOTOFF
> +; LINUX:   .long	 .LBB7_7 at GOTOFF
> }
> 
> declare void @foo1(...)
> 
> Modified: llvm/trunk/test/CodeGen/X86/tail-call-got.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-call-got.ll?rev=238487&r1=238486&r2=238487&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/tail-call-got.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/tail-call-got.ll Thu May 28 15:44:28 2015
> @@ -1,12 +1,14 @@
> ; RUN: llc < %s -relocation-model=pic -mattr=+sse2 | FileCheck %s
> 
> +; We used to do tail calls through the GOT for these symbols, but it was
> +; disabled due to PR15086.
> +
> target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
> target triple = "i386-unknown-freebsd9.0"
> 
> define double @test1(double %x) nounwind readnone {
> ; CHECK-LABEL: test1:
> -; CHECK: movl foo at GOT
> -; CHECK-NEXT: jmpl
> +; CHECK:  calll foo at PLT
>   %1 = tail call double @foo(double %x) nounwind readnone
>   ret double %1
> }
> @@ -15,10 +17,18 @@ declare double @foo(double) readnone
> 
> define double @test2(double %x) nounwind readnone {
> ; CHECK-LABEL: test2:
> -; CHECK: movl sin at GOT
> -; CHECK-NEXT: jmpl
> +; CHECK:  calll sin at PLT
>   %1 = tail call double @sin(double %x) nounwind readnone
>   ret double %1
> }
> 
> declare double @sin(double) readnone
> +
> +define double @test3(double %x) nounwind readnone {
> +; CHECK-LABEL: test3:
> +; CHECK:  calll sin2 at PLT
> +  %1 = tail call double @sin2(double %x) nounwind readnone
> +  ret double %1
> +}
> +
> +declare double @sin2(double) readnone
> 
> Modified: llvm/trunk/test/CodeGen/X86/tailcallpic1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic1.ll?rev=238487&r1=238486&r2=238487&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/tailcallpic1.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/tailcallpic1.ll Thu May 28 15:44:28 2015
> @@ -1,5 +1,8 @@
> ; RUN: llc < %s  -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s
> 
> +; This test uses guaranteed TCO so these will be tail calls, despite the early
> +; binding issues.
> +
> define protected fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) {
> entry:
> 	ret i32 %a3
> 
> Added: llvm/trunk/test/CodeGen/X86/tailcallpic3.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic3.ll?rev=238487&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/tailcallpic3.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/tailcallpic3.ll Thu May 28 15:44:28 2015
> @@ -0,0 +1,73 @@
> +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s
> +
> +; While many of these could be tail called, we don't do it because it forces
> +; early binding.
> +
> +declare void @external()
> +
> +define hidden void @tailcallee_hidden() {
> +entry:
> +  ret void
> +}
> +
> +define void @tailcall_hidden() {
> +entry:
> +  tail call void @tailcallee_hidden()
> +  ret void
> +}
> +; CHECK: tailcall_hidden:
> +; CHECK: jmp tailcallee_hidden
> +
> +define internal void @tailcallee_internal() {
> +entry:
> +  ret void
> +}
> +
> +define void @tailcall_internal() {
> +entry:
> +  tail call void @tailcallee_internal()
> +  ret void
> +}
> +; CHECK: tailcall_internal:
> +; CHECK: jmp tailcallee_internal
> +
> +define default void @tailcallee_default() {
> +entry:
> +  ret void
> +}
> +
> +define void @tailcall_default() {
> +entry:
> +  tail call void @tailcallee_default()
> +  ret void
> +}
> +; CHECK: tailcall_default:
> +; CHECK: calll tailcallee_default at PLT
> +
> +define void @tailcallee_default_implicit() {
> +entry:
> +  ret void
> +}
> +
> +define void @tailcall_default_implicit() {
> +entry:
> +  tail call void @tailcallee_default_implicit()
> +  ret void
> +}
> +; CHECK: tailcall_default_implicit:
> +; CHECK: calll tailcallee_default_implicit at PLT
> +
> +define void @tailcall_external() {
> +  tail call void @external()
> +  ret void
> +}
> +; CHECK: tailcall_external:
> +; CHECK: calll external at PLT
> +
> +define void @musttail_external() {
> +  musttail call void @external()
> +  ret void
> +}
> +; CHECK: musttail_external:
> +; CHECK: movl external at GOT
> +; CHECK: jmpl
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list