<div dir="ltr">This has caused <a href="http://llvm.org/bugs/show_bug.cgi?id=18029">http://llvm.org/bugs/show_bug.cgi?id=18029</a> (miscompilation)<div>I am going to revert it now. </div></div><div class="gmail_extra"><br>
<br><div class="gmail_quote">On Thu, Nov 21, 2013 at 11:04 AM, Bill Wendling <span dir="ltr"><<a href="mailto:isanbard@gmail.com" target="_blank">isanbard@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: void<br>
Date: Thu Nov 21 01:04:30 2013<br>
New Revision: 195318<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=195318&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=195318&view=rev</a><br>
Log:<br>
The basic problem is that some mainstream programs cannot deal with the way<br>
clang optimizes tail calls, as in this example:<br>
<br>
int foo(void);<br>
int bar(void) {<br>
 return foo();<br>
}<br>
<br>
where the call is transformed to:<br>
<br>
  calll .L0$pb<br>
.L0$pb:<br>
  popl  %eax<br>
.Ltmp0:<br>
  addl  $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax<br>
  movl  foo@GOT(%eax), %eax<br>
  popl  %ebp<br>
  jmpl  *%eax                   # TAILCALL<br>
<br>
However, the GOT references must all be resolved at dlopen() time, and so this<br>
approach cannot be used with lazy dynamic linking (e.g. using RTLD_LAZY), which<br>
usually populates the PLT with stubs that perform the actual resolving.<br>
<br>
This patch changes X86TargetLowering::LowerCall() to skip tail call<br>
optimization, if the called function is a global or external symbol.<br>
<br>
Patch by Dimitry Andric!<br>
<br>
PR15086<br>
<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
    llvm/trunk/test/CodeGen/X86/tail-call-got.ll<br>
    llvm/trunk/test/CodeGen/X86/tailcallpic2.ll<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=195318&r1=195317&r2=195318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=195318&r1=195317&r2=195318&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Nov 21 01:04:30 2013<br>
@@ -2665,21 +2665,15 @@ X86TargetLowering::LowerCall(TargetLower<br>
       RegsToPass.push_back(std::make_pair(unsigned(X86::EBX),<br>
                DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), getPointerTy())));<br>
     } else {<br>
-      // If we are tail calling and generating PIC/GOT style code load the<br>
-      // address of the callee into ECX. The value in ecx is used as target of<br>
-      // the tail jump. This is done to circumvent the ebx/callee-saved problem<br>
-      // for tail calls on PIC/GOT architectures. Normally we would just put the<br>
-      // address of GOT into ebx and then call target@PLT. But for tail calls<br>
-      // ebx would be restored (since ebx is callee saved) before jumping to the<br>
-      // target@PLT.<br>
-<br>
-      // Note: The actual moving to ECX is done further down.<br>
+      // If we are tail calling a global or external symbol in GOT pic mode, we<br>
+      // cannot use a direct jump, since that would make lazy dynamic linking<br>
+      // impossible (see PR15086).  So pretend this is not a tail call, to<br>
+      // prevent the optimization to a jump.<br>
       GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);<br>
-      if (G && !G->getGlobal()->hasHiddenVisibility() &&<br>
-          !G->getGlobal()->hasProtectedVisibility())<br>
-        Callee = LowerGlobalAddress(Callee, DAG);<br>
-      else if (isa<ExternalSymbolSDNode>(Callee))<br>
-        Callee = LowerExternalSymbol(Callee, DAG);<br>
+      if ((G && !G->getGlobal()->hasHiddenVisibility() &&<br>
+          !G->getGlobal()->hasProtectedVisibility()) ||<br>
+          isa<ExternalSymbolSDNode>(Callee))<br>
+        isTailCall = false;<br>
     }<br>
   }<br>
<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/tail-call-got.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-call-got.ll?rev=195318&r1=195317&r2=195318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-call-got.ll?rev=195318&r1=195317&r2=195318&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/tail-call-got.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/tail-call-got.ll Thu Nov 21 01:04:30 2013<br>
@@ -5,8 +5,7 @@ target triple = "i386-unknown-freebsd9.0<br>
<br>
 define double @test1(double %x) nounwind readnone {<br>
 ; CHECK-LABEL: test1:<br>
-; CHECK: movl foo@GOT<br>
-; CHECK-NEXT: jmpl<br>
+; CHECK: calll foo@PLT<br>
   %1 = tail call double @foo(double %x) nounwind readnone<br>
   ret double %1<br>
 }<br>
@@ -15,8 +14,7 @@ declare double @foo(double) readnone<br>
<br>
 define double @test2(double %x) nounwind readnone {<br>
 ; CHECK-LABEL: test2:<br>
-; CHECK: movl sin@GOT<br>
-; CHECK-NEXT: jmpl<br>
+; CHECK: calll sin@PLT<br>
   %1 = tail call double @sin(double %x) nounwind readnone<br>
   ret double %1<br>
 }<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/tailcallpic2.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic2.ll?rev=195318&r1=195317&r2=195318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic2.ll?rev=195318&r1=195317&r2=195318&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/tailcallpic2.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/tailcallpic2.ll Thu Nov 21 01:04:30 2013<br>
@@ -9,7 +9,7 @@ define fastcc i32 @tailcaller(i32 %in1,<br>
 entry:<br>
        %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 )             ; <i32> [#uses=1]<br>
        ret i32 %tmp11<br>
-; CHECK: movl tailcallee@GOT<br>
-; CHECK: jmpl<br>
+; Note that this call via PLT could be further optimized into a direct call (no GOT, no PLT):<br>
+; CHECK: calll tailcallee@PLT<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>