This is the mail archive of the gcc-patches@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]

regmove.c duplicates SET of UNCHANGING destination


I've posted this message to  gcc-bugs@gcc.gnu.org  but didn't see any
reaction. Since I'm subscribed to gcc-patches I hope this mail gets
through....
++++++++++++++++


In message  http://gcc.gnu.org/ml/gcc-bugs/2000-02/msg00723.html  I
mentioned a
bug (with source code).

Further analysis showed the reason: regmove.c:copy_src_to_dest duplicates
SETs
of insns with the unchanging attribute (REG 53):

bug.c.09.combine
;; Start of basic block 6, registers live: 6 [bp] 7 [sp] 20 [frame] 29 30 31
37
39 47 58 73
(code_label 103 102 406 13 "" "" [num uses: 1])

(note 406 103 104 [bb 6] NOTE_INSN_BASIC_BLOCK)

(note 104 406 108 ("bug.c") 94)

(insn 108 104 109 (parallel[ 
            (set (reg/v/u:SI 53)
                (minus:SI (reg:SI 47)
                    (reg/v/u:SI 39)))
            (clobber (reg:CC 17 flags))
        ] ) -1 (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

bug.c.10.regmove
;; Start of basic block 6, registers live: 6 [bp] 7 [sp] 20 [frame] 29 30 31
37
39 47 58 73
(code_label 103 102 406 13 "" "" [num uses: 1])

(note 406 103 104 [bb 6] NOTE_INSN_BASIC_BLOCK)

(note 104 406 425 ("bug.c") 94)

(insn 425 104 108 (set (reg/v/u:SI 53)
        (reg:SI 47)) 37 {*movsi_1} (nil)
    (nil))

(insn 108 425 109 (parallel[ 
            (set (reg/v/u:SI 53)
                (minus:SI (reg/v/u:SI 53)
                    (reg/v/u:SI 39)))
            (clobber (reg:CC 17 flags))
        ] ) 198 {*subsi_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))


(At least) the dead code elimination of flow.c gets confused by the
duplicate
SET of an unchanging insn:
mark_used_regs->anti_dependence->write_dependence_p has a comment:

  /* If MEM is an unchanging read, then it can't possibly conflict with
     the store to X, because there is at most one store to MEM, and it must
     have occurred somewhere before MEM.  */
  if (!writep && RTX_UNCHANGING_P (mem))
    return 0;

As result insn 425 gets eliminated which results in a read of an
uninitialized
memory location.

bug.c.14.flow2:
;; Start of basic block 6, registers live: 3 [bx] 5 [di] 6 [bp] 7 [sp] 20
[frame]
(code_label 103 102 406 13 "" "" [num uses: 1])

(note 406 103 104 [bb 6] NOTE_INSN_BASIC_BLOCK)

(note 104 406 425 ("bug.c") 94)

(note 425 104 108 "" NOTE_INSN_DELETED)

(insn 108 425 109 (parallel[ 
            (set (mem/u:SI (plus:SI (reg:SI 6 ebp)
                        (const_int -88 [0xffffffa8])) 0)
                (minus:SI (mem/u:SI (plus:SI (reg:SI 6 ebp)
                            (const_int -88 [0xffffffa8])) 0)
                    (reg/v/u:SI 3 ebx)))
            (clobber (reg:CC 17 flags))
        ] ) 198 {*subsi_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

(note 109 108 111 ("bug.c") 96)


FIX:
Avoid creating two SETs for an "unchanging" reg 53!
Diff is against egcs-20000229


Wed Mar  3 00:30:31 MET 2000  Thomas Schuster <Thomas.Schuster@gmx.net>
	* regmove.c (copy_src_to_dest)  Do not create src->dest move
	for unchanging destination.


*** regmove.c	Wed Mar  1 22:16:20 2000
--- regmove.patched.c	Fri Mar  3 00:24:15 2000
*************** copy_src_to_dest (insn, src, dest, old_m
*** 763,768 ****
--- 763,769 ----
        && REG_LIVE_LENGTH (REGNO (dest)) > 0
        && (set = single_set (insn)) != NULL_RTX
        && !reg_mentioned_p (dest, SET_SRC (set))
+       && !RTX_UNCHANGING_P (dest)
        && GET_MODE (src) == GET_MODE (dest))
      {
        int old_num_regs = reg_rtx_no;



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