[PATCH] D24836: X86: Allow conditional tail calls in Win64 "leaf" functions (PR26302)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 22 10:45:39 PDT 2016


hans created this revision.
hans added reviewers: rnk, majnemer.
hans added a subscriber: llvm-commits.

We can't use Jcc to leave a Win64 function in general, because that confuses the unwinder. However, for "leaf" functions, that is, functions where the return address is always on top of the stack and which don't have unwind info, it's OK.

This depends on https://reviews.llvm.org/D24748

https://reviews.llvm.org/D24836

Files:
  lib/Target/X86/X86ExpandPseudo.cpp
  lib/Target/X86/X86InstrInfo.cpp
  test/CodeGen/X86/conditional-tailcall.ll

Index: test/CodeGen/X86/conditional-tailcall.ll
===================================================================
--- test/CodeGen/X86/conditional-tailcall.ll
+++ test/CodeGen/X86/conditional-tailcall.ll
@@ -1,5 +1,6 @@
-; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s
-; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s
+; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck -check-prefix=CHECK %s
+; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck -check-prefix=CHECK %s
+; RUN: llc < %s -mtriple=x86_64-win32 -show-mc-encoding | FileCheck -check-prefix=CHECK -check-prefix=WIN64 %s
 
 declare void @foo()
 declare void @bar()
@@ -23,6 +24,28 @@
 ; CHECK: jmp foo
 }
 
+define void @f_non_leaf(i32 %x, i32 %y) optsize {
+entry:
+  ; Force %ebx to be spilled on the stack, turning this into
+  ; not a "leaf" function for Win64.
+  tail call void asm sideeffect "", "~{ebx}"()
+
+	%p = icmp eq i32 %x, %y
+  br i1 %p, label %bb1, label %bb2
+bb1:
+  tail call void @foo()
+  ret void
+bb2:
+  tail call void @bar()
+  ret void
+
+; CHECK-LABEL: f_non_leaf:
+; WIN64-NOT: je foo
+; WIN64-NOT: jne bar
+; WIN64: jne
+; WIN64: jmp foo
+; WIN64: jmp bar
+}
 
 declare x86_thiscallcc zeroext i1 @baz(i8*, i32)
 define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize {
Index: lib/Target/X86/X86InstrInfo.cpp
===================================================================
--- lib/Target/X86/X86InstrInfo.cpp
+++ lib/Target/X86/X86InstrInfo.cpp
@@ -4228,9 +4228,9 @@
     return false;
   }
 
-  if (Subtarget.isTargetWin64()) {
+  const MachineFunction *MF = TailCall.getParent()->getParent();
+  if (Subtarget.isTargetWin64() && MF->hasWinCFI()) {
     // Conditional tail calls confuse the Win64 unwinder.
-    // TODO: Allow them for "leaf" functions; PR30337.
     return false;
   }
 
@@ -4240,8 +4240,7 @@
     return false;
   }
 
-  const X86MachineFunctionInfo *X86FI =
-      TailCall.getParent()->getParent()->getInfo<X86MachineFunctionInfo>();
+  const X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
   if (X86FI->getTCReturnAddrDelta() != 0 ||
       TailCall.getOperand(1).getImm() != 0) {
     // A conditional tail call cannot do any stack adjustment.
Index: lib/Target/X86/X86ExpandPseudo.cpp
===================================================================
--- lib/Target/X86/X86ExpandPseudo.cpp
+++ lib/Target/X86/X86ExpandPseudo.cpp
@@ -122,8 +122,9 @@
         Op = X86::TAILJMPd_CC;
         break;
       case X86::TCRETURNdi64cc:
-        assert(!IsWin64 && "Conditional tail calls confuse the Win64 unwinder.");
-        // TODO: We could do it for Win64 "leaf" functions though; PR30337.
+        assert(!MBB.getParent()->hasWinCFI() &&
+               "Conditional tail calls confuse "
+               "the Win64 unwinder.");
         Op = X86::TAILJMPd64_CC;
         break;
       default:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24836.72195.patch
Type: text/x-patch
Size: 2943 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160922/2a88ab76/attachment.bin>


More information about the llvm-commits mailing list