------- 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

Reply via email to