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 RFA] SH: Fix PR target/29599


Hi,

The attached patch is to fix PR target/29599
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29599
which is a 4.1/4.2/4.3 regression.  For the testcase in PR,
eliminate_regs_in_insn makes an insn like
  (set (hard-reg:SI) (const_int 0x80000008))
when replacing sfp with (sp + offset).  Then movsi_ie which
is the constant load pattern of SH errors this value out.
The patch sign-extends it in sh.c/prepare_move_operands.
I guess that if eliminate_regs_in_insn took account of the mode
of the destination, then it'll generate
  (set (hard-reg:SI) (const_int 0xffffffff80000008))
instead of the above set insn.  But even if it's not in wrong
direction, it seems to be too invasive anyway and the target
specific patch would be enough.
The patch is tested with bootstrap and the top level "make -k
check" on sh4-unknown-linux-gnu for 4.1, 4.2 and mainline with
no new failures.  OK for trunk and 4.2?

Regards,
	kaz
--
:ADDPATCH target:

	PR target/29599
	* config/sh/sh.c (prepare_move_operands): Sign-extend the value
	of const_int if needed.

diff -uprN ORIG/trunk/gcc/config/sh/sh.c LOCAL/trunk/gcc/config/sh/sh.c
--- ORIG/trunk/gcc/config/sh/sh.c	2007-02-07 08:17:12.000000000 +0900
+++ LOCAL/trunk/gcc/config/sh/sh.c	2007-02-07 09:21:34.000000000 +0900
@@ -1345,6 +1345,20 @@ prepare_move_operands (rtx operands[], e
 	}
     }
 
+  /* Reload might make move insn from const_int to a register of
+     which mode is narrower than HOST_WIDE_INT where the value of
+     const_int is out of range for that mode.  See PR 29599.  */
+  if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT
+      && GET_CODE (operands[1]) == CONST_INT)
+    {
+      unsigned int width = GET_MODE_BITSIZE (mode);
+      HOST_WIDE_INT val = INTVAL (operands[1]);
+
+      val &= ((HOST_WIDE_INT) 1 << width) - 1;
+      if (val & ((HOST_WIDE_INT) 1 << (width - 1)))
+	operands[1] = GEN_INT (((HOST_WIDE_INT) (-1) << width) | val);
+    }
+
   return 0;
 }
 


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