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] combine.c: Fix execute/0021120-2.c and execute/941101-1.c.


Hi,

The attached is a patch to fix regressions caused by

http://gcc.gnu.org/ml/gcc-patches/2003-03/msg02597.html

Specifically, on H8, the patch causes execute/20021120-2.c and
execute/941101-1.c to fail at compile time.

Consider the following, derived from 941101-1.c.

/* h8300-hms-gcc -mh -O2 */
int
foo ()
{
  int var = 7;
  return var / 7;
}

After the life analysis, we have:

(set (reg:SI 22)
     (const_int 7))

(set (reg:HI 23)
     (subreg:HI (reg:SI 22) 2))

(parallel
 [(set (reg:HI 20)
       (truncate:HI (div:SI (reg:SI 22)
			    (sign_extend:SI (reg:HI 23)))))
  (set (reg:HI 21)
       (truncate:HI (mod:SI (reg:SI 22)
			    (sign_extend:SI (reg:HI 23)))))])

(set (reg/i:HI 0) <- this (reg 0) is the return value register
     (reg:HI 20))

With the patch, the combiner outputs

(set (subreg:SI (reg:HI 21) 0) <- This code is redundant.
     (const_int 0))               The result of mod:SI is not used.

(set (subreg:SI (reg:HI 20) 0)
     (const_int 1))

(set (reg/i:HI 0 r0)
     (reg:HI 20))

and I see

941101-1.c: In function `foo':
941101-1.c:6: internal compiler error: in find_free_reg, at local-alloc.c:2185

local-alloc does not seem to like

  (set (subreg:SI (...) 0) (const_int))

which I don't think is valid on a machine without
WORD_REGISTER_OPERATIONS because of

http://gcc.gnu.org/ml/gcc/2003-06/msg00111.html
http://gcc.gnu.org/ml/gcc/2003-06/msg00115.html

The patch avoids creating a paradoxical subreg as a SET_DEST.  With
the patch, the combiner outputs

(set (reg:HI 20)
     (const_int 1))

(set (reg/i:HI 0)
     (reg:HI 20))

Tested on h8300 port.  OK to apply?

Kazu Hirata

2003-06-02  Kazu Hirata  <kazu@cs.umass.edu>

	* combine.c (simplify_set): Don't move a subreg in SET_SRC to
	SET_DEST if WORD_REGISTER_OPERATIONS is not defined.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.358
diff -u -9 -r1.358 combine.c
--- combine.c	16 May 2003 02:05:29 -0000	1.358
+++ combine.c	2 Jun 2003 14:17:45 -0000
@@ -5232,57 +5232,55 @@
     }
   else
     {
       /* Get SET_SRC in a form where we have placed back any
 	 compound expressions.  Then do the checks below.  */
       src = make_compound_operation (src, SET);
       SUBST (SET_SRC (x), src);
     }
 
+#ifdef WORD_REGISTER_OPERATIONS
   /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
      and X being a REG or (subreg (reg)), we may be able to convert this to
      (set (subreg:m2 x) (op)).
 
      We can always do this if M1 is narrower than M2 because that means that
      we only care about the low bits of the result.
 
      However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
      perform a narrower operation than requested since the high-order bits will
      be undefined.  On machine where it is defined, this transformation is safe
      as long as M1 and M2 have the same number of words.  */
 
   if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
       && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o'
       && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
 	   / UNITS_PER_WORD)
 	  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
 	       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
-#ifndef WORD_REGISTER_OPERATIONS
-      && (GET_MODE_SIZE (GET_MODE (src))
-	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
-#endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
 	    && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
 					 GET_MODE (SUBREG_REG (src)),
 					 GET_MODE (src)))
 #endif
       && (GET_CODE (dest) == REG
 	  || (GET_CODE (dest) == SUBREG
 	      && GET_CODE (SUBREG_REG (dest)) == REG)))
     {
       SUBST (SET_DEST (x),
 	     gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)),
 				      dest));
       SUBST (SET_SRC (x), SUBREG_REG (src));
 
       src = SET_SRC (x), dest = SET_DEST (x);
     }
+#endif
 
 #ifdef HAVE_cc0
   /* If we have (set (cc0) (subreg ...)), we try to remove the subreg
      in SRC.  */
   if (dest == cc0_rtx
       && GET_CODE (src) == SUBREG
       && subreg_lowpart_p (src)
       && (GET_MODE_BITSIZE (GET_MODE (src))
 	  < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src)))))


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