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)
     {
...

Reply via email to