------- 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