Author: lattner
Date: Sat Jan 26 13:45:50 2008
New Revision: 46401

URL: http://llvm.org/viewvc/llvm-project?rev=46401&view=rev
Log:
Infer alignment of loads and increase their alignment when we can tell they are 
from the stack.  This allows us to compile stack-align.ll to:

_test:
        movsd   LCPI1_0, %xmm0
        movapd  %xmm0, %xmm1
***     andpd   4(%esp), %xmm1
        andpd   _G, %xmm0
        addsd   %xmm1, %xmm0
        movl    20(%esp), %eax
        movsd   %xmm0, (%eax)
        ret

instead of:

_test:
        movsd   LCPI1_0, %xmm0
**      movsd   4(%esp), %xmm1
**      andpd   %xmm0, %xmm1
        andpd   _G, %xmm0
        addsd   %xmm1, %xmm0
        movl    20(%esp), %eax
        movsd   %xmm0, (%eax)
        ret


Added:
    llvm/trunk/test/CodeGen/X86/stack-align.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=46401&r1=46400&r2=46401&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Jan 26 13:45:50 2008
@@ -18,6 +18,7 @@
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
@@ -4073,13 +4074,41 @@
 static unsigned InferAlignment(SDOperand Ptr, SelectionDAG &DAG) {
   // If this is a direct reference to a stack slot, use information about the
   // stack slot's alignment.
+  int FrameIdx = 1 << 31;
+  int64_t FrameOffset = 0;
   if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Ptr)) {
-    return DAG.getMachineFunction().getFrameInfo()->
-         getObjectAlignment(FI->getIndex());
+    FrameIdx = FI->getIndex();
+  } else if (Ptr.getOpcode() == ISD::ADD && 
+             isa<ConstantSDNode>(Ptr.getOperand(1)) &&
+             isa<FrameIndexSDNode>(Ptr.getOperand(0))) {
+    FrameIdx = cast<FrameIndexSDNode>(Ptr.getOperand(0))->getIndex();
+    FrameOffset = Ptr.getConstantOperandVal(1);
+  }
+             
+  if (FrameIdx != (1 << 31)) {
+    // FIXME: Handle FI+CST.
+    const MachineFrameInfo &MFI = *DAG.getMachineFunction().getFrameInfo();
+    if (MFI.isFixedObjectIndex(FrameIdx)) {
+      int64_t ObjectOffset = MFI.getObjectOffset(FrameIdx);
+
+      // The alignment of the frame index can be determined from its offset 
from
+      // the incoming frame position.  If the frame object is at offset 32 and
+      // the stack is guaranteed to be 16-byte aligned, then we know that the
+      // object is 16-byte aligned.
+      unsigned StackAlign = 
DAG.getTarget().getFrameInfo()->getStackAlignment();
+      unsigned Align = MinAlign(ObjectOffset, StackAlign);
+      
+      // Finally, the frame object itself may have a known alignment.  Factor
+      // the alignment + offset into a new alignment.  For example, if we know
+      // the  FI is 8 byte aligned, but the pointer is 4 off, we really have a
+      // 4-byte alignment of the resultant pointer.  Likewise align 4 + 4-byte
+      // offset = 4-byte alignment, align 4 + 1-byte offset = align 1, etc.
+      unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx), 
+                                      FrameOffset);
+      return std::max(Align, FIInfoAlign);
+    }
   }
   
-  // FIXME: Handle FI+CST.
-  
   return 0;
 }
 

Added: llvm/trunk/test/CodeGen/X86/stack-align.ll
URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-align.ll?rev=46401&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/stack-align.ll (added)
+++ llvm/trunk/test/CodeGen/X86/stack-align.ll Sat Jan 26 13:45:50 2008
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep 
{andpd.*4(%esp), %xmm}
+
+; The double argument is at 4(esp) which is 16-byte aligned, allowing us to
+; fold the load into the andpd.
+
+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:128:128"
+target triple = "i686-apple-darwin8"
[EMAIL PROTECTED] = external global double
+
+define void @test({ double, double }* byval  %z, double* %P) {
+entry:
+       %tmp = getelementptr { double, double }* %z, i32 0, i32 0               
; <double*> [#uses=1]
+       %tmp1 = load double* %tmp, align 8              ; <double> [#uses=1]
+       %tmp2 = tail call double @fabs( double %tmp1 )          ; <double> 
[#uses=1]
+       %tmp3 = load double* @G, align 16               ; <double> [#uses=1]
+       %tmp4 = tail call double @fabs( double %tmp3 )          ; <double> 
[#uses=1]
+       %tmp6 = add double %tmp4, %tmp2         ; <double> [#uses=1]
+       store double %tmp6, double* %P, align 8
+       ret void
+}
+
+declare double @fabs(double)


_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to