This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to fix rtx sharing problem in noce_process_if_block
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 30 Jan 2002 18:54:02 +0000
- Subject: Patch to fix rtx sharing problem in noce_process_if_block
This patch is for a memory sharing problem in noce_process_if_block.
The problem is easy to demonstrate, but it's annoyingly difficult to
come up with a test case that fails because of it.
The following code:
extern unsigned int a;
void bar (int c)
{
if (c == 1)
(&a)[8] = 1;
}
will be converted as follows on MIPS IV:
lw $2,a+32
xori $3,$4,0x1
movz $2,$4,$3
sw $2,a+32
j $31
The rtx representing a+32 is shared between the first and last
instructions. (To prove it, I modified print-rtl.c to print the
addresses of MEMs. See below for the RTL output before and after
the patch.)
Is the following patch the right way to fix things? Tested on
mips64-elf with no regressions.
Richard
* ifcvt.c (noce_process_if_block): Make a copy of the destination
when copying back from a temporary.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.76
diff -u -p -d -r1.76 ifcvt.c
--- ifcvt.c 2002/01/10 20:37:42 1.76
+++ ifcvt.c 2002/01/30 10:56:01
@@ -1792,7 +1792,7 @@ noce_process_if_block (test_bb, then_bb,
if (orig_x != x)
{
start_sequence ();
- noce_emit_move_insn (orig_x, x);
+ noce_emit_move_insn (copy_rtx (orig_x), x);
insn_b = gen_sequence ();
end_sequence ();
cse2 dump before the patch. MEM rtxs prefixed by their addresses:
----------------------------------------------------------------------
(insn 4 24 5 (set (reg/v:SI 81)
(reg:SI 4 a0)) 159 {movsi_internal2} (nil)
(expr_list:REG_EQUIV (0x401f3678 mem/f:SI (plus:SI (reg/f:SI 0 $0)
(const_int 4 [0x4])) [2 c+0 S4 A32])
(nil)))
(insn 11 5 30 (set (reg:SI 82)
(const_int 1 [0x1])) 159 {movsi_internal2} (nil)
(expr_list:REG_EQUAL (const_int 1 [0x1])
(nil)))
(insn 30 11 31 (set (reg:SI 86)
(0x401f37e0 mem:SI (const:SI (plus:SI (symbol_ref/v:SI ("a"))
(const_int 32 [0x20]))) [2 S4 A32])) 159 {movsi_internal2} (nil)
(nil))
(insn 31 30 32 (set:SI (reg:SI 87)
(xor:SI (reg/v:SI 81)
(const_int 1 [0x1]))) 101 {*mips.md:3472} (nil)
(nil))
(insn 32 31 35 (set:SI (reg:SI 85)
(if_then_else:SI (eq (reg:SI 87)
(const_int 0 [0x0]))
(reg/v:SI 81)
(reg:SI 86))) 312 {*mips.md:10247} (nil)
(nil))
(insn 35 32 21 (set (0x401f37e0 mem:SI (const:SI (plus:SI (symbol_ref/v:SI ("a"))
(const_int 32 [0x20]))) [2 S4 A32])
(reg:SI 85)) 159 {movsi_internal2} (nil)
(nil))
----------------------------------------------------------------------
cse2 dump after the patch:
----------------------------------------------------------------------
(insn 4 24 5 (set (reg/v:SI 81)
(reg:SI 4 a0)) 159 {movsi_internal2} (nil)
(expr_list:REG_EQUIV (0x401f3678 mem/f:SI (plus:SI (reg/f:SI 0 $0)
(const_int 4 [0x4])) [2 c+0 S4 A32])
(nil)))
(insn 11 5 30 (set (reg:SI 82)
(const_int 1 [0x1])) 159 {movsi_internal2} (nil)
(expr_list:REG_EQUAL (const_int 1 [0x1])
(nil)))
(insn 30 11 31 (set (reg:SI 86)
(0x401f37e0 mem:SI (const:SI (plus:SI (symbol_ref/v:SI ("a"))
(const_int 32 [0x20]))) [2 S4 A32])) 159 {movsi_internal2} (nil)
(nil))
(insn 31 30 32 (set:SI (reg:SI 87)
(xor:SI (reg/v:SI 81)
(const_int 1 [0x1]))) 101 {*mips.md:3472} (nil)
(nil))
(insn 32 31 35 (set:SI (reg:SI 85)
(if_then_else:SI (eq (reg:SI 87)
(const_int 0 [0x0]))
(reg/v:SI 81)
(reg:SI 86))) 312 {*mips.md:10247} (nil)
(nil))
(insn 35 32 21 (set (0x401f3ee8 mem:SI (const:SI (plus:SI (symbol_ref/v:SI ("a"))
(const_int 32 [0x20]))) [2 S4 A32])
(reg:SI 85)) 159 {movsi_internal2} (nil)
(nil))
----------------------------------------------------------------------