This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, PR61446] Fix mode for register copy in REE pass


Hi,

This patch fixes PR61446.  The problem appears when we insert value copies after transformations. We use the widest extension mode met in a chain, but it may be wider than original destination register size.  This patch checks it and use smaller mode if required.

Bootstrapped and tested on linux-x86_64.

Does it look OK?

Thanks,
Ilya
--
2014-06-09  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR 61446
	* ree.c (find_and_remove_re): Narrow mode for register copy
	if required.

diff --git a/gcc/ChangeLog.pr61446 b/gcc/ChangeLog.pr61446
new file mode 100644
index 0000000..b9e2148
--- /dev/null
+++ b/gcc/ChangeLog.pr61446
@@ -0,0 +1,5 @@
+2014-06-09  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+	PR 61446
+	* ree.c (find_and_remove_re): Narrow mode for register copy
+	if required.
diff --git a/gcc/ree.c b/gcc/ree.c
index ade413e..6d34764 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -1088,14 +1088,24 @@ find_and_remove_re (void)
       /* Use the mode of the destination of the defining insn
 	 for the mode of the copy.  This is necessary if the
 	 defining insn was used to eliminate a second extension
-	 that was wider than the first.  */
+	 that was wider than the first.  Truncate mode if it is
+	 too wide for destination reg.  */
       rtx sub_rtx = *get_sub_rtx (def_insn);
       rtx pat = PATTERN (curr_insn);
-      rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
-				 REGNO (XEXP (SET_SRC (pat), 0)));
-      rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
-				 REGNO (SET_DEST (pat)));
-      rtx set = gen_rtx_SET (VOIDmode, new_dst, new_src);
+      unsigned int regno = REGNO (XEXP (SET_SRC (pat), 0));
+      enum machine_mode mode = GET_MODE (SET_DEST (sub_rtx));
+      rtx new_dst, new_src, set;
+
+      if (HARD_REGNO_NREGS (regno, mode) != 1)
+	{
+	  mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode));
+	  while (HARD_REGNO_NREGS (regno, GET_MODE_WIDER_MODE (mode)) == 1)
+	    mode = GET_MODE_WIDER_MODE (mode);
+	}
+
+      new_dst = gen_rtx_REG (mode, REGNO (XEXP (SET_SRC (pat), 0)));
+      new_src = gen_rtx_REG (mode, REGNO (SET_DEST (pat)));
+      set = gen_rtx_SET (VOIDmode, new_dst, new_src);
       emit_insn_after (set, def_insn);
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]