From 4dbb3af1efe55174a714d15c2994cf2842ef8c28 Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Fri, 14 Jul 2023 09:54:20 +0900 Subject: [PATCH] SH: Fix PR101496 peephole bug 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. --- gcc/config/sh/sh.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 5cb179548256..484a34fe4438 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -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]); }) -- 2.47.2