Hi, This patch (diff-abi-compat) backports the ABI compatibility fix for PR57949.
Thanks, Bill [gcc] 2014-03-29 Bill Schmidt <wschm...@linux.vnet.ibm.com> Backport from mainline r201750. 2013-11-15 Ulrich Weigand <ulrich.weig...@de.ibm.com> Note: Default setting of -mcompat-align-parm inverted! 2013-08-14 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR target/57949 * doc/invoke.texi: Add documentation of mcompat-align-parm option. * config/rs6000/rs6000.opt: Add mcompat-align-parm option. * config/rs6000/rs6000.c (rs6000_function_arg_boundary): For AIX and Linux, correct BLKmode alignment when 128-bit alignment is required and compatibility flag is not set. (rs6000_gimplify_va_arg): For AIX and Linux, honor specified alignment for zero-size arguments when compatibility flag is not set. [gcc/testsuite] 2014-03-29 Bill Schmidt <wschm...@linux.vnet.ibm.com> Backport from mainline r201750. 2013-11-15 Ulrich Weigand <ulrich.weig...@de.ibm.com> Note: Default setting of -mcompat-align-parm inverted! 2013-08-14 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR target/57949 * gcc.target/powerpc/pr57949-1.c: New. * gcc.target/powerpc/pr57949-2.c: New. Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c =================================================================== --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c +++ gcc-4_8-test/gcc/config/rs6000/rs6000.c @@ -8680,8 +8680,8 @@ rs6000_function_arg_boundary (enum machi || (type && TREE_CODE (type) == VECTOR_TYPE && int_size_in_bytes (type) >= 16)) return 128; - else if (TARGET_MACHO - && rs6000_darwin64_abi + else if (((TARGET_MACHO && rs6000_darwin64_abi) + || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)) && mode == BLKmode && type && TYPE_ALIGN (type) > 64) return 128; @@ -10233,8 +10233,9 @@ rs6000_gimplify_va_arg (tree valist, tre We don't need to check for pass-by-reference because of the test above. We can return a simplifed answer, since we know there's no offset to add. */ - if (TARGET_MACHO - && rs6000_darwin64_abi + if (((TARGET_MACHO + && rs6000_darwin64_abi) + || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)) && integer_zerop (TYPE_SIZE (type))) { unsigned HOST_WIDE_INT align, boundary; Index: gcc-4_8-test/gcc/config/rs6000/rs6000.opt =================================================================== --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.opt +++ gcc-4_8-test/gcc/config/rs6000/rs6000.opt @@ -550,6 +550,10 @@ mquad-memory Target Report Mask(QUAD_MEMORY) Var(rs6000_isa_flags) Generate the quad word memory instructions (lq/stq/lqarx/stqcx). +mcompat-align-parm +Target Report Var(rs6000_compat_align_parm) Init(1) Save +Generate aggregate parameter passing code with at most 64-bit alignment. + mupper-regs-df Target Undocumented Mask(UPPER_REGS_DF) Var(rs6000_isa_flags) Allow double variables in upper registers with -mcpu=power7 or -mvsx Index: gcc-4_8-test/gcc/doc/invoke.texi =================================================================== --- gcc-4_8-test.orig/gcc/doc/invoke.texi +++ gcc-4_8-test/gcc/doc/invoke.texi @@ -17243,7 +17243,8 @@ following options: -mpopcntb -mpopcntd -mpowerpc64 @gol -mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol -msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr -mvsx @gol --mcrypto -mdirect-move -mpower8-fusion -mpower8-vector -mquad-memory} +-mcrypto -mdirect-move -mpower8-fusion -mpower8-vector -mquad-memory @gol +-mcompat-align-parm -mno-compat-align-parm} The particular options set for any particular CPU varies between compiler versions, depending on what setting seems to produce optimal @@ -18128,6 +18129,23 @@ stack location in the function prologue a pointer on AIX and 64-bit Linux systems. If the TOC value is not saved in the prologue, it is saved just before the call through the pointer. The @option{-mno-save-toc-indirect} option is the default. + +@item -mcompat-align-parm +@itemx -mno-compat-align-parm +@opindex mcompat-align-parm +Generate (do not generate) code to pass structure parameters with a +maximum alignment of 64 bits, for compatibility with older versions +of GCC. + +Older versions of GCC (prior to 4.9.0) incorrectly did not align a +structure parameter on a 128-bit boundary when that structure contained +a member requiring 128-bit alignment. This is corrected in more +recent versions of GCC. This option may be used to generate code +that is compatible with functions compiled with older versions of +GCC. + +In this version of the compiler, the @option{-mcompat-align-parm} +is the default, except when using the Linux ELFv2 ABI. @end table @node RX Options Index: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/pr57949-1.c =================================================================== --- /dev/null +++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/pr57949-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcpu=power7 -mno-compat-align-parm" } */ + +/* Verify that vs is 16-byte aligned with -mcompat-align-parm. */ + +typedef float v4sf __attribute__ ((vector_size (16))); +struct s { long m; v4sf v; }; +long n; +v4sf ve; + +void pr57949 (long d1, long d2, long d3, long d4, long d5, long d6, + long d7, long d8, long d9, struct s vs) { + n = vs.m; + ve = vs.v; +} + +/* { dg-final { scan-assembler "li \.\*,144" } } */ +/* { dg-final { scan-assembler "ld \.\*,128\\(1\\)" } } */ Index: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/pr57949-2.c =================================================================== --- /dev/null +++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/pr57949-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcpu=power7" } */ + +/* Verify that vs is not 16-byte aligned in the absence of -mno-compat-align-parm. */ + +typedef float v4sf __attribute__ ((vector_size (16))); +struct s { long m; v4sf v; }; +long n; +v4sf ve; + +void pr57949 (long d1, long d2, long d3, long d4, long d5, long d6, + long d7, long d8, long d9, struct s vs) { + n = vs.m; + ve = vs.v; +} + +/* { dg-final { scan-assembler "ld .\*,136\\(1\\)" } } */ +/* { dg-final { scan-assembler "ld .\*,120\\(1\\)" } } */