This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix small structure passing on x86-64
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 31 Oct 2008 11:46:58 +0100
- Subject: [PATCH] Fix small structure passing on x86-64
Hi,
the structure
struct S { char c; char arr[4]; float f; };
is incorrect passed on x86-64/Linux with every C compiler I tried: only the
first 4 bytes and the float are passed (in registers), the 5th byte is lost.
That's because the first word has partial integer class X86_64_INTEGERSI_CLASS
instead of full integer class X86_64_INTEGER_CLASS.
Tested on x86_64-suse-linux and compat-regtested against the system compiler,
OK for mainline?
2008-10-31 Eric Botcazou <ebotcazou@adacore.com>
* config/i386/i386.c (classify_argument) <ARRAY_TYPE>: Promote partial
integer class to full integer class if the offset is not word-aligned.
2008-10-31 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/execute/20081031.c: New test.
--
Eric Botcazou
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 141459)
+++ config/i386/i386.c (working copy)
@@ -4930,7 +4930,8 @@ classify_argument (enum machine_mode mod
/* The partial classes are now full classes. */
if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
subclasses[0] = X86_64_SSE_CLASS;
- if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
+ if (subclasses[0] == X86_64_INTEGERSI_CLASS
+ && !((bit_offset % 64) == 0 && bytes == 4))
subclasses[0] = X86_64_INTEGER_CLASS;
for (i = 0; i < words; i++)
struct S { char c; char arr[4]; float f; };
char A[4] = { '1', '2', '3', '4' };
void foo (struct S s)
{
if (__builtin_memcmp (s.arr, A, 4))
__builtin_abort ();
}
int main (void)
{
struct S s;
__builtin_memcpy (s.arr, A, 4);
foo (s);
return 0;
}