This is the mail archive of the gcc@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]

Re: Why does sparc build for you? or, why are make check results reported when it hasn't bootstrapped since May 5?


> The problem seems to arise in make_compound_operation/make_extraction.
> We start with (sign_extend:DI (reg:SI 32)).  make_compound_operation
> converts this to (ashiftrt:DI (ashift:DI (reg:DI 32) 32) 32).  Then
> make_extraction converts this to (sign_extend:DI (subreg:SI (reg:DI
> 32))).   We should have gotten back the same register RTL at the end
> that we had at the beginning.  Thus assuming that combine is supposed to
> work for hard registers, one of these two routines is broken.  I am
> wondering if perhaps make_compound_operation broke as a side-effect of
> simplify_gen_subreg related changes.  Or it may be that this has been
> broken for a long time.

Thanks for the analysis.

> There is curious code in make_extraction which deliberately avoids
> calling gen_lowpart, and instead explicitly makes a SUBREG.  There is a
> comment that claims we must have a SUBREG here.  Perhaps this is out
> dated.  We could try using gen_lowpart here to see if it works.  This
> will have unpredicable effect though, so it isn't clear if it is safe.
> This needs to be investigated.

This comment, I presume:

      else if (GET_CODE (inner) == REG)
	{
	  /* We can't call gen_lowpart_for_combine here since we always want
	     a SUBREG and it would sometimes return a new hard register.  */

> An alternative solution would be for combine to try to notice when it it
> has changed the size of a register, and adjust the REG_DEAD note, but I
> suspect this will be hard because we don't have easy access to the info
> we need.

Would it be sufficient anyway? Pseudo 33 would then be live on entry but not 
on exit, without being mentioned in-between.

> I looked at make_extraction more closely.  The call to
> gen_lowpart_for_combine was removed here:
>
> Sat Jun 20 06:32:11 1992  Richard Kenner  (kenner at vlsi1.ultra.nyu.edu)
>
>
>          * combine.c (make_extraction): Always ensure we have a SUBREG
> when we make a STRICT_LOW_PART.
>
> However, this code is used for both when the operand is !in_dest, and
> for the case when STRICT_LOW_PART is available.  So it looks like this
> might have been broken since the beginning.  If !in_dest is true, we
> should be able to use gen_lowpart_for_combine here, and that will fix
> the sparc build problem.  Hopefully without causing other build problems.

Clever. The attached patch indeed fixes the problem, by folding the former 
(sign_extend:DI (subreg:SI (reg:DI 32))).

Is it what you intended? If so, I'll test the patch on x86, SPARC32 and 
SPARC64 tomorrow.

-- 
Eric Botcazou
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.360
diff -c -r1.360 combine.c
*** combine.c	5 Jun 2003 13:00:14 -0000	1.360
--- combine.c	11 Jun 2003 20:15:11 -0000
***************
*** 6185,6214 ****
  	}
        else if (GET_CODE (inner) == REG)
  	{
- 	  /* We can't call gen_lowpart_for_combine here since we always want
- 	     a SUBREG and it would sometimes return a new hard register.  */
  	  if (tmode != inner_mode)
  	    {
! 	      HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
  
! 	      if (WORDS_BIG_ENDIAN
! 		  && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
! 		final_word = ((GET_MODE_SIZE (inner_mode)
! 			       - GET_MODE_SIZE (tmode))
! 			      / UNITS_PER_WORD) - final_word;
  
! 	      final_word *= UNITS_PER_WORD;
! 	      if (BYTES_BIG_ENDIAN &&
! 		  GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
! 		final_word += (GET_MODE_SIZE (inner_mode)
! 			       - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
  
! 	      /* Avoid creating invalid subregs, for example when
! 		 simplifying (x>>32)&255.  */
! 	      if (final_word >= GET_MODE_SIZE (inner_mode))
! 		return NULL_RTX;
  
! 	      new = gen_rtx_SUBREG (tmode, inner, final_word);
  	    }
  	  else
  	    new = inner;
--- 6185,6219 ----
  	}
        else if (GET_CODE (inner) == REG)
  	{
  	  if (tmode != inner_mode)
  	    {
! 	      if (in_dest)
! 		{
! 		  /* We can't call gen_lowpart_for_combine here since we always want
! 		     a SUBREG and it would sometimes return a new hard register.  */
! 		  HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
  
! 		  if (WORDS_BIG_ENDIAN
! 		      && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
! 		    final_word = ((GET_MODE_SIZE (inner_mode)
! 				   - GET_MODE_SIZE (tmode))
! 				  / UNITS_PER_WORD) - final_word;
  
! 		  final_word *= UNITS_PER_WORD;
! 		  if (BYTES_BIG_ENDIAN &&
! 		      GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
! 		    final_word += (GET_MODE_SIZE (inner_mode)
! 				   - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
  
! 		  /* Avoid creating invalid subregs, for example when
! 		     simplifying (x>>32)&255.  */
! 		  if (final_word >= GET_MODE_SIZE (inner_mode))
! 		    return NULL_RTX;
  
! 		  new = gen_rtx_SUBREG (tmode, inner, final_word);
! 		}
! 	      else
! 		new = gen_lowpart_for_combine (tmode, inner);
  	    }
  	  else
  	    new = inner;

Attachment: natFloat.cc.21.combine
Description: Text document


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