llvm.org GIT mirror llvm / 1329cb8
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46401 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 12 years ago
2 changed file(s) with 56 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
1717 #include "llvm/CodeGen/MachineFrameInfo.h"
1818 #include "llvm/Analysis/AliasAnalysis.h"
1919 #include "llvm/Target/TargetData.h"
20 #include "llvm/Target/TargetFrameInfo.h"
2021 #include "llvm/Target/TargetLowering.h"
2122 #include "llvm/Target/TargetMachine.h"
2223 #include "llvm/Target/TargetOptions.h"
40724073 static unsigned InferAlignment(SDOperand Ptr, SelectionDAG &DAG) {
40734074 // If this is a direct reference to a stack slot, use information about the
40744075 // stack slot's alignment.
4076 int FrameIdx = 1 << 31;
4077 int64_t FrameOffset = 0;
40754078 if (FrameIndexSDNode *FI = dyn_cast(Ptr)) {
4076 return DAG.getMachineFunction().getFrameInfo()->
4077 getObjectAlignment(FI->getIndex());
4078 }
4079
4080 // FIXME: Handle FI+CST.
4079 FrameIdx = FI->getIndex();
4080 } else if (Ptr.getOpcode() == ISD::ADD &&
4081 isa(Ptr.getOperand(1)) &&
4082 isa(Ptr.getOperand(0))) {
4083 FrameIdx = cast(Ptr.getOperand(0))->getIndex();
4084 FrameOffset = Ptr.getConstantOperandVal(1);
4085 }
4086
4087 if (FrameIdx != (1 << 31)) {
4088 // FIXME: Handle FI+CST.
4089 const MachineFrameInfo &MFI = *DAG.getMachineFunction().getFrameInfo();
4090 if (MFI.isFixedObjectIndex(FrameIdx)) {
4091 int64_t ObjectOffset = MFI.getObjectOffset(FrameIdx);
4092
4093 // The alignment of the frame index can be determined from its offset from
4094 // the incoming frame position. If the frame object is at offset 32 and
4095 // the stack is guaranteed to be 16-byte aligned, then we know that the
4096 // object is 16-byte aligned.
4097 unsigned StackAlign = DAG.getTarget().getFrameInfo()->getStackAlignment();
4098 unsigned Align = MinAlign(ObjectOffset, StackAlign);
4099
4100 // Finally, the frame object itself may have a known alignment. Factor
4101 // the alignment + offset into a new alignment. For example, if we know
4102 // the FI is 8 byte aligned, but the pointer is 4 off, we really have a
4103 // 4-byte alignment of the resultant pointer. Likewise align 4 + 4-byte
4104 // offset = 4-byte alignment, align 4 + 1-byte offset = align 1, etc.
4105 unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx),
4106 FrameOffset);
4107 return std::max(Align, FIInfoAlign);
4108 }
4109 }
40814110
40824111 return 0;
40834112 }
0 ; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep {andpd.*4(%esp), %xmm}
1
2 ; The double argument is at 4(esp) which is 16-byte aligned, allowing us to
3 ; fold the load into the andpd.
4
5 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"
6 target triple = "i686-apple-darwin8"
7 @G = external global double
8
9 define void @test({ double, double }* byval %z, double* %P) {
10 entry:
11 %tmp = getelementptr { double, double }* %z, i32 0, i32 0 ; [#uses=1]
12 %tmp1 = load double* %tmp, align 8 ; [#uses=1]
13 %tmp2 = tail call double @fabs( double %tmp1 ) ; [#uses=1]
14 %tmp3 = load double* @G, align 16 ; [#uses=1]
15 %tmp4 = tail call double @fabs( double %tmp3 ) ; [#uses=1]
16 %tmp6 = add double %tmp4, %tmp2 ; [#uses=1]
17 store double %tmp6, double* %P, align 8
18 ret void
19 }
20
21 declare double @fabs(double)