------- Comment #15 from dave dot korn dot cygwin at gmail dot com 2009-01-25 06:33 ------- (In reply to comment #14) > And that is presumably the intention of this if clause in ix86_can_eliminate: > > if (stack_realign_fp) > return ((from == ARG_POINTER_REGNUM > && to == HARD_FRAME_POINTER_REGNUM) > || (from == FRAME_POINTER_REGNUM > && to == STACK_POINTER_REGNUM)); > else [ ... ] >
I just looked twice at that and it seemed odd to me. Testing this: if (stack_realign_fp) return ((from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) || (from == FRAME_POINTER_REGNUM - && to == STACK_POINTER_REGNUM)); + && to == HARD_FRAME_POINTER_REGNUM)); gives me this: (gdb) disass main Dump of assembler code for function main: 0x00401070 <main+0>: push %ebp 0x00401071 <main+1>: mov %esp,%ebp 0x00401073 <main+3>: and $0xfffffff0,%esp 0x00401076 <main+6>: push %edi 0x00401077 <main+7>: push %esi 0x00401078 <main+8>: push %ebx 0x00401079 <main+9>: sub $0x54,%esp 0x0040107c <main+12>: movl $0x4075f0,-0x34(%ebp) 0x00401083 <main+19>: movl $0x407bc4,-0x30(%ebp) 0x0040108a <main+26>: lea -0x2c(%ebp),%eax 0x0040108d <main+29>: lea -0x18(%ebp),%edx 0x00401090 <main+32>: mov %edx,(%eax) 0x00401092 <main+34>: mov $0x4010e2,%edx 0x00401097 <main+39>: mov %edx,0x4(%eax) 0x0040109a <main+42>: mov %esp,0x8(%eax) 0x0040109d <main+45>: lea -0x4c(%ebp),%eax 0x004010a0 <main+48>: mov %eax,(%esp) 0x004010a3 <main+51>: call 0x405058 <_Unwind_SjLj_Register> Which works, but now I suspect the address calculations accessing the jmp_buf are going to be wrong. Argh. It looks like we have to know whether there's an offset in the mem rtx relating to FRAME_POINTER_REGNUM and if it's negative we have to allow elimination against STACK_POINTER but if its zero or positive we'd have to only allow elimination against HARD_FRAME_POINTER ... ouch. Guess the next thing I'll try is simply not allowing elimination against FRAME_POINTER at all in this context. That'll mean we can't -fomit-frame-pointer in functions which have stack_realign_fp true, but it beats wrong code and maybe there's a way of avoiding it that I haven't thought of. Now testing: if (stack_realign_fp) return ((from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) || (from == FRAME_POINTER_REGNUM - && to == STACK_POINTER_REGNUM)); + && 0)); -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38952