This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: PR target/46195: r165965 regresses i386 darwin
On Fri, Oct 29, 2010 at 04:55:57AM -0700, H.J. Lu wrote:
>
> We have to check mode since type may be NULL. Long double
> is a very special case for 32bit psABI where normal alignment of a
> type/mode != its alignment when passed on stack. So we have
> to check when normal alignment is 128 with the alignment of mode/type
> is determined by long double.
>
> Here is the updated patch I changed the new function name to
> function_arg_128bit_aligned_32_p.
>
H.J.,
I can confirm that this new version eliminates the regressions on
x86_64-apple-darwin10 as well.
Jack
>
> --
> H.J.
> ---
> 2010-10-29 H.J. Lu <hongjiu.lu@intel.com>
>
> PR target/46195
> * config/i386/i386.c (function_arg_128bit_aligned_32_p): New.
> (ix86_function_arg_boundary): Align long double parameters on
> stack to 4byte in 32bit.
> 2010-10-29 H.J. Lu <hongjiu.lu@intel.com>
>
> PR target/46195
> * config/i386/i386.c (function_arg_128bit_aligned_32_p): New.
> (ix86_function_arg_boundary): Align long double parameters on
> stack to 4byte in 32bit.
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index f2bd705..d6bfd8e 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -7032,6 +7032,59 @@ ix86_old_function_arg_boundary (enum machine_mode mode, const_tree type,
> return align;
> }
>
> +/* Return true when aggregate TYPE should be aligned at 128bit for
> + 32bit argument passing ABI. */
> +
> +static bool
> +function_arg_128bit_aligned_32_p (const_tree type)
> +{
> + enum machine_mode mode = TYPE_MODE (type);
> +
> + if (mode == XFmode || mode == XCmode)
> + return false;
> +
> + if (TYPE_ALIGN (type) < 128)
> + return false;
> +
> + if (!AGGREGATE_TYPE_P (type))
> + return TYPE_ALIGN (type) >= 128;
> + else
> + {
> + /* Walk the aggregates recursively. */
> + switch (TREE_CODE (type))
> + {
> + case RECORD_TYPE:
> + case UNION_TYPE:
> + case QUAL_UNION_TYPE:
> + {
> + tree field;
> +
> + /* Walk all the structure fields. */
> + for (field = TYPE_FIELDS (type);
> + field;
> + field = DECL_CHAIN (field))
> + {
> + if (TREE_CODE (field) == FIELD_DECL
> + && function_arg_128bit_aligned_32_p (TREE_TYPE (field)))
> + return true;
> + }
> + break;
> + }
> +
> + case ARRAY_TYPE:
> + /* Just for use if some languages passes arrays by value. */
> + if (function_arg_128bit_aligned_32_p (TREE_TYPE (type)))
> + return true;
> + break;
> +
> + default:
> + gcc_unreachable ();
> + }
> + }
> +
> + return false;
> +}
> +
> /* Gives the alignment boundary, in bits, of an argument with the
> specified mode and type. */
>
> @@ -7055,7 +7108,18 @@ ix86_function_arg_boundary (enum machine_mode mode, const_tree type)
> static bool warned;
> int saved_align = align;
>
> - if (!TARGET_64BIT && align < 128)
> + /* i386 ABI defines all arguments to be 4 byte aligned. Even if
> + long double is aligned to 16 byte, we always align it at 4
> + byte, whether it is a scalar or the part of aggregate, when
> + passed as function argument. */
> + if (!TARGET_64BIT
> + && (align < 128
> + || (align == 128
> + && (mode == XFmode
> + || mode == XCmode
> + || (type
> + && AGGREGATE_TYPE_P (type)
> + && !function_arg_128bit_aligned_32_p (type))))))
> align = PARM_BOUNDARY;
>
> if (warn_psabi