------- Comment #1 from uweigand at gcc dot gnu dot org 2010-06-29 16:56
-------
I agree, this looks like a longstanding bug in
rs6000_legitimize_reload_address.
What happens here is that find_reloads is called on this insn:
(insn 15 8 18 2 pr44707.c:13 (asm_operands/v ("/* %0 %1 %2 %3 %4 */") ("") 0 [
(mem/s/c:SI (symbol_ref:SI ("v") [flags 0xc0] <var_decl 0xf6f90fc0
v>) [3 v.a+0 S4 A32])
(mem/c/i:SI (symbol_ref:SI ("w") [flags 0xc4] <var_decl 0xf6f91020
w>) [3 w+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 4 [0x4]))) [3 v.b+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 8 [0x8]))) [3 v.c+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 12 [0xc]))) [3 v.d+0 S4 A32])
]
[
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
]
[] pr44707.c:14) -1 (nil))
rs6000_find_reloads_address notices that it can rewrite
(symbol_ref:SI "v")
to
(lo_sum:SI (high:SI (symbol_ref:SI "v")) (symbol_ref:SI "v"))
(and place a reload on the (high:SI) subexpression) and does so. This change
remains in the insn, and when in the next iteration find_reloads is called
again, the insn now looks like:
(insn 15 8 18 2 pr44707.c:13 (asm_operands/v ("/* %0 %1 %2 %3 %4 */") ("") 0 [
(mem/s/c:SI (lo_sum:SI (high:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>))
(symbol_ref:SI ("v") [flags 0xc0] <var_decl 0xf6f90fc0 v>))
[3 v.a+0 S4 A32])
(mem/c/i:SI (lo_sum:SI (high:SI (symbol_ref:SI ("w") [flags 0xc4]
<var_decl 0xf6f91020 w>))
(symbol_ref:SI ("w") [flags 0xc4] <var_decl 0xf6f91020 w>))
[3 w+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 4 [0x4]))) [3 v.b+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 8 [0x8]))) [3 v.c+0 S4 A32])
(mem/s/c:SI (const:SI (plus:SI (symbol_ref:SI ("v") [flags 0xc0]
<var_decl 0xf6f90fc0 v>)
(const_int 12 [0xc]))) [3 v.d+0 S4 A32])
]
[
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
(asm_input:SI ("nro") (null):0)
]
[] pr44707.c:14) -1 (nil))
However, this expression is now no longer recognized by
rs6000_legitimize_reload_address, and therefore no reload on (high:SI) is
pushed.
Thus, when the reload is finally processed, a reload insn like this is
generated:
(insn 26 8 27 2 pr44707.c:13 (set (reg:SI 10 10)
(lo_sum:SI (high:SI (symbol_ref:SI ("v") [flags 0xc0] <var_decl
0xf6f90fc0 v>))
(symbol_ref:SI ("v") [flags 0xc0] <var_decl 0xf6f90fc0 v>))) -1
(nil))
As this does not actually correspond to any valid pattern, an assertion is
triggered.
The underlying problem is that with the current reload setup, an implementation
of LEGITIMATE_RELOAD_ADDRESS must always recognize expressions it has itself
generated in an earlier call. And indeed, that's what a comment in
rs6000_legitimize_reload_address says:
static rtx
rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
int opnum, int type,
int ind_levels ATTRIBUTE_UNUSED, int *win)
{
bool reg_offset_p = reg_offset_addressing_ok_p (mode);
/* We must recognize output that we have already generated ourselves. */
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
However, this recognizes only certain types of such output, and in particular
not the one that shows up in this test case.
It seems to me that simply extending rs6000_legitimate_reload_address to handle
this case as well should fix the bug.
--
uweigand at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever Confirmed|0 |1
Last reconfirmed|0000-00-00 00:00:00 |2010-06-29 16:56:47
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44707