Patchwork RFT: Fix PR middle/end-40154

login
register
mail settings
Submitter Joern Rennecke
Date Nov. 8, 2011, 1:11 p.m.
Message ID <20111108081145.k697g6oymos8c4so-nzlynne@webmail.spamcop.net>
Download mbox | patch
Permalink /patch/124360/
State New
Headers show

Comments

Joern Rennecke - Nov. 8, 2011, 1:11 p.m.
Quoting Kaz Kojima <kkojima@rr.iij4u.or.jp>:

> It seems that find_reloads calls set_unique_reg_note for
> a USE insn.

That's true, and it is by design.
This use of set_unique_reg_note is a bit debatable - add_reg_note
should do just fine there.

OTOH keeping this as it is, and keeping set_unique_reg_note accepting USE
in this case, seems more conservative for stage3.
2011-11-07  Joern Rennecke  <joern.rennecke@embecosm.com>

	* emit-rtl.c (set_unique_reg_note): Don't add notes that disagree
	with the SET_DEST of INSN.

Patch

Index: trunk/gcc/emit-rtl.c
===================================================================
--- trunk/gcc/emit-rtl.c	(revision 181122)
+++ trunk/gcc/emit-rtl.c	(working copy)
@@ -4951,8 +4951,32 @@ 
 rtx
 set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
 {
-  rtx note = find_reg_note (insn, kind, NULL_RTX);
+  rtx set, note;
+  enum machine_mode mode;
 
+  /* Sometimes the value is calculated with some SUBREG tricks, so the
+     SET_DEST of INSN ends up with a different mode then DATUM.  */
+  set = single_set (insn);
+  if (set)
+    {
+      mode = GET_MODE (SET_DEST (set));
+      /* If DATUM is too narrow, we can't make it fit.  */
+      if ((GET_MODE (datum) != VOIDmode || GET_MODE_CLASS (mode) != MODE_INT)
+	  && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (datum)))
+	return NULL_RTX;
+      if (GET_MODE (datum) != VOIDmode && GET_MODE (datum) != mode)
+	{
+	  /* Adjust DATUM to the SET_DEST.  */
+	  datum = simplify_gen_subreg (mode, datum, GET_MODE (datum), 0);
+	  if (!datum)
+	    return NULL_RTX;
+	}
+    }
+  else /* Reload uses USEs with REG_EQUAL notes attached to keep track of
+	  reload inhertiance opportunities.  */
+    gcc_assert (PATTERN (insn) == USE && reload_in_progress);
+  note = find_reg_note (insn, kind, NULL_RTX);
+
   switch (kind)
     {
     case REG_EQUAL: