------- Comment #5 from jakub at gcc dot gnu dot org 2008-06-03 09:13 ------- The short testcase reproduces also on the trunk. I see at least 3 problems with -fasynchronous-unwind-tables -mno-accumulate-outgoing-args -fno-omit-frame-pointer: 1) expand_resx_expr doesn't do pending stack adjust: --- except.c.jj 2008-04-28 11:35:55.000000000 +0200 +++ except.c 2008-06-03 10:27:04.000000000 +0200 @@ -540,6 +540,7 @@ expand_resx_expr (tree exp) cfun->eh->region_array, region_nr);
gcc_assert (!reg->resume); + do_pending_stack_adjust (); reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr)); emit_barrier (); } The problem with this change is that it is probably completely unnecessary if we end up calling Dwarf2 _Unwind_Resume, it is certainly needed when it is being changed into a jump. 2) as shown on the short testcases, CSA merges stack adjustments between a prologue stack adjustment and post-prologue stack adjustment. (insn/f 547 546 548 2 rhp.C:171 (parallel [ (set (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -76 [0xffffffffffffffb4]))) (clobber (reg:CC 17 flags)) (clobber (mem:BLK (scratch) [0 A8])) ]) -1 (nil)) ... (insn:HI 9 5 10 2 rhp.C:173 (parallel [ (set (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -12 [0xfffffffffffffff4]))) (clobber (reg:CC 17 flags)) ]) 283 {*addsi_1} (nil)) becomes after CSA: (insn/f 547 546 548 2 rhp.C:171 (parallel [ (set (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -88 [0xffffffffffffffa8]))) (clobber (reg:CC 17 flags)) (clobber (mem:BLK (scratch) [0 A8])) ]) 868 {pro_epilogue_adjust_stack_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) As dwarf2out_stack_adjust ignores prologue insns, without CSA it would properly set DW_CFA_GNU_args_size to 12 after that post-prologue adjustment but as it has been merged into a prologue stack adjustment, it is ignored and so DW_CFA_GNU_args_size is off-by-12 until first barrier. 3) As can be also seen on the short testcases, the assumption that after BARRIER we should reset DW_CFA_GNU_args_size back to 0 is wrong. While it holds (resp. should hold) during expansion and perhaps shortly after that, e.g. outof_cfglayout happily moves things around such that we have unconditional jumps and BARRIERs too, with different level of stack pushing than level DW_CFA_GNU_args_size 0. Any ideas about this? Do you think it is ok to just apply 1) or should we e.g. try to remove unnecessary stack adjustments before _Unwind_Resume (though, _Unwind_Resume is a call, so we probably need to guarantee correct stack alignment at least). For 2) and 3), we might just walk the whole function, noting the level of stack pushing for all labels, verify at CALLs that it matches their second operand and verify that all jumps to labels have the same level of stack pushing. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ebotcazou at libertysurf dot | |fr, hubicka at gcc dot gnu | |dot org Summary|[4.3 Regression] Wrong |[4.3/4.4 Regression] Wrong |unwind info with -Os - |unwind info with -Os - |fasynchronous-unwind-tables |fasynchronous-unwind-tables http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36419