This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/25130] [4.1/4.2 Regression] miscompilation in GCSE



------- Comment #3 from wilson at gcc dot gnu dot org  2005-11-29 06:10 -------
This is indeed a gcse problem.  It is a problem with the load motion support.

There are some similarities to PR 24804 here.  We have multiple overlapping
objects on the stack, that have mems with different MEM_EXPR fields, that are
being treated as the same object because they have the same hash code.  This
results in some new RTL being emitted by gcse that has mems with incorrect
MEM_EXPR fields.  This doesn't cause the failure though, and seems to be
harmless for this testcase.  This is potentially a problem for other testcases
though.

The problem happens shortly before the printf call.  We have before gcse
(insn 60 58 61 3 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffffffffffff8])) [0
clusters.D.1787\._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffffffffffff8])) [0
clusters.D.\1787._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 208 {*addsi_1} (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)

;; Start of basic block 4, registers live: (nil)
(code_label 61 60 62 4 4 "" [1 uses])

(note 62 61 64 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 64 62 65 4 (set (reg:SI 72 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [0
clusters.D.1787._M_impl\._M_finish_cur+0 S4 A32])) 40 {*movsi_1} (nil)
    (nil))

and after gcse we have
(insn 60 58 124 3 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffffffffffff8])) [0
clusters.D.1787\._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffffffffffff8])) [0
clusters.D.\1787._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 208 {*addsi_1} (nil)
    (nil))

(jump_insn 124 60 125 3 (set (pc)
        (label_ref 61)) -1 (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)

(barrier 125 124 127)

;; Start of basic block 4, registers live: (nil)
(code_label 127 125 126 4 12 "" [1 uses])

(note 126 127 121 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 121 126 61 4 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [0
<variable>._M_impl._M_s\tart_node+0 S4 A32])) 40 {*movsi_1} (nil)
    (nil))
;; End of basic block 4, registers live:
 (nil)

;; Start of basic block 5, registers live: (nil)
(code_label 61 121 62 5 4 "" [1 uses])

(note 62 61 65 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(insn 65 62 66 5 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S4 A32])
        (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])) 40 {*movsi_1}
(n\il)
    (nil))

For some reason, gcse thought that insn 64 was redundant, and deleted it,
adding a new basic block with a load as compensation code.  This results in reg
79 having the wrong value when we go from the increment to the printf.

I haven't pinpointed an exact cause of the problem.  The gcse algorithmics are
complicated.  I think the underlying failure is that we are adding mems to the
expression table, and adding their load/store insns to the ldst_table.  When we
find a load/store we can't handle, we remove it from the ldst_table.  However,
we never remove entries from the expression table.  Since there are still mems
in the expression table, gcse still tries to optimize them.  And this results
in bad code, because some load/store insns needs fixups when their mems are
optimized, and these fixups do not happen because the load/store insns are no
longer in the ldst_table.  The fixups are supposed to be emitted in
update_ld_motion_stores.


-- 

wilson at gcc dot gnu dot org changed:

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]