From 968823946949925bcc68163bed41b6a1da90a677 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 6 Aug 2014 17:57:23 +0000 Subject: [PATCH] Round up the size of byval arguments to MinAlign Otherwise we can end up with an argument frame size that is not a multiple of stack slot size, which is very awkward. This fixes PR20547, which was a bug in x86_64 Sys V vararg handling. However, it's much easier to test this with x86 callee-cleanup functions, which previously ended in "retl $6" instead of "retl $8". This does affect behavior of all backends, but it presumably fixes the same bug in all of them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214980 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CallingConvLower.cpp | 1 + test/CodeGen/X86/byval-callee-cleanup.ll | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 test/CodeGen/X86/byval-callee-cleanup.ll diff --git a/lib/CodeGen/CallingConvLower.cpp b/lib/CodeGen/CallingConvLower.cpp index 50fc6a179b6..cfcc9eae14e 100644 --- a/lib/CodeGen/CallingConvLower.cpp +++ b/lib/CodeGen/CallingConvLower.cpp @@ -52,6 +52,7 @@ void CCState::HandleByVal(unsigned ValNo, MVT ValVT, Align = MinAlign; MF.getFrameInfo()->ensureMaxAlignment(Align); TM.getSubtargetImpl()->getTargetLowering()->HandleByVal(this, Size, Align); + Size = unsigned(RoundUpToAlignment(Size, MinAlign)); unsigned Offset = AllocateStack(Size, Align); addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); } diff --git a/test/CodeGen/X86/byval-callee-cleanup.ll b/test/CodeGen/X86/byval-callee-cleanup.ll new file mode 100644 index 00000000000..61e2369a404 --- /dev/null +++ b/test/CodeGen/X86/byval-callee-cleanup.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=x86 | FileCheck %s + +; Previously we would forget to align to stack slot alignment after placing a +; byval argument. Subsequent arguments would align themselves, but if it was +; the last argument, the argument size would not be a multiple of stack slot +; size. This resulted in retl $6 in callee-cleanup functions, as well as subtle +; varargs bugs. + +%struct.Six = type { [6 x i8] } + +define x86_stdcallcc void @f(%struct.Six* byval %a) { + ret void +} +; CHECK-LABEL: _f@8: +; CHECK: retl $8 + +define x86_thiscallcc void @g(i8* %this, %struct.Six* byval %a) { + ret void +} +; CHECK-LABEL: _g: +; CHECK: retl $8 + +define x86_fastcallcc void @h(i32 inreg %x, i32 inreg %y, %struct.Six* byval %a) { + ret void +} +; FIXME: This should be @h@8. +; CHECK-LABEL: @h@16: +; CHECK: retl $8 -- 2.11.0