[SH,committed] Fix PR 101469
Checks
Commit Message
Hi,
The attached patch fixes PR 101469.
Tested by the original reporter Rin Okuyama on NetBSD with GCC 10.5.
Applied to master, GCC 11, GCC 12, GCC 13 after 'make all' sanity check.
Cheers,
Oleg
gcc/ChangeLog:
PR target/101469
* config/sh/sh.md (peephole2): Handle case where eliminated reg
is also used by the address of the following memory
operand.
@@ -10680,6 +10680,45 @@
&& peep2_reg_dead_p (2, operands[1]) && peep2_reg_dead_p (3, operands[0])"
[(const_int 0)]
{
+ if (MEM_P (operands[3]) && reg_overlap_mentioned_p (operands[0], operands[3]))
+ {
+ // Take care when the eliminated operand[0] register is part of
+ // the destination memory address.
+ rtx addr = XEXP (operands[3], 0);
+
+ if (REG_P (addr))
+ operands[3] = replace_equiv_address (operands[3], operands[1]);
+
+ else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
+ && CONST_INT_P (XEXP (addr, 1))
+ && REGNO (operands[0]) == REGNO (XEXP (addr, 0)))
+ operands[3] = replace_equiv_address (operands[3],
+ gen_rtx_PLUS (SImode, operands[1], XEXP (addr, 1)));
+
+ else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
+ && REG_P (XEXP (addr, 1)))
+ {
+ // register + register address @(R0, Rn)
+ // can change only the Rn in the address, not R0.
+ if (REGNO (operands[0]) == REGNO (XEXP (addr, 0))
+ && REGNO (XEXP (addr, 0)) != 0)
+ {
+ operands[3] = replace_equiv_address (operands[3],
+ gen_rtx_PLUS (SImode, operands[1], XEXP (addr, 1)));
+ }
+ else if (REGNO (operands[0]) == REGNO (XEXP (addr, 1))
+ && REGNO (XEXP (addr, 1)) != 0)
+ {
+ operands[3] = replace_equiv_address (operands[3],
+ gen_rtx_PLUS (SImode, XEXP (addr, 0), operands[1]));
+ }
+ else
+ FAIL;
+ }
+ else
+ FAIL;
+ }
+
emit_insn (gen_addsi3 (operands[1], operands[1], operands[2]));
sh_peephole_emit_move_insn (operands[3], operands[1]);
})