Arguments spilled on the stack before a function call may have
authorJeroen Ketema <j.ketema@imperial.ac.uk>
Tue, 29 Sep 2015 10:12:57 +0000 (10:12 +0000)
committerJeroen Ketema <j.ketema@imperial.ac.uk>
Tue, 29 Sep 2015 10:12:57 +0000 (10:12 +0000)
commitf5f9e9a3bfa0c7142b7be5027355ffa819b94ac6
treef5105f80aed04db922c58079114ed826be0fc912
parente6204cf2f1990eb90e727e003e687ef5b84c8a75
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248786 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/CodeGen/CallingConvLower.h
lib/CodeGen/CallingConvLower.cpp
lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/win32-spill-xmm.ll [new file with mode: 0644]