http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50251
--- Comment #9 from vries at gcc dot gnu.org 2011-09-02 09:03:54 UTC --- The following testcase reproduces the same failure without alloca, vla, or the 178353 patch. stack-stave-restore.c: ... extern void bar (int*); char *p; int main () { int q; p = __builtin_stack_save (); bar (&q); __builtin_stack_restore (p); bar (&q); return 0; } ... Using &q makes sure we use virtual-stack-vars, which expands into something using FRAME_POINTER_REG. Main has an incoming stack boundary of 32, and a preferred one of 128, so a realign is needed. Nothing sets crtl->need_drap, so we have stack_realign_fp rather than stack_realign_drap. This forbids elimination from FRAME_POINTER_REG to HARD_FRAME_POINTER_REG. The __builtin_stack_restore stays until ira (if we wouldn't by declaring p global), and this forbids elimination from FRAME_POINTER_REG to STACK_POINTER_REGNUM. FRAME_POINTER_REG cannot be eliminated, and we assert. This patch sets need_drap when a stack_restore is present at expand, which allows both the 20010209-1.c and the stack-stave-restore.c testcase to succeed: ... Index: src/gcc-mainline/gcc/explow.c =================================================================== --- src/gcc-mainline/gcc/explow.c (revision 178379) +++ src/gcc-mainline/gcc/explow.c (working copy) @@ -1062,6 +1062,9 @@ emit_stack_restore (enum save_level save /* The default is that we use a move insn. */ rtx (*fcn) (rtx, rtx) = gen_move_insn; + if (SUPPORTS_STACK_ALIGNMENT) + crtl->need_drap = true; + /* See if this machine has anything special to do for this kind of save. */ switch (save_level) { ...