SSE fix 12 - argument alignment PR pending/8212
Jan Hubicka
jh@suse.cz
Mon Oct 21 08:12:00 GMT 2002
> On Sun, Oct 20, 2002 at 12:23:54AM +0200, Jan Hubicka wrote:
> > OK. Do you see different choice than walking recursivly the types and
> > looking for vector modes?
>
> Worst case, no.
>
> In the normal case, if TYPE_USER_ALIGN is _not_ set, then we
> can just use the alignment given without searching.
>
> But if TYPE_USER_ALIGN _is_ set, then we have to search to
> see if there are vector mode types that _havn't_ been set to
> have user alignment less than normal.
Hi,
here is updated version of the patch. Types are still bit magic to me,
but hope it does what it should. I didn't suceeded to produce testcase
for vector type with lowered alignment. My attempt:
#include <xmmintrin.h>
struct a
{
__m128 b __attribute__ ((aligned (8)));
} aa;
test (int a, struct a b, int c);
q()
{
test (1,aa,2);
}
Is still 128bit aligned.
Honza
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: 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
*** i386.c 20 Oct 2002 22:37:10 -0000 1.478
--- i386.c 21 Oct 2002 15:07:12 -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_USER_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;
More information about the Gcc-patches
mailing list