http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48016
--- Comment #2 from H.J. Lu <hjl.tools at gmail dot com> 2011-03-07 14:40:35 UTC --- (In reply to comment #1) > The gimple middle-end only knows one pointer type mode, ptr_type_mode. If > we want to save Pmode then we need to use an appropriate integer type > and a proper alias set. > > I guess this code should be simply replaced to emit RTL directly instead > of going through expansion of an ARRAY_REF. For x32 target, we expand function h in: extern void foo (void) __attribute__((noreturn)); int n; void g (void) { __label__ lab; void h (void) { if (n == 2) goto lab; } void (*f1) (void) = foo; void (*f2) (void) = h; f2 (); if (n) f1 (); n = 1; lab: n++; } to h () { int n.3; long long unsigned int[3] * D.2708; # BLOCK 2 # PRED: ENTRY (fallthru) n.3_1 = n; if (n.3_1 == 2) goto <bb 3>; else goto <bb 4>; # SUCC: 3 (true) 4 (false) # BLOCK 3 # PRED: 2 (true) D.2708_3 = &CHAIN.5_2(D)->__nl_goto_buf; __builtin_nonlocal_goto (&<L2>, D.2708_3); # SUCC: # BLOCK 4 # PRED: 2 (false) return; # SUCC: EXIT } I am checking this patch as a workaround on x32 branch. diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32 index f39563b..3f1f953 100644 --- a/gcc/ChangeLog.x32 +++ b/gcc/ChangeLog.x32 @@ -1,3 +1,8 @@ +2011-03-07 H.J. Lu <hongjiu...@intel.com> + + PR middle-end/48016 + * explow.c (emit_stack_save): Adjust mode of stack save area. + 2011-03-06 H.J. Lu <hongjiu...@intel.com> * config/i386/predicates.md (aligned_operand): Check SUBREG_REG diff --git a/gcc/explow.c b/gcc/explow.c index 3401e49..460af1f 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -1008,6 +1008,14 @@ emit_stack_save (enum save_level save_level, rtx *psave) do_pending_stack_adjust (); if (sa != 0) sa = validize_mem (sa); + /* FIXME: update_nonlocal_goto_save_area may pass SA in the wrong mode. */ + if (GET_MODE (sa) != mode) + { + gcc_assert (ptr_mode != Pmode + && GET_MODE (sa) == ptr_mode + && mode == Pmode); + sa = adjust_address (sa, mode, 0); + } emit_insn (fcn (sa, stack_pointer_rtx)); }