From: Daniel Dunbar Date: Fri, 22 May 2009 17:33:44 +0000 (+0000) Subject: x86_64 ABI: Account for sret parameters consuming an integer register. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a5f5c57e0a262207f7cb721a60df3676ab5209f;p=clang x86_64 ABI: Account for sret parameters consuming an integer register. - PR4242. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72268 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 356caa3f90..ce98f8c256 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1055,6 +1055,11 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context) const { // Keep track of the number of assigned registers. unsigned freeIntRegs = 6, freeSSERegs = 8; + + // If the return value is indirect, then the hidden argument is consuming one + // integer register. + if (FI.getReturnInfo().isIndirect()) + --freeIntRegs; // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers // get assigned (in left-to-right order) for passing as follows... diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index b28e064d35..3b4f5ff68f 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -61,4 +61,12 @@ struct s12 { int a __attribute__((aligned(16))); }; struct s12 f12_0(void) {} void f12_1(struct s12 a0) {} +// Check that sret parameter is accounted for when checking available integer +// registers. +// RUN: grep 'define void @f13(.struct.s13_0. noalias sret .agg.result, i32 .a, i32 .b, i32 .c, i32 .d, .struct.s13_1. byval .e, i32 .f)' %t && + +struct s13_0 { long long f0[3]; }; +struct s13_0 f13(int a, int b, int c, int d, + struct s13_1 { long long f0[2]; } e, int f) {} + // RUN: true