http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47918
Summary: [4.6 regression] noreturn discovery broke non local gotos on m68k Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: mi...@it.uu.se gcc.dg/torture/stackalign/non-local-goto-4.c and several similar test cases fail with current 4.6 on m68k-linux. Bisection identified r160124 as the cause: Author: hubicka Date: Tue Jun 1 21:55:49 2010 New Revision: 160124 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=160124 Log: * ipa-pure-const.c (local_pure_const): Do NORETURN discovery. The essence of non-local-goto-4.c is a function x() with a local self-recursive function y() and a non-local goto from y() to x(): x(a) { __label__ xlab; void y(a) { if (a==0) goto xlab; y (a-1); } y (a); xlab:; return a; } With r160123, gcc -O3 -fomit-frame-pointer -S generates this for x() and y(): .text .align 2 .type y.1201, @function y.1201: link.w %fp,#0 move.l #.L2,%a1 move.l (%a0),%fp move.l 4(%a0),%sp jmp (%a1) .size y.1201, .-y.1201 .align 2 .globl x .type x, @function x: lea (-12,%sp),%sp fmovem #252,-(%sp) movem.l #16190,-(%sp) lea (128,%sp),%a0 move.l %a0,116(%sp) move.l %sp,120(%sp) move.l 132(%sp),-(%sp) lea (120,%sp),%a0 jsr y.1201 addq.l #4,%sp .L4: move.l 132(%sp),%d0 movem.l (%sp)+,#31996 fmovem (%sp)+,#63 lea (12,%sp),%sp rts .L2: move.l 132(%sp),%d0 movem.l (%sp)+,#31996 fmovem (%sp)+,#63 lea (12,%sp),%sp rts .size x, .-x This works. But r160124 changes the code to: .align 2 .type y.1201, @function y.1201: link.w %fp,#0 move.l #.L2,%a1 move.l (%a0),%fp move.l 4(%a0),%sp jmp (%a1) .size y.1201, .-y.1201 .align 2 .globl x .type x, @function x: lea (-12,%sp),%sp fmovem #252,-(%sp) movem.l #16190,-(%sp) lea (128,%sp),%a0 move.l %a0,116(%sp) move.l %sp,120(%sp) move.l 132(%sp),-(%sp) lea (120,%sp),%a0 jsr y.1201 .L2: .L4: move.l 136(%sp),%d0 movem.l (%sp)+,#31996 fmovem (%sp)+,#63 lea (12,%sp),%sp rts .size x, .-x A diff shows that L2 and L4 have been merged, a stack increment before L4 has been removed and the stack offset for loading %d0 in L4 has been adjusted for that. However, the path leading up to L2 is the same as before, but L2 is now the same as L4 so uses an incorrect (off-by-4) stack offset when fetching %d2. --- non-local-goto-4.s-r160123 2011-02-27 23:44:28.000000000 +0100 +++ non-local-goto-4.s-r160124 2011-02-27 23:36:27.000000000 +0100 @@ -23,15 +23,9 @@ move.l 132(%sp),-(%sp) lea (120,%sp),%a0 jsr y.1201 - addq.l #4,%sp -.L4: - move.l 132(%sp),%d0 - movem.l (%sp)+,#31996 - fmovem (%sp)+,#63 - lea (12,%sp),%sp - rts .L2: - move.l 132(%sp),%d0 +.L4: + move.l 136(%sp),%d0 movem.l (%sp)+,#31996 fmovem (%sp)+,#63 lea (12,%sp),%sp