------- Comment #2 from jakub at gcc dot gnu dot org  2008-08-01 16:13 -------
I've managed to reproduce it, only happens with -mtune=i586 apparently.
Without my patch GCC doesn't ICE, just creates bad unwind info.
In *.greg dump we have (in uname__uname_lt):
(insn:HI 10 9 11 3 uname.adb:615 (parallel [
            (set (reg/f:SI 7 sp)
                (plus:SI (reg/f:SI 7 sp)
                    (const_int -12 [0xfffffffffffffff4])))
            (clobber (reg:CC 17 flags))
        ]) 249 {*addsi_1} (nil))

(insn:HI 11 10 12 3 uname.adb:615 (set (mem/i:SI (pre_dec:SI (reg/f:SI 7 sp))
[0 S4 A32])
        (reg/v:SI 0 ax [orig:70 left ] [70])) 40 {*pushsi2} (nil))

(call_insn:HI 12 11 13 3 uname.adb:615 (call (mem:QI (symbol_ref:SI
("namet__get_name_string") [flags 0x41] <function_decl 0x7fa5
        (const_int 16 [0x10])) 601 {*call_0} (nil)
    (nil))

(insn:HI 13 12 14 3 uname.adb:616 (parallel [
            (set (reg/f:SI 5 di [88])
                (plus:SI (reg/f:SI 7 sp)
                    (const_int 16 [0x10])))
            (clobber (reg:CC 17 flags))
        ]) 249 {*addsi_1} (expr_list:REG_EQUIV (plus:SI (reg/f:SI 7 sp)
            (const_int 16 [0x10]))
        (nil)))

...
(insn:HI 16 15 173 3 uname.adb:616 (parallel [
            (set (reg/f:SI 7 sp)
                (plus:SI (reg/f:SI 7 sp)
                    (const_int 16 [0x10])))
            (clobber (reg:CC 17 flags))
        ]) 249 {*addsi_1} (nil))

...
(insn:HI 26 155 27 3 uname.adb:616 (parallel [
            (set (reg/f:SI 7 sp)
                (plus:SI (reg/f:SI 7 sp)
                    (const_int -4 [0xfffffffffffffffc])))
            (clobber (reg:CC 17 flags))
        ]) 249 {*addsi_1} (nil))

(insn:HI 27 26 28 3 uname.adb:616 (set (mem/i:SI (pre_dec:SI (reg/f:SI 7 sp))
[0 S4 A32])
        (reg:SI 1 dx [73])) 40 {*pushsi2} (nil))

(insn:HI 28 27 29 3 uname.adb:616 (set (mem/f/i:SI (pre_dec:SI (reg/f:SI 7 sp))
[0 S4 A32])
        (symbol_ref:SI ("namet__name_buffer") [flags 0x40] <var_decl
0x7fa51618a140 namet__name_buffer>)) 40 {*pushsi2} (nil))

(insn:HI 29 28 30 3 uname.adb:616 (set (mem/f/i:SI (pre_dec:SI (reg/f:SI 7 sp))
[0 S4 A32])
        (reg/f:SI 5 di [88])) 40 {*pushsi2} (nil))

(call_insn:HI 30 29 33 3 uname.adb:616 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("memcpy") [flags 0x41] <function_decl
0x7fa5161dc5b0 memcpy>) [0 S1 A8])
            (const_int 16 [0x10]))) 839 {*call_value_0}
(expr_list:REG_EH_REGION (const_int 0 [0x0])
        (nil))
    (nil))

and no stack adjustments in between.  The first insn listed above starts at
args_size 0 level, then the first call is at args_size 16 level, then we pop up
the stack back to args_size 0 level, decrease by 4 bytes again and push 3 * 4
bytes, so again memcpy is at args_size 16 level.
But *.postreload decides to change insn 16 into:
(insn:HI 16 15 173 3 uname.adb:616 (set (reg/f:SI 7 sp)
        (reg/f:SI 5 di [88])) 47 {*movsi_1} (nil))
which is equivalent to the sp = sp + 16, but unfortunately is something
stack_adjust_offset doesn't track for the args_size adjustments.  Which means
that args_size on the second call will be 32 instead of the correct 16, and
with my patch it ICEs because label 127 is reachable both from a place where
args_size is 0 (jump_insn 8) and from a place where gcc believes it is 16
(after the memcpy call).

Not sure what's the best way to fix this though.  I can surely remove the
assert and let it silently generate invalid unwind info, but I don't think
that's a good idea.  So, either reload is changed not to do this (pointless)
replacement,
or perhaps the dwarf2out.c could assume if sp is set to some register (rather
than sp + const), args_size should be reset to 0 (though, I really don't know
if
that would be a safe assumption).  Tracking all registers that might ever
contain some pointers into the stack would be a nightmare.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36998

Reply via email to