This is PR56791. The address inside of an autoinc is reloaded, and the
autoinc is reloaded, but the reload insns are emitted in the wrong order.
As far as I can tell, this is because find_reloads_address_1 has two
methods of pushing a reload for an autoinc, one of them using the
previously identified type, and the other (better one) using
RELOAD_OTHER. If we previously reloaded an inner part of the address,
the use of RELOAD_OTHER is mismatched and leads to the wrong order of insns.
This patch just remembers if we've pushed a reload, and forces the
optimization to be skipped in that case. Bootstrapped and tested on
x86_64-linux (with lra_p disabled but still somewhat pointlessly); John
Anglin said in the PR that it tests ok on PA. Will commit in a few days
if no objections.
Bernd
diff --git a/gcc/reload.c b/gcc/reload.c
index 2546c1b..279c4b8e 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -5557,6 +5557,7 @@ find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
enum reg_class context_reg_class;
RTX_CODE code = GET_CODE (x);
+ bool reloaded_inner_of_autoinc = false;
if (context == 1)
context_reg_class = INDEX_REG_CLASS;
@@ -5844,6 +5846,7 @@ find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
&XEXP (tem, 0), opnum, type,
ind_levels, insn);
+ reloaded_inner_of_autoinc = true;
if (!rtx_equal_p (tem, orig))
push_reg_equiv_alt_mem (regno, tem);
/* Put this inside a new increment-expression. */
@@ -5892,7 +5895,10 @@ find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
#endif
&& ! (icode != CODE_FOR_nothing
&& insn_operand_matches (icode, 0, equiv)
- && insn_operand_matches (icode, 1, equiv)))
+ && insn_operand_matches (icode, 1, equiv))
+ /* Using RELOAD_OTHER means we emit this and the reload we
+ made earlier in the wrong order. */
+ && !reloaded_inner_of_autoinc)
{
/* We use the original pseudo for loc, so that
emit_reload_insns() knows which pseudo this