This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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;