From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 94862 invoked by alias); 3 Jul 2015 15:26:10 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 94852 invoked by uid 89); 3 Jul 2015 15:26:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,KAM_LOTSOFHASH,SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 03 Jul 2015 15:26:08 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-29-5l8YK4RaRQWQm2kL5uM5XQ-1 Received: from [10.2.207.65] ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 3 Jul 2015 16:26:01 +0100 Message-ID: <5596A98A.7080500@arm.com> Date: Fri, 03 Jul 2015 15:26:00 -0000 From: Alan Lawrence User-Agent: Thunderbird 2.0.0.24 (X11/20101213) MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" Subject: [PATCH 1/2][ARM] PR/65956 AAPCS update for alignment attribute In-Reply-To: <5596A928.4080108@arm.com> X-MC-Unique: 5l8YK4RaRQWQm2kL5uM5XQ-1 Content-Type: multipart/mixed; boundary="------------040304020707070701080400" X-IsSubscribed: yes X-SW-Source: 2015-07/txt/msg00215.txt.bz2 This is a multi-part message in MIME format. --------------040304020707070701080400 Content-Type: text/plain; charset=WINDOWS-1252; format=flowed Content-Transfer-Encoding: quoted-printable Content-length: 1215 These include tests of structs, scalars, and vectors - only general-purpose= =20 registers are affected by the ABI rules for alignment, but we can restrict = the=20 vector test to use the base AAPCS. Prior to this patch, align2.c, align3.c and align_rec1.c were failing (the= =20 latter showing an internal inconsistency, the first two merely that GCC did= not=20 obey the new ABI). With this patch, the align_rec2.c fails, and also=20 gcc.c-torture/execute/20040709-1.c at -O0 only, both because of a latent bu= g=20 where we can emit strd/ldrd on an odd-numbered register in ARM state, fixed= by=20 the second patch. gcc/ChangeLog: * config/arm/arm.c (arm_needs_doubleword_align): Drop any outer alignment attribute, exploring one level down for aggregates. gcc/testsuite/ChangeLog: * gcc.target/arm/aapcs/align1.c: New. * gcc.target/arm/aapcs/align_rec1.c: New. * gcc.target/arm/aapcs/align2.c: New. * gcc.target/arm/aapcs/align_rec2.c: New. * gcc.target/arm/aapcs/align3.c: New. * gcc.target/arm/aapcs/align_rec3.c: New. * gcc.target/arm/aapcs/align4.c: New. * gcc.target/arm/aapcs/align_rec4.c: New. * gcc.target/arm/aapcs/align_vararg1.c: New. * gcc.target/arm/aapcs/align_vararg2.c: New. --------------040304020707070701080400 Content-Type: text/x-patch; name=arm_overalign_1.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="arm_overalign_1.patch" Content-length: 12084 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 04663999224c8c8eb8e2d10b0ec634db6ce5027e..ee57d30617a2f7e1cd63ca013fe= 5655a01027581 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6020,8 +6020,17 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tre= e fntype, static bool arm_needs_doubleword_align (machine_mode mode, const_tree type) { - return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY - || (type && TYPE_ALIGN (type) > PARM_BOUNDARY)); + if (!type) + return PARM_BOUNDARY < GET_MODE_ALIGNMENT (mode); + + if (!AGGREGATE_TYPE_P (type)) + return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) > PARM_BOUNDARY; + + for (tree field =3D TYPE_FIELDS (type); field; field =3D DECL_CHAIN (fie= ld)) + if (DECL_ALIGN (field) > PARM_BOUNDARY) + return true; + + return false; } =20 =20 diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align1.c b/gcc/testsuite/gc= c.target/arm/aapcs/align1.c new file mode 100644 index 0000000000000000000000000000000000000000..8981d57c3eaf0bd89d224bec79f= f8a45627a0a89 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align1.c @@ -0,0 +1,29 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "align1.c" + +typedef __attribute__((aligned (8))) int alignedint; + +alignedint a =3D 11; +alignedint b =3D 13; +alignedint c =3D 17; +alignedint d =3D 19; +alignedint e =3D 23; +alignedint f =3D 29; + +#include "abitest.h" +#else + ARG (alignedint, a, R0) + /* Attribute suggests R2, but we should use only natural alignment: */ + ARG (alignedint, b, R1) + ARG (alignedint, c, R2) + ARG (alignedint, d, R3) + ARG (alignedint, e, STACK) + /* Attribute would suggest STACK + 8 but should be ignored: */ + LAST_ARG (alignedint, f, STACK + 4) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align2.c b/gcc/testsuite/gc= c.target/arm/aapcs/align2.c new file mode 100644 index 0000000000000000000000000000000000000000..992da53c606c793f25278152406= 582bb993719d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align2.c @@ -0,0 +1,30 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "align2.c" + +/* The underlying struct here has alignment 4. */ +typedef struct __attribute__((aligned (8))) + { + int x; + int y; + } overaligned; + +/* A couple of instances, at 8-byte-aligned memory locations. */ +overaligned a =3D { 2, 3 }; +overaligned b =3D { 5, 8 }; + +#include "abitest.h" +#else + ARG (int, 7, R0) + /* Alignment should be 4. */ + ARG (overaligned, a, R1) + ARG (int, 9, R3) + ARG (int, 10, STACK) + /* Alignment should be 4. */ + LAST_ARG (overaligned, b, STACK + 4) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align3.c b/gcc/testsuite/gc= c.target/arm/aapcs/align3.c new file mode 100644 index 0000000000000000000000000000000000000000..81ad3f587a95aae52ec601ce5a6= 0b198e5351edf --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align3.c @@ -0,0 +1,42 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O3" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "align3.c" + +/* Struct will be aligned to 8. */ +struct s + { + int x; + /* 4 bytes padding here. */ + __attribute__((aligned (8))) int y; + /* 4 bytes padding here. */ + }; + +typedef struct s __attribute__((aligned (4))) underaligned; + +#define EXPECTED_STRUCT_SIZE 16 +extern void link_failure (void); +int +foo () +{ + /* Optimization gets rid of this before linking. */ + if (sizeof (struct s) !=3D EXPECTED_STRUCT_SIZE) + link_failure (); +} + +underaligned a =3D { 1, 4 }; +underaligned b =3D { 9, 16 }; + +#include "abitest.h" +#else + ARG (int, 3, R0) + /* Object alignment is 8, so split between 2 regs and 8 on stack. */ + ARG (underaligned, a, R2) + ARG (int, 6, STACK + 8) + /* Object alignment is 8, so skip over STACK + 12. */ + LAST_ARG (underaligned, b, STACK + 16) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align4.c b/gcc/testsuite/gc= c.target/arm/aapcs/align4.c new file mode 100644 index 0000000000000000000000000000000000000000..5535c55b8ac895ea31e468fd547= 4a71c232d2fea --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align4.c @@ -0,0 +1,29 @@ +/* Test AAPCS layout (alignment) - passing vectors in GPRs. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O" } */ +/* { dg-add-options arm_neon } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "align4.c" + +#define PCSATTR __attribute__((pcs("aapcs"))) + +#include + +typedef __attribute__((aligned (4))) int32x2_t unalignedvec; + +unalignedvec a =3D {11, 13}; +unalignedvec b =3D {17, 19}; + +#include "abitest.h" +#else + ARG (int, 2, R0) + /* Attribute suggests R1, but we should use natural alignment: */ + ARG (unalignedvec, a, R2) + ARG (int, 6, STACK) + /* Attribute would suggest STACK + 4 but should be ignored: */ + LAST_ARG (unalignedvec, b, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_rec1.c b/gcc/testsuit= e/gcc.target/arm/aapcs/align_rec1.c new file mode 100644 index 0000000000000000000000000000000000000000..2e42baefb5877f28b763cc302fd= 4ef728fb3f72c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_rec1.c @@ -0,0 +1,36 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2 -fno-inline" } */ + +extern void abort (void); + +typedef __attribute__((aligned (8))) int alignedint; + +alignedint a =3D 11; +alignedint b =3D 13; +alignedint c =3D 17; +alignedint d =3D 19; +alignedint e =3D 23; +alignedint f =3D 29; + +void +foo (alignedint r0, alignedint r1, alignedint r2, alignedint r3, + alignedint stack, alignedint stack4) +{ + if (r0 !=3D a + || r1 !=3D b + || r2 !=3D c + || r3 !=3D d + || stack !=3D e + || stack4 !=3Df) + abort (); +} + +int +main (int argc, char **argv) +{ + foo (a, b, c, d, e, f); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_rec2.c b/gcc/testsuit= e/gcc.target/arm/aapcs/align_rec2.c new file mode 100644 index 0000000000000000000000000000000000000000..a00da508443f6c350dac610851d= 111d0685f2853 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_rec2.c @@ -0,0 +1,41 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2 -fno-inline" } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +typedef struct __attribute__((aligned (8))) + { + int x; + int y; + } overaligned; + +overaligned a =3D { 2, 3 }; +overaligned b =3D { 5, 8 }; + +void +f (int r0, overaligned r1, int r3, int stack, overaligned stack4) +{ + if (r0 !=3D 7 || r3 !=3D 9 || stack !=3D 10) + abort (); + if (memcmp ((void *) &r1, (void *)&a, sizeof (overaligned))) + abort (); + if (memcmp ((void *)&stack4, (void *)&b, sizeof (overaligned))) + abort (); + int addr =3D ((int) &stack4) & 7; + if (addr !=3D 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + f (7, a, 9, 10, b); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_rec3.c b/gcc/testsuit= e/gcc.target/arm/aapcs/align_rec3.c new file mode 100644 index 0000000000000000000000000000000000000000..2184cb76a6a7f68c59b39c12ec6= 472ac7b561794 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_rec3.c @@ -0,0 +1,43 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2 -fno-inline" } */ + +/* Test AAPCS layout (alignment) for callee. */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + + +/* Struct will be aligned to 8. */ +struct s + { + int x; + /* 4 bytes padding here. */ + __attribute__((aligned (8))) int y; + /* 4 bytes padding here. */ + }; + +typedef struct s __attribute__((aligned (4))) underaligned; + +underaligned a =3D { 1, 4 }; +underaligned b =3D { 9, 16 }; + +void +f (int r0, underaligned r2, int stack8, underaligned stack16) +{ + if (r0 !=3D 3 || stack8 !=3D 6) + abort (); + if (memcmp ((void *) &r2, (void *)&a, sizeof (underaligned))) + abort (); + if (memcmp ((void *)&stack16, (void *)&b, sizeof (underaligned))) + abort (); +} + +int +main (int argc, char **argv) +{ + f (3, a, 6, b); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_rec4.c b/gcc/testsuit= e/gcc.target/arm/aapcs/align_rec4.c new file mode 100644 index 0000000000000000000000000000000000000000..907b90af70f7ce2ded456d08d64= 71462e64fa15c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_rec4.c @@ -0,0 +1,33 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O -fno-inline" } */ +/* { dg-add-options arm_neon } */ + +#include + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +typedef __attribute__((aligned (4))) int32x4_t unalignedvec; + +unalignedvec a =3D {11, 13}; +unalignedvec b =3D {17, 19}; + +void +foo (int r0, unalignedvec r2, int s0, unalignedvec s8) +{ + if (r0 !=3D 2 || s0 !=3D 6 + || memcmp ( (void *) &r2, (void *) &a, 16) + || memcmp ( (void *) &s8, (void *) &b, 16)) + abort (); +} + +int +main (int argc, char **argv) +{ + foo (2, a, 6, b); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_vaarg_1.c b/gcc/tests= uite/gcc.target/arm/aapcs/align_vaarg_1.c new file mode 100644 index 0000000000000000000000000000000000000000..daa321415998df658814d853a15= 284ae2125cb1e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_vaarg_1.c @@ -0,0 +1,36 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2 -fno-inline" } */ + +#include + +extern void abort (void); + +typedef __attribute__((aligned (8))) int alignedint; + +void +foo (int i, ...) +{ + va_list va; + va_start (va, i); + /* Arguments should be passed in the same registers as if they were ints= . */ + while (i-- > 0) + if (va_arg (va, int) !=3D i) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + alignedint a =3D 5; + alignedint b =3D 4; + alignedint c =3D 3; + alignedint d =3D 2; + alignedint e =3D 1; + alignedint f =3D 0; + foo (a, b, c, d, e, f); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/aapcs/align_vaarg_2.c b/gcc/tests= uite/gcc.target/arm/aapcs/align_vaarg_2.c new file mode 100644 index 0000000000000000000000000000000000000000..b0c923b97edbdf7ee75ce0d2ad8= 68a16f49485fd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/align_vaarg_2.c @@ -0,0 +1,30 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2 -fno-inline" } */ + +#include + +extern void abort (void); + +typedef __attribute__((aligned (8))) int alignedint; + +void +foo (int i, ...) +{ + va_list va; + va_start (va, i); + /* alignedint should be pulled out of regs/stack just like an int. */ + while (i-- > 0) + if (va_arg (va, alignedint) !=3D i) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + foo (5, 4, 3, 2, 1, 0); + return 0; +} --------------040304020707070701080400--