------- Comment #7 from jakub at gcc dot gnu dot org 2009-07-09 12:56 -------
There are multiple places which bump crtl->stack_alignment_estimated to 64
during expansion in this case (thus forcing stack_realign_needed):
if (SUPPORTS_STACK_ALIGNMENT)
{
unsigned int align = FUNCTION_ARG_BOUNDARY (data.promoted_mode,
data.passed_type);
if (TYPE_ALIGN (data.nominal_type) > align)
align = TYPE_ALIGN (data.passed_type);
if (crtl->stack_alignment_estimated < align && 0)
{
gcc_assert (!crtl->stack_realign_processed);
crtl->stack_alignment_estimated = align;
}
}
in assign_parms and:
/* If a virtual register with bigger mode alignment is generated,
increase stack alignment estimation because it might be spilled
to stack later. */
if (SUPPORTS_STACK_ALIGNMENT
&& crtl->stack_alignment_estimated < align
&& !crtl->stack_realign_processed)
crtl->stack_alignment_estimated = align;
in gen_reg_rtx (DImode) called from parmreg = gen_reg_rtx
(promoted_nominal_mode); in assign_parm_setup_reg.
We'd need to arrange for these bumps not to happen for long long incoming
parameters somehow. Another testcase:
int f (long long x);
long long x;
int
g (void)
{
f (x);
return 0;
}
which would need something in expand_one_var:
1166 if (TREE_STATIC (var) || DECL_EXTERNAL (var))
1167 align = TYPE_ALIGN (TREE_TYPE (var));
1168 else
1169 align = DECL_ALIGN (var);
1170
1171 if (crtl->stack_alignment_estimated < align)
1172 {
1173 /* stack_alignment_estimated shouldn't change after stack
1174 realign decision made */
1175 gcc_assert(!crtl->stack_realign_processed);
1176 crtl->stack_alignment_estimated = align;
1177 }
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40667