------- 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