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: SSE fix 12 - argument alignment PR pending/8212


> On Mon, Oct 21, 2002 at 09:58:05PM +0200, Jan Hubicka wrote:
> > I am just testing the patch with second TYPE_USER_ALIGN changed to
> > TYPE_ALIGN and packed attribute in the testcase.
> > OK if it passes?
> 
> I'd like to see the test cases you tried.  We need to be
> _really_ careful that we don't break the C ABI here...
Hi,
I am attaching the updated patch.  It now seems to work in all case I
came up with.  I am attaching the testcase resutling in missaligned
movdqa

#include <xmmintrin.h>
struct a
{
  __m128 b __attribute__ ((aligned (8))) __attribute__ ((packed));
} aa;
test (int a, struct a b, int c);

q()
{
  test (1,aa,2);
}
Mon Oct 21 17:07:47 CEST 2002  Jan Hubicka  <jh@suse.cz>

	* i386.c (contains_128bit_aligned_vector_p): New function
	(ix86_function_arg_boundary): Properly align vector modes.

Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.478
diff -c -3 -p -r1.478 i386.c
*** config/i386/i386.c	20 Oct 2002 22:37:10 -0000	1.478
--- config/i386/i386.c	21 Oct 2002 21:21:34 -0000
*************** const struct attribute_spec ix86_attribu
*** 797,802 ****
--- 797,803 ----
  static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
  static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
  static int ix86_value_regno PARAMS ((enum machine_mode));
+ static bool contains_128bit_aligned_vector_p PARAMS ((tree));
  
  #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
  static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
*************** function_arg (cum, mode, type, named)
*** 2262,2267 ****
--- 2263,2326 ----
    return ret;
  }
  
+ /* Return true when TYPE should be 128bit aligned for 32bit argument passing
+    ABI  */
+ static bool
+ contains_128bit_aligned_vector_p (type)
+      tree type;
+ {
+   enum machine_mode mode = TYPE_MODE (type);
+   if (SSE_REG_MODE_P (mode)
+       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
+     return true;
+   if (TYPE_ALIGN (type) < 128)
+     return false;
+ 
+   if (AGGREGATE_TYPE_P (type))
+     {
+       /* Walk the agregates recursivly.  */
+       if (TREE_CODE (type) == RECORD_TYPE
+ 	  || TREE_CODE (type) == UNION_TYPE
+ 	  || TREE_CODE (type) == QUAL_UNION_TYPE)
+ 	{
+ 	  tree field;
+ 
+ 	  if (TYPE_BINFO (type) != NULL
+ 	      && TYPE_BINFO_BASETYPES (type) != NULL)
+ 	    {
+ 	      tree bases = TYPE_BINFO_BASETYPES (type);
+ 	      int n_bases = TREE_VEC_LENGTH (bases);
+ 	      int i;
+ 
+ 	      for (i = 0; i < n_bases; ++i)
+ 		{
+ 		  tree binfo = TREE_VEC_ELT (bases, i);
+ 		  tree type = BINFO_TYPE (binfo);
+ 
+ 		  if (contains_128bit_aligned_vector_p (type))
+ 		    return true;
+ 		}
+ 	    }
+ 	  /* And now merge the fields of structure.   */
+ 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ 	    {
+ 	      if (TREE_CODE (field) == FIELD_DECL
+ 		  && contains_128bit_aligned_vector_p (TREE_TYPE (field)))
+ 		return true;
+ 	    }
+ 	}
+       /* Just for use if some languages passes arrays by value.  */
+       else if (TREE_CODE (type) == ARRAY_TYPE)
+ 	{
+ 	  if (contains_128bit_aligned_vector_p (TREE_TYPE (type)))
+ 	    return true;
+ 	}
+       else
+ 	abort ();
+     }
+   return false;
+ }
+ 
  /* Gives the alignment boundary, in bits, of an argument with the specified mode
     and type.   */
  
*************** ix86_function_arg_boundary (mode, type)
*** 2271,2284 ****
       tree type;
  {
    int align;
-   if (!TARGET_64BIT)
-     return PARM_BOUNDARY;
    if (type)
      align = TYPE_ALIGN (type);
    else
      align = GET_MODE_ALIGNMENT (mode);
    if (align < PARM_BOUNDARY)
      align = PARM_BOUNDARY;
    if (align > 128)
      align = 128;
    return align;
--- 2330,2363 ----
       tree type;
  {
    int align;
    if (type)
      align = TYPE_ALIGN (type);
    else
      align = GET_MODE_ALIGNMENT (mode);
    if (align < PARM_BOUNDARY)
      align = PARM_BOUNDARY;
+   if (!TARGET_64BIT)
+     {
+       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
+ 	 make an exception for SSE modes since these require 128bit
+ 	 alignment.  
+ 
+ 	 The handling here differs from field_alignment.  ICC aligns MMX
+ 	 arguments to 4 byte boundaries, while structure fields are aligned
+ 	 to 8 byte boundaries.  */
+       if (!type)
+ 	{
+ 	  if (!SSE_REG_MODE_P (mode))
+ 	    align = PARM_BOUNDARY;
+ 	}
+       else
+ 	{
+ 	  if (!contains_128bit_aligned_vector_p (type))
+ 	    align = PARM_BOUNDARY;
+ 	}
+       if (align != PARM_BOUNDARY && !TARGET_SSE)
+ 	abort();
+     }
    if (align > 128)
      align = 128;
    return align;


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