This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]