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]

Re: GCC build failed for powerpc-eabisim with your patch on 2001-06-04T15:31:45Z.


> With your recent patch, GCC does not compile on:
>  powerpc-eabisim
> /maat/heart/tbox/cvs-gcc/gcc/gcc/libgcc2.c: In function `__gcc_bcmp':
> /maat/heart/tbox/cvs-gcc/gcc/gcc/libgcc2.c:1233: Internal compiler error in gen_lowpart, at emit-rtl.c:1110
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.

This is latent bug caught by my checking code.
Basically we do SImode lowpart of (subreg:QI (reg:SI) 3).
The second is already lowpart of SImode value, so the result should be (reg:SI),
but most of the code combines offsets by adding the offsets.  This is not
true for paradoxical subregs on big endian machines in our current representation.

To simplify_subreg I've copied code that seemed to handle, but it is not correct,
as it checks only old subreg to be paradoxical, so I've rewrote the code to cleaner
form and I've checked that it fixes the problem.

I am now running i386 checking, but it is mostly useless, as the code in
question triggers only for big endian.

OK assuming it passes?
(it makes gcc to compile few randomly choosen PPC files, that seems to be
good test given the amount of sanity checking I do have)

Mon Jun  4 19:46:00 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* simplify-rtx.c (simplify_subreg): Fix combining of
	paradoxical subregs.

Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/simplify-rtx.c,v
retrieving revision 1.56
diff -c -3 -p -r1.56 simplify-rtx.c
*** simplify-rtx.c	2001/06/04 14:52:14	1.56
--- simplify-rtx.c	2001/06/04 17:45:22
*************** simplify_subreg (outermode, op, innermod
*** 2297,2337 ****
    if (GET_CODE (op) == SUBREG)
      {
        enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
!       unsigned int final_offset = byte + SUBREG_BYTE (op);
        rtx new;
  
        if (outermode == innermostmode
  	  && byte == 0 && SUBREG_BYTE (op) == 0)
  	return SUBREG_REG (op);
  
!       if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
! 	  && GET_MODE_SIZE (innermode) > GET_MODE_SIZE (outermode)
! 	  && GET_MODE_SIZE (innermode) > GET_MODE_SIZE (innermostmode))
  	{
! 	  /* Inner SUBREG is paradoxical, outer is not.  On big endian
! 	     we have to special case this.  */
! 	  if (SUBREG_BYTE (op))
! 	    abort(); /* Can a paradoxical subreg have nonzero offset? */
! 	  if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
! 	    final_offset = (byte - GET_MODE_SIZE (innermode)
! 			    + GET_MODE_SIZE (innermostmode));
! 	  else if (WORDS_BIG_ENDIAN)
! 	    final_offset = ((final_offset % UNITS_PER_WORD)
! 			    + ((byte - GET_MODE_SIZE (innermode)
! 			        + GET_MODE_SIZE (innermostmode))
! 			       * UNITS_PER_WORD) / UNITS_PER_WORD);
  	  else
! 	    final_offset = (((final_offset * UNITS_PER_WORD)
! 			     / UNITS_PER_WORD)
! 			    + ((byte - GET_MODE_SIZE (innermode)
! 			        + GET_MODE_SIZE (innermostmode))
! 			       % UNITS_PER_WORD));
  	}
  
-       /* Bail out in case resulting subreg would be incorrect.  */
-       if (final_offset % GET_MODE_SIZE (outermode)
- 	  || final_offset >= GET_MODE_SIZE (innermostmode))
- 	return NULL;
        /* Recurse for futher possible simplifications.  */
        new = simplify_subreg (outermode, SUBREG_REG (op),
  			     GET_MODE (SUBREG_REG (op)),
--- 2297,2359 ----
    if (GET_CODE (op) == SUBREG)
      {
        enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
!       int final_offset = byte + SUBREG_BYTE (op);
        rtx new;
  
        if (outermode == innermostmode
  	  && byte == 0 && SUBREG_BYTE (op) == 0)
  	return SUBREG_REG (op);
  
!       /* The SUBREG_BYTE represents offset, as if the value were stored
! 	 in memory.  Irritating exception is paradoxical subreg, where
! 	 we define SUBREG_BYTE to be 0.  On big endian machines, this
! 	 value should be negative.  For a moment, undo this exception. */
!       if (byte == 0 && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
  	{
! 	  int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
! 	  if (WORDS_BIG_ENDIAN)
! 	    final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
! 	  if (BYTES_BIG_ENDIAN)
! 	    final_offset += difference % UNITS_PER_WORD;
! 	}
!       if (SUBREG_BYTE (op) == 0
! 	  && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
! 	{
! 	  int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
! 	  if (WORDS_BIG_ENDIAN)
! 	    final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
! 	  if (BYTES_BIG_ENDIAN)
! 	    final_offset += difference % UNITS_PER_WORD;
! 	}
! 
!       /* See whether resulting subreg will be paradoxical.  */
!       if (GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (outermode))
! 	{
! 	  /* In nonparadoxical subregs we can't handle negative offsets.  */
! 	  if (final_offset < 0)
! 	    return NULL_RTX;
! 	  /* Bail out in case resulting subreg would be incorrect.  */
! 	  if (final_offset % GET_MODE_SIZE (outermode)
! 	      || final_offset >= GET_MODE_SIZE (innermostmode))
! 	    return NULL;
! 	}
!       else
! 	{
! 	  int offset = 0;
! 	  int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (outermode));
! 
! 	  /* In paradoxical subreg, see if we are still looking on lower part.
! 	     If so, our SUBREG_BYTE will be 0.  */
! 	  if (WORDS_BIG_ENDIAN)
! 	    offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
! 	  if (BYTES_BIG_ENDIAN)
! 	    offset += difference % UNITS_PER_WORD;
! 	  if (offset == final_offset)
! 	    final_offset = 0;
  	  else
! 	    return NULL;
  	}
  
        /* Recurse for futher possible simplifications.  */
        new = simplify_subreg (outermode, SUBREG_REG (op),
  			     GET_MODE (SUBREG_REG (op)),


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