re PR target/68277 ([SH]: error: insn does not satisfy its constraints when compiling...
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 16 Nov 2015 14:11:50 +0000 (14:11 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 16 Nov 2015 14:11:50 +0000 (14:11 +0000)
gcc/
PR target/68277
* config/sh/sh.md (addsi3_scr): Handle reg overlap of operands[0] and
operands[2].
(*addsi3): Add another insn_and_split variant for reload.

Co-Authored-By: Kaz Kojima <kkojima@gcc.gnu.org>
From-SVN: r230425

gcc/ChangeLog
gcc/config/sh/sh.md

index 2bba1191da2af5c722ec185c6b866def3865a12d..aabed12bb03ee8249390bb80a387d8b9d2d34c94 100644 (file)
@@ -1,3 +1,11 @@
+2015-11-16  Oleg Endo  <olegendo@gcc.gnu.org>
+           Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       PR target/68277
+       * config/sh/sh.md (addsi3_scr): Handle reg overlap of operands[0] and
+       operands[2].
+       (*addsi3): Add another insn_and_split variant for reload.
+
 2015-11-16  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/68117
index 5c748cee7304e264e55b3e79f5b32c4dfb3c4850..083febe595426a10961b4af488a2bf7c959ee842 100644 (file)
        }
     }
   else if (!reg_overlap_mentioned_p (operands[0], operands[1]))
-    emit_move_insn (operands[0], operands[1]);
+    {
+      if (!reg_overlap_mentioned_p (operands[0], operands[2]))
+       emit_move_insn (operands[0], operands[1]);
+      else
+       operands[2] = operands[1];
+    }
 }
   [(set_attr "type" "arith")])
 
+;; Old reload might generate add insns directly (not through the expander) for
+;; the memory address of complex insns like atomic insns when reloading.
+(define_insn_and_split "*addsi3"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
+                (match_operand:SI 2 "arith_or_int_operand" "rn")))]
+  "TARGET_SH1 && !sh_lra_p ()
+   && reload_completed
+   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+  "#"
+  "&& 1"
+  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
+{
+  if (operands[2] == const0_rtx)
+    {
+      emit_move_insn (operands[0], operands[1]);
+      DONE;
+    }
+
+  if (CONST_INT_P (operands[2]))
+    {
+      if (satisfies_constraint_I08 (operands[2]))
+       emit_move_insn (operands[0], operands[1]);
+      else
+       {
+         emit_move_insn (operands[0], operands[2]);
+         operands[2] = operands[1];
+       }
+    }
+  else if (!reg_overlap_mentioned_p (operands[0], operands[2]))
+    emit_move_insn (operands[0], operands[1]);
+  else
+    operands[2] = operands[1];
+})
+
 (define_insn_and_split "*addsi3"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
        (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")