Hi, Adjusted my original testcase so that eax isn't redeclared and shadows. Additional moved initialization of eax_live up. ChangeLog
2014-02-14 Kai Tietz <kti...@redhat.com> PR target/60193 * config/i386/i386.c (ix86_expand_prologue): Use rax register as displacement for restoring %r10, %rax. Additional fix wrong offset for restoring both-registers. ChangeLog testsuite 2014-02-14 Kai Tietz <kti...@redhat.com> PR target/60193 * gcc.target/i386/nest-1.c: New testcase. Regression-tested for x86_64-unknown-linux-gnu, and x86_64-w64-mingw32, and i686-w64-mingw32. Ok for apply? Regards, Kai Index: i386.c =================================================================== --- i386.c (Revision 207686) +++ i386.c (Arbeitskopie) @@ -11023,13 +11023,12 @@ ix86_expand_prologue (void) rtx r10 = NULL; rtx (*adjust_stack_insn)(rtx, rtx, rtx); const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx); - bool eax_live = false; + bool eax_live = ix86_eax_live_at_start_p (); bool r10_live = false; if (TARGET_64BIT) r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0); - eax_live = ix86_eax_live_at_start_p (); if (eax_live) { insn = emit_insn (gen_push (eax)); @@ -11084,17 +11083,20 @@ ix86_expand_prologue (void) works for realigned stack, too. */ if (r10_live && eax_live) { - t = plus_constant (Pmode, stack_pointer_rtx, allocate); + t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax); emit_move_insn (gen_rtx_REG (word_mode, R10_REG), gen_frame_mem (word_mode, t)); - t = plus_constant (Pmode, stack_pointer_rtx, - allocate - UNITS_PER_WORD); + + t = plus_constant (Pmode, eax, UNITS_PER_WORD); + emit_move_insn (eax, t); + t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax); emit_move_insn (gen_rtx_REG (word_mode, AX_REG), gen_frame_mem (word_mode, t)); } else if (eax_live || r10_live) { - t = plus_constant (Pmode, stack_pointer_rtx, allocate); + /* Don't exceed displacement-range for 64-bit. */ + t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax); emit_move_insn (gen_rtx_REG (word_mode, (eax_live ? AX_REG : R10_REG)), gen_frame_mem (word_mode, t)); Index: nest-1.c =================================================================== --- nest-1.c (Revision 0) +++ nest-1.c (Arbeitskopie) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +void foo (int i) +{ + void nested (void) + { + char arr[(1U << 31) + 4U]; + arr[i] = 0; + } + + nested (); +} +