]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
SH: Fix PR101469 peephole bug
authorOleg Endo <olegendo@gcc.gnu.org>
Fri, 14 Jul 2023 00:54:20 +0000 (09:54 +0900)
committerOleg Endo <olegendo@gcc.gnu.org>
Fri, 14 Jul 2023 01:44:55 +0000 (10:44 +0900)
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

index e3af9ae21c1dccb40fa07401ba30357fa085784d..963984060e68bee0ab35531701536fabec7e3f40 100644 (file)
    && 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]);
 })