<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Mar 4, 2014 at 3:36 AM, Oliver Stannard <span dir="ltr"><<a href="mailto:oliver.stannard@arm.com" target="_blank">oliver.stannard@arm.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi rengolin,<br>
<br>
This patch fixes a bug that would cause an 8-byte-aligned function argument<br>
to be consistently misaligned in some situations involving byval arguments.<br>
The following function signature is one of these cases:<br>
<br>
%struct12bytes = type { i32, i32, i32 }<br>
define void @foo(i32 %a, %struct12bytes* byval %b, i64 %c) {<br>
<br>
When arguments are initially been allocated, %b has 12 bytes reserved on the<br>
stack, but this is later adjusted to use registers r1..r3 instead of the<br>
stack. However, the 12 bytes are still used when calculating the alignment<br>
of %c, causing %c to be allocated 4 bytes above the top of %b, at stack<br>
offset 0x10. The stack pointer is moved down 12 bytes at the beginning of<br>
the function  to make space for the part of %b which is in registers (all of<br>
it in this example), plus another 4 bytes to maintain 8-byte SP alignment.<br>
However, the 4 bytes of alignment gap between %b and %c are still present,<br>
resulting in %c being loaded from SP+0x14, which is not 8-byte aligned.<br>
<br>
The solution to this is to not allocate stack space for the part of a byval<br>
which will be passed in registers.</blockquote><div><br></div><div>Maybe I didn't get the whole picture, but I think we need to allocate stack space  for</div><div>the part of a byval that will be passed in registers, so the part passed in registers</div>
<div>and the part passed on stack will be laid out contiguously on stack.</div><div><br></div><div>Thanks,</div><div>Manman</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 This requires some extra work to<br>
calculate the location of byval arguments on the stack, especially in the<br>
case of multiple small byvals in registers, as previously the stack<br>
locations were used to record the location of a byval after storing to the<br>
stack.<br>
<br>
This bug can be triggered from C, using a similar test case, but argument b<br>
must be larger than 64 bytes to cause clang to emit a byval argument.<br>
<br>
I have put this patch through a night of random PCS testing with no failures.<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D2933" target="_blank">http://llvm-reviews.chandlerc.com/D2933</a><br>
<br>
Files:<br>
  include/llvm/CodeGen/CallingConvLower.h<br>
  lib/Target/ARM/ARMFrameLowering.cpp<br>
  lib/Target/ARM/ARMISelLowering.cpp<br>
  lib/Target/ARM/ARMISelLowering.h<br>
  lib/Target/ARM/Thumb1FrameLowering.cpp<br>
  test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll<br>
  test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll<br>
  test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll<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>
<br></blockquote></div><br></div></div>