This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
regmove.c duplicates SET of UNCHANGING destination
- To: gcc-patches at gcc dot gnu dot org
- Subject: regmove.c duplicates SET of UNCHANGING destination
- From: Thomas dot Schuster at atd dot mchh dot siemens dot de
- Date: Fri, 3 Mar 2000 08:06:58 +0100
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;