mirror of git://gcc.gnu.org/git/gcc.git
mips: Fix overaligned function arguments [PR109435]
This patch changes alignment for typedef types when passed as arguments, making the alignment equal to the alignment of original (aliased) types. This change makes it impossible for a typedef type to have alignment that is less than its size. 2023-06-27 Jovan Dmitrović <jovan.dmitrovic@syrmia.com> gcc/ChangeLog: PR target/109435 * config/mips/mips.cc (mips_function_arg_alignment): Returns the alignment of function argument. In case of typedef type, it returns the aligment of the aliased type. (mips_function_arg_boundary): Relocated calculation of the aligment of function arguments. gcc/testsuite/ChangeLog: * gcc.target/mips/align-1-n64.c: New test. * gcc.target/mips/align-1-o32.c: New test.
This commit is contained in:
parent
14bfda6084
commit
e20abdb749
|
@ -6271,6 +6271,23 @@ mips_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
|
|||
return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
|
||||
}
|
||||
|
||||
/* Given MODE and TYPE of a function argument, return the alignment in
|
||||
bits.
|
||||
In case of typedef, alignment of its original type is
|
||||
used. */
|
||||
|
||||
static unsigned int
|
||||
mips_function_arg_alignment (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (!type)
|
||||
return GET_MODE_ALIGNMENT (mode);
|
||||
|
||||
if (is_typedef_decl (TYPE_NAME (type)))
|
||||
type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
|
||||
|
||||
return TYPE_ALIGN (type);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
|
||||
least PARM_BOUNDARY bits of alignment, but will be given anything up
|
||||
to STACK_BOUNDARY bits if the type requires it. */
|
||||
|
@ -6279,8 +6296,8 @@ static unsigned int
|
|||
mips_function_arg_boundary (machine_mode mode, const_tree type)
|
||||
{
|
||||
unsigned int alignment;
|
||||
alignment = mips_function_arg_alignment (mode, type);
|
||||
|
||||
alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
|
||||
if (alignment < PARM_BOUNDARY)
|
||||
alignment = PARM_BOUNDARY;
|
||||
if (alignment > STACK_BOUNDARY)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* Check that typedef alignment does not affect passing of function
|
||||
parameters for N64/N32 ABIs. */
|
||||
/* { dg-do compile { target { "mips*-*-*" } } } */
|
||||
/* { dg-options "-mabi=64" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
|
||||
|
||||
typedef struct ui8
|
||||
{
|
||||
unsigned v[8];
|
||||
} uint8 __attribute__ ((aligned(64)));
|
||||
|
||||
unsigned
|
||||
callee (int x, uint8 a)
|
||||
{
|
||||
return a.v[0];
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$5,0\\(\\\$\[0-9\]\\)" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$6,8\\(\\\$\[0-9\]\\)" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$7,16\\(\\\$\[0-9\]\\)" } } */
|
|
@ -0,0 +1,20 @@
|
|||
/* Check that typedef alignment does not affect passing of function
|
||||
parameters for O32 ABI. */
|
||||
/* { dg-do compile { target { "mips*-*-*" } } } */
|
||||
/* { dg-options "-mabi=32" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
|
||||
|
||||
typedef struct ui8
|
||||
{
|
||||
unsigned v[8];
|
||||
} uint8 __attribute__ ((aligned(64)));
|
||||
|
||||
unsigned
|
||||
callee (int x, uint8 a)
|
||||
{
|
||||
return a.v[0];
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tsw\t\\\$5,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
|
||||
/* { dg-final { scan-assembler "\tsw\t\\\$6,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
|
||||
/* { dg-final { scan-assembler "\tsw\t\\\$7,1\\d\\d\\(\\\$(sp|fp)\\)" } } */
|
Loading…
Reference in New Issue