This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
gcse fouling notes
- To: gcc-patches at gcc dot gnu dot org
- Subject: gcse fouling notes
- From: Alan Modra <amodra at bigpond dot net dot au>
- Date: Tue, 12 Jun 2001 21:57:54 +0930
This "interesting" REG_EQUAL note, generated during gcse, causes
an abort in pa.c:output_global_address, which doesn't expect
a string of `const's like this.
(insn 424 421 428 (set (reg/s/f:SI 229)
(plus:SI (reg/s/f:SI 225)
(reg/s:SI 227))) 166 {addsi3} (nil)
(expr_list:REG_EQUAL (const:SI (const:SI (const:SI (plus:SI (symbol_ref:SI ("game"))
(const_int 131072 [0x20000])))))
(nil)))
In try_replace_reg, we start with:
(gdb) p debug_rtx (from)
(reg/s:SI 227)
(gdb) p debug_rtx (to)
(const_int 131072 [0x20000])
(gdb) p debug_rtx (insn)
(insn 424 421 428 (set (reg/s/f:SI 229)
(plus:SI (reg/s/f:SI 225)
(reg/s:SI 227))) 166 {addsi3} (nil)
(expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("game"))
(const_int 131072 [0x20000])))
(nil)))
and validate_replace_rtx_1 eventually gets to work on the note.
<case PLUS> turns
(plus:SI (symbol_ref:SI ("game"))
(const_int 131072 [0x20000]))
into
(const:SI (plus:SI (symbol_ref:SI ("game"))
(const_int 131072 [0x20000])))
I think this should fix the problem, but there are a number of
other possible solutions. eg. Teaching simplify_rtx to remove
outermost `const's in a string of `const's.
* recog.c (validate_replace_rtx_1): Exit early if nothing changed
in args of commutative or comparison operations.
This one affects the branch too, but I don't have a simple testcase.
--
Alan Modra
--- gcc/recog.c.orig Tue Jun 12 20:40:33 2001
+++ gcc/recog.c Tue Jun 12 21:42:14 2001
@@ -437,7 +437,15 @@ validate_replace_rtx_1 (loc, from, to, o
validate_replace_rtx_1 (&XEXP (x, 0), from, to, object);
validate_replace_rtx_1 (&XEXP (x, 1), from, to, object);
- if (prev_changes != num_changes && CONSTANT_P (XEXP (x, 0)))
+ /* If nothing changed, we can exit now. In fact, continuing on
+ into the switch statement below can be bad, eg. turning
+ (plus (symbol_ref) (const_int)) into
+ (const (plus (symbol_ref) (const_int))). This might not seem
+ so bad, but the first rtx is already enclosed in `const', so
+ we get a string of (const (const (const...))). */
+ if (prev_changes == num_changes)
+ return;
+ if (CONSTANT_P (XEXP (x, 0)))
{
validate_change (object, loc,
gen_rtx_fmt_ee (GET_RTX_CLASS (code) == 'c' ? code