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]

reload_cse_move2add generates invalid insn


Given the following sequence of insns:

(insn 7514 6572 4516 (set (reg:SI 0 %d0)
        (reg/v:SI 3 %d3)) 42 {movsi+1} (nil)
    (nil))

(insn/i 4516 7514 7517 (set (reg:SI 0 %d0)
        (plus:SI (reg:SI 0 %d0)
            (const_int -65377 [0xffff009f]))) 126 {*addsi3_internal} (nil)
    (nil))

(insn 7517 4516 4517 (set (reg:SI 2 %d2)
        (const_int 62 [0x3e])) 42 {movsi+1} (nil)
    (nil))

(insn/i:QI 4517 7517 4518 (set (cc0)
        (compare (reg:SI 0 %d0)
            (reg:SI 2 %d2))) 19 {cmpsi+1} (insn_list 4516 (nil))
    (nil))

(jump_insn/i 4518 4517 6573 (set (pc)
        (if_then_else (gtu (cc0)
                (const_int 0 [0x0]))
            (label_ref 4535)
            (pc))) 386 {bgtu} (nil)
    (nil))

(note 6573 4518 7519 [bb 849] NOTE_INSN_BASIC_BLOCK)

(insn 7519 6573 4519 (set (reg/v:QI 0 %d0)
        (reg:QI 3 %d3)) 51 {movqi+1} (nil)
    (nil))

(insn/i 4519 7519 4529 (set (reg/v:QI 0 %d0)
        (plus:QI (reg/v:QI 0 %d0)
            (const_int 64 [0x40]))) 132 {addqi3} (nil)
    (nil))

the post-reload cse pass replaces the last two insn with the following
one:

(insn/i 4519 7519 4529 (set (reg/v:QI 0 %d0)
        (plus:QI (reg/v:QI 0 %d0)
            (const_int 65441 [0xffa1]))) 132 {addqi3} (nil)
    (nil))

Currently all of the patterns in m68k.md assume that any CONST_INT operand
is strictly within the range of the respective mode, and the assembler
will barf when trying to assemble `add.b #65185,%d0'.


1999-05-02  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

	* reload1.c (gen_mode_int): New function.
	(reload_cse_move2add): Use it to generate the new constants.

--- egcs-2.93/gcc/reload1.c.~1~	Mon Apr 19 18:38:14 1999
+++ egcs-2.93/gcc/reload1.c	Sun May  2 23:23:26 1999
@@ -9962,6 +9962,24 @@
    reload_cse_move2add and move2add_note_store.  */
 static int move2add_luid;
 
+/* Generate a CONST_INT and force it in the range of MODE.  */
+static rtx
+gen_mode_int (mode, value)
+     enum machine_mode mode;
+     HOST_WIDE_INT value;
+{
+  HOST_WIDE_INT cval = value & GET_MODE_MASK (mode);
+  int width = GET_MODE_BITSIZE (mode);
+
+  /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative number,
+     sign extend it.  */
+  if (width > 0 && width < HOST_BITS_PER_WIDE_INT
+      && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
+    cval |= (HOST_WIDE_INT) -1 << width;
+
+  return GEN_INT (cval);
+}
+
 static void
 reload_cse_move2add (first)
      rtx first;
@@ -10013,8 +10031,9 @@
 	      if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
 		{
 		  int success = 0;
-		  rtx new_src = GEN_INT (INTVAL (src)
-					 - INTVAL (reg_offset[regno]));
+		  rtx new_src
+		    = gen_mode_int (GET_MODE (reg),
+				    INTVAL (src) - INTVAL (reg_offset[regno]));
 		  /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
 		     use (set (reg) (reg)) instead.
 		     We don't delete this insn, nor do we convert it into a
@@ -10059,8 +10078,10 @@
 		      && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
 		    {
 		      rtx src3 = XEXP (SET_SRC (set), 1);
-		      rtx new_src = GEN_INT (INTVAL (src3)
-					     - INTVAL (reg_offset[regno]));
+		      rtx new_src
+			= gen_mode_int (GET_MODE (reg),
+					INTVAL (src3)
+					- INTVAL (reg_offset[regno]));
 		      int success = 0;
 
 		      if (new_src == const0_rtx)

-- 
Andreas Schwab                                      "And now for something
schwab@issan.cs.uni-dortmund.de                      completely different"
schwab@gnu.org


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