diff mbox

[SH,committed] Fix PR 68277

Message ID 1447683928.2230.108.camel@t-online.de
State New
Headers show

Commit Message

Oleg Endo Nov. 16, 2015, 2:25 p.m. UTC
Hi,

The attached patch fixes PR 68277.
Tested by Kaz on trunk on sh4-linux.  I've also done a sanity check on
GCC 5 branch with "make all" on sh-elf.

Committed to trunk as r230425 and to GCC 5 branch as r230426.

Cheers,
Oleg

gcc/ChangeLog:
	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.
diff mbox

Patch

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 230158)
+++ gcc/config/sh/sh.md	(working copy)
@@ -2232,11 +2232,51 @@ 
 	}
     }
   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")
 		 (match_operand:SI 2 "arith_operand" "rI08,Z")))]