re PR target/67657 ([SH][5/6 Regression]: internal compiler error: in cselib_record_s...
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 21 Sep 2015 12:57:31 +0000 (12:57 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 21 Sep 2015 12:57:31 +0000 (12:57 +0000)
gcc/
PR target/67657
* config/sh/sh.c (sh_remove_overlapping_post_inc,
sh_peephole_emit_move_insn): Add new functions.
* config/sh/sh-protos.h (sh_remove_overlapping_post_inc,
sh_peephole_emit_move_insn): Declere them.
* config/sh/sh.md: Use them in various peephole2 patterns.

From-SVN: r227969

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.md

index 246237b78c6440c77b355745e8d181a2dbf14a9d..bf688962b9773045713448da3d18097c12c94883 100644 (file)
@@ -1,3 +1,12 @@
+2015-09-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/67657
+       * config/sh/sh.c (sh_remove_overlapping_post_inc,
+       sh_peephole_emit_move_insn): Add new functions.
+       * config/sh/sh-protos.h (sh_remove_overlapping_post_inc,
+       sh_peephole_emit_move_insn): Declere them.
+       * config/sh/sh.md: Use them in various peephole2 patterns.
+
 2015-09-21  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/67651
index bb7003c18cde3fc6faa2c90bf841f95d6c794968..916fe044ed60ad6d444bbb5247464125bc673891 100644 (file)
@@ -306,6 +306,8 @@ extern bool sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
 extern bool sh_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno);
 extern void sh_remove_reg_dead_or_unused_notes (rtx_insn* i, int regno);
 extern rtx_insn* sh_check_add_incdec_notes (rtx_insn* i);
+extern rtx sh_remove_overlapping_post_inc (rtx dst, rtx src);
+extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src);
 
 extern bool sh_in_recog_treg_set_expr (void);
 extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
index ec0abc59a8bddfb667c884e2d4908ce70a345f91..3b83dcc11cf5f720948314dfb3afebacd8fa759e 100644 (file)
@@ -13810,6 +13810,34 @@ sh_check_add_incdec_notes (rtx_insn* i)
   return i;
 }
 
+/* Given a move insn destiation and a source, make sure that the move source
+   operand is not a post-inc mem load with the same address reg as the
+   destination.  Returns the modified source operand with the post-inc removed
+   if necessary.  */
+rtx
+sh_remove_overlapping_post_inc (rtx dst, rtx src)
+{
+  if (!MEM_P (src))
+    return src;
+
+  rtx addr = XEXP (src, 0);
+
+  if (GET_CODE (addr) == POST_INC
+      && reg_overlap_mentioned_p (XEXP (addr, 0), dst))
+    return replace_equiv_address (src, XEXP (addr, 0));
+
+  gcc_assert (GET_CODE (addr) != POST_MODIFY);
+  return src;
+}
+
+/* Emit a move insn that is safe to be used in peephole patterns.  */
+rtx_insn*
+sh_peephole_emit_move_insn (rtx dst, rtx src)
+{
+  return sh_check_add_incdec_notes (
+       emit_move_insn (dst, sh_remove_overlapping_post_inc (dst, src)));
+}
+
 /* Given an op rtx and an insn, try to find out whether the result of the
    specified op consists only of logical operations on T bit stores.  */
 bool
index e0fc90368eef9d7f020dc0ef569ebb212cabe4c9..f3f68c6b45ddd37125e46b568c33b8c8d049acb9 100644 (file)
@@ -14681,7 +14681,7 @@ label:
   [(const_int 0)]
 {
   emit_insn (gen_addsi3 (operands[1], operands[1], operands[2]));
-  sh_check_add_incdec_notes (emit_move_insn (operands[3], operands[1]));
+  sh_peephole_emit_move_insn (operands[3], operands[1]);
 })
 
 ;;     mov.l   @(r0,r9),r1
@@ -14694,7 +14694,7 @@ label:
   "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
   [(const_int 0)]
 {
-  sh_check_add_incdec_notes (emit_move_insn (operands[2], operands[1]));
+  sh_peephole_emit_move_insn (operands[2], operands[1]);
 })
 
 (define_peephole2
@@ -14705,7 +14705,7 @@ label:
   "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
   [(const_int 0)]
 {
-  sh_check_add_incdec_notes (emit_move_insn (operands[2], operands[1]));
+  sh_peephole_emit_move_insn (operands[2], operands[1]);
 })
 
 (define_peephole2
@@ -14717,7 +14717,7 @@ label:
   [(const_int 0)]
 {
   sh_check_add_incdec_notes (emit_insn (gen_extend<mode>si2 (operands[2],
-                                                            operands[1])));
+                  sh_remove_overlapping_post_inc (operands[2], operands[1]))));
 })
 
 ;;     mov.w   @(18,r1),r0 (r0 = HImode)
@@ -14747,8 +14747,9 @@ label:
 
   // We don't know what the new set insn will be in detail.  Just make sure
   // that it still can be recognized and the constraints are satisfied.
-  rtx_insn* i = emit_insn (gen_rtx_SET (operands[2], operands[3]));
-                                                    
+  rtx_insn* i = emit_insn (gen_rtx_SET (operands[2],
+                   sh_remove_overlapping_post_inc (operands[2], operands[3])));
+
   recog_data_d prev_recog_data = recog_data;
   bool i_invalid = insn_invalid_p (i, false); 
   recog_data = prev_recog_data;
@@ -14786,7 +14787,8 @@ label:
 {
   // We don't know what the new set insn will be in detail.  Just make sure
   // that it still can be recognized and the constraints are satisfied.
-  rtx_insn* i = emit_insn (gen_rtx_SET (operands[2], operands[3]));
+  rtx_insn* i = emit_insn (gen_rtx_SET (operands[2],
+                   sh_remove_overlapping_post_inc (operands[2], operands[3])));
 
   recog_data_d prev_recog_data = recog_data;
   bool i_invalid = insn_invalid_p (i, false);