summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/CallingConvLower.cpp
diff options
context:
space:
mode:
authorJeroen Ketema <j.ketema@imperial.ac.uk>2015-09-29 10:12:57 +0000
committerJeroen Ketema <j.ketema@imperial.ac.uk>2015-09-29 10:12:57 +0000
commit740f9d79ca7ea90b4836424f841462e286a46f43 (patch)
tree9636eb17d2122168f5369ec875a39add5c5077bf /llvm/lib/CodeGen/CallingConvLower.cpp
parent26fd0e8b6294e81a983eba9efb06b765e06e3a4e (diff)
downloadbcm5719-llvm-740f9d79ca7ea90b4836424f841462e286a46f43.tar.gz
bcm5719-llvm-740f9d79ca7ea90b4836424f841462e286a46f43.zip
Arguments spilled on the stack before a function call may have
alignment requirements, for example in the case of vectors. These requirements are exploited by the code generator by using move instructions that have similar alignment requirements, e.g., movaps on x86. Although the code generator properly aligns the arguments with respect to the displacement of the stack pointer it computes, the displacement itself may cause misalignment. For example if we have %3 = load <16 x float>, <16 x float>* %1, align 64 call void @bar(<16 x float> %3, i32 0) the x86 back-end emits: movaps 32(%ecx), %xmm2 movaps (%ecx), %xmm0 movaps 16(%ecx), %xmm1 movaps 48(%ecx), %xmm3 subl $20, %esp <-- if %esp was 16-byte aligned before this instruction, it no longer will be afterwards movaps %xmm3, (%esp) <-- movaps requires 16-byte alignment, while %esp is not aligned as such. movl $0, 16(%esp) calll __bar To solve this, we need to make sure that the computed value with which the stack pointer is changed is a multiple af the maximal alignment seen during its computation. With this change we get proper alignment: subl $32, %esp movaps %xmm3, (%esp) Differential Revision: http://reviews.llvm.org/D12337 llvm-svn: 248786
Diffstat (limited to 'llvm/lib/CodeGen/CallingConvLower.cpp')
-rw-r--r--llvm/lib/CodeGen/CallingConvLower.cpp3
1 files changed, 3 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp
index fb29b1db7a4..23c0d542560 100644
--- a/llvm/lib/CodeGen/CallingConvLower.cpp
+++ b/llvm/lib/CodeGen/CallingConvLower.cpp
@@ -32,6 +32,7 @@ CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
CallOrPrologue(Unknown) {
// No stack is used.
StackOffset = 0;
+ MaxStackArgAlign = 1;
clearByValRegsInfo();
UsedRegs.resize((TRI.getNumRegs()+31)/32);
@@ -192,6 +193,7 @@ static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) {
void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
MVT VT, CCAssignFn Fn) {
unsigned SavedStackOffset = StackOffset;
+ unsigned SavedMaxStackArgAlign = MaxStackArgAlign;
unsigned NumLocs = Locs.size();
// Set the 'inreg' flag if it is used for this calling convention.
@@ -223,6 +225,7 @@ void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
// as allocated so that future queries don't return the same registers, i.e.
// when i64 and f64 are both passed in GPRs.
StackOffset = SavedStackOffset;
+ MaxStackArgAlign = SavedMaxStackArgAlign;
Locs.resize(NumLocs);
}
OpenPOWER on IntegriCloud