<br><br><div class="gmail_quote">On Fri, Dec 21, 2012 at 3:48 PM, Nadav Rotem <span dir="ltr"><<a href="mailto:nrotem@apple.com" target="_blank">nrotem@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: nadav<br>
Date: Fri Dec 21 17:48:49 2012<br>
New Revision: 170961<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=170961&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=170961&view=rev</a><br>
Log:<br>
In some cases, due to scheduling constraints we copy the EFLAGS.<br>
The only way to read the eflags is using push and pop. If we don't<br>
adjust the stack then we run over the first frame index. This is<br>
not something that we want to do, so we have to make sure that<br>
our machine function does not copy the flags. If it does then<br>
we have to emit the prolog that adjusts the stack.<br>
<br>
rdar://12896831<br>
<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/clobber-fi0.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=170961&r1=170960&r2=170961&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=170961&r1=170960&r2=170961&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Fri Dec 21 17:48:49 2012<br>
@@ -625,6 +625,22 @@<br>
   return CompactUnwindEncoding;<br>
 }<br>
<br>
+/// colobbersTheStack - This function checks if any of the users of EFLAGS<br>
+/// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has<br>
+/// to use the stack, and if we don't adjust the stack we clobber the first<br>
+/// frame index.<br>
+/// See  X86InstrInfo::copyPhysReg.<br>
+static bool colobbersTheStack(MachineFunction &MF) {<br></blockquote><div><br>colobbers?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+<br>
+  for (MachineRegisterInfo::reg_iterator ri = MRI.reg_begin(X86::EFLAGS),<br>
+       re = MRI.reg_end(); ri != re; ++ri)<br>
+    if (ri->isCopy())<br>
+      return true;<br>
+<br>
+  return false;<br>
+}<br>
+<br>
 /// emitPrologue - Push callee-saved registers onto the stack, which<br>
 /// automatically adjust the stack pointer. Adjust the stack pointer to allocate<br>
 /// space for local variables. Also emit labels used by the exception handler to<br>
@@ -673,12 +689,14 @@<br>
   // If this is x86-64 and the Red Zone is not disabled, if we are a leaf<br>
   // function, and use up to 128 bytes of stack space, don't have a frame<br>
   // pointer, calls, or dynamic alloca then we do not need to adjust the<br>
-  // stack pointer (we fit in the Red Zone).<br>
+  // stack pointer (we fit in the Red Zone). We also check that we don't<br>
+  // push and pop from the stack.<br>
   if (Is64Bit && !Fn->getFnAttributes().hasAttribute(Attribute::NoRedZone) &&<br>
       !RegInfo->needsStackRealignment(MF) &&<br>
       !MFI->hasVarSizedObjects() &&                     // No dynamic alloca.<br>
       !MFI->adjustsStack() &&                           // No calls.<br>
       !IsWin64 &&                                       // Win64 has no Red Zone<br>
+      !colobbersTheStack(MF) &&                         // Don't push and pop.<br>
       !MF.getTarget().Options.EnableSegmentedStacks) {  // Regular stack<br>
     uint64_t MinSize = X86FI->getCalleeSavedFrameSize();<br>
     if (HasFP) MinSize += SlotSize;<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=170961&r1=170960&r2=170961&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=170961&r1=170960&r2=170961&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 21 17:48:49 2012<br>
@@ -2892,6 +2892,8 @@<br>
   }<br>
<br>
   // Moving EFLAGS to / from another register requires a push and a pop.<br>
+  // Notice that we have to adjust the stack if we don't want to clobber the<br>
+  // first frame index. See X86FrameLowering.cpp - colobbersTheStack.<br>
   if (SrcReg == X86::EFLAGS) {<br>
     if (X86::GR64RegClass.contains(DestReg)) {<br>
       BuildMI(MBB, MI, DL, get(X86::PUSHF64));<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/clobber-fi0.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/clobber-fi0.ll?rev=170961&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/clobber-fi0.ll?rev=170961&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/clobber-fi0.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/clobber-fi0.ll Fri Dec 21 17:48:49 2012<br>
@@ -0,0 +1,37 @@<br>
+; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s<br>
+<br>
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.7.0"<br>
+<br>
+; In the code below we need to copy the EFLAGS because of scheduling constraints.<br>
+; When copying the EFLAGS we need to write to the stack with push/pop. This forces<br>
+; us to emit the prolog.<br>
+<br>
+; CHECK: main<br>
+; CHECK: subq{{.*}}rsp<br>
+; CHECK: ret<br>
+define i32 @main(i32 %arg, i8** %arg1) nounwind {<br>
+bb:<br>
+  %tmp = alloca i32, align 4                      ; [#uses=3 type=i32*]<br>
+  %tmp2 = alloca i32, align 4                     ; [#uses=3 type=i32*]<br>
+  %tmp3 = alloca i32                              ; [#uses=1 type=i32*]<br>
+  store i32 1, i32* %tmp, align 4<br>
+  store i32 1, i32* %tmp2, align 4<br>
+  br label %bb4<br>
+<br>
+bb4:                                              ; preds = %bb4, %bb<br>
+  %tmp6 = load i32* %tmp2, align 4                ; [#uses=1 type=i32]<br>
+  %tmp7 = add i32 %tmp6, -1                       ; [#uses=2 type=i32]<br>
+  store i32 %tmp7, i32* %tmp2, align 4<br>
+  %tmp8 = icmp eq i32 %tmp7, 0                    ; [#uses=1 type=i1]<br>
+  %tmp9 = load i32* %tmp                          ; [#uses=1 type=i32]<br>
+  %tmp10 = add i32 %tmp9, -1              ; [#uses=1 type=i32]<br>
+  store i32 %tmp10, i32* %tmp3<br>
+  br i1 %tmp8, label %bb11, label %bb4<br>
+<br>
+bb11:                                             ; preds = %bb4<br>
+  %tmp12 = load i32* %tmp, align 4                ; [#uses=1 type=i32]<br>
+  ret i32 %tmp12<br>
+}<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><br clear="all"><br>-- <br>~Craig