This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Patch fuer bug in regmove.c
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Patch fuer bug in regmove.c
- From: Thomas Schuster <Thomas dot Schuster at gmx dot net>
- Date: Fri, 03 Mar 2000 00:36:26 +0100
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!
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;