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]

Another patch to prevent invalid subreg generation (fwd)


I'm resubmitting this again since nobody seemed to want to comment on
it.

It prevents an ICE when compiling  for d10v.


typedef union
{
  unsigned char member3;
  signed short member4;
  unsigned int member5;
}
UNI02;

struct srt_dat_t
{
  UNI02 un2;
  unsigned long member1;
  signed short member2;
};

struct srt_dat_t exsrt1;
void
extern_test (struct srt_dat_t arg1)
{
  arg1.un2.member3++;
  arg1.member1++;
  arg1.member2++;
}

int
main (void)
{
  extern_test (exsrt1);
  return (0);
}

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299
--- Begin Message ---


This is a similar patch to the one that Geoff Keating applied
to extract_bit_field. It prevents the generation of
invalid SUBREGs in some cases.

Bootstrapped on i686 and ppc without any regressions.

2001-11-30 Alan Matsuoka <alanm@redhat.com>

	* expmed.c (store_bit_field): Don't create invalid SUBREGs.

Index: gcc/expmed.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/expmed.c,v
retrieving revision 1.163
diff -d -c -p -r1.163 expmed.c
*** expmed.c	2001/11/26 01:12:24	1.163
--- expmed.c	2001/12/11 14:47:43
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 299,304 ****
--- 299,305 ----
    unsigned HOST_WIDE_INT offset = bitnum / unit;
    unsigned HOST_WIDE_INT bitpos = bitnum % unit;
    rtx op0 = str_rtx;
+   int byte_offset;
  
    enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
  
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 332,338 ****
       If the target is memory, storing any naturally aligned field can be
       done with a simple store.  For targets that support fast unaligned
       memory, any naturally sized, unit aligned field can be done directly.  */
!      
    if (bitpos == 0
        && bitsize == GET_MODE_BITSIZE (fieldmode)
        && (GET_CODE (op0) != MEM
--- 333,342 ----
       If the target is memory, storing any naturally aligned field can be
       done with a simple store.  For targets that support fast unaligned
       memory, any naturally sized, unit aligned field can be done directly.  */
! 
!   byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
!               + (offset * UNITS_PER_WORD);
! 
    if (bitpos == 0
        && bitsize == GET_MODE_BITSIZE (fieldmode)
        && (GET_CODE (op0) != MEM
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 342,371 ****
  	     || (offset * BITS_PER_UNIT % bitsize == 0
  		 && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
      {
!       if (GET_MODE (op0) != fieldmode)
! 	{
! 	  if (GET_CODE (op0) == SUBREG)
! 	    {
! 	      if (GET_MODE (SUBREG_REG (op0)) == fieldmode
! 		  || GET_MODE_CLASS (fieldmode) == MODE_INT
! 		  || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
! 		op0 = SUBREG_REG (op0);
! 	      else
! 		/* Else we've got some float mode source being extracted into
! 		   a different float mode destination -- this combination of
! 		   subregs results in Severe Tire Damage.  */
! 		abort ();
  	    }
! 	  if (GET_CODE (op0) == REG)
! 	    op0 = gen_rtx_SUBREG (fieldmode, op0,
! 				  (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
! 				  + (offset * UNITS_PER_WORD));
! 	  else
! 	    op0 = adjust_address (op0, fieldmode, offset);
! 	}
!       emit_move_insn (op0, value);
!       return value;
!     }
  
    /* Make sure we are playing with integral modes.  Pun with subregs
       if we aren't.  This must come after the entire register case above,
--- 346,376 ----
  	     || (offset * BITS_PER_UNIT % bitsize == 0
  		 && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
      {
!       if (byte_offset % GET_MODE_SIZE (fieldmode) == 0)
!         {
!           if (GET_MODE (op0) != fieldmode)
!             {
! 	      if (GET_CODE (op0) == SUBREG)
! 	        {
! 	          if (GET_MODE (SUBREG_REG (op0)) == fieldmode
! 	           || GET_MODE_CLASS (fieldmode) == MODE_INT
! 	           || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
! 	            op0 = SUBREG_REG (op0);
! 	          else
! 	           /* Else we've got some float mode source being extracted into
! 	              a different float mode destination -- this combination of
! 	              subregs results in Severe Tire Damage.  */
! 	            abort ();
! 	        }
! 	        if (GET_CODE (op0) == REG)
! 	          op0 = gen_rtx_SUBREG (fieldmode, op0, byte_offset);
! 	        else
! 	          op0 = adjust_address (op0, fieldmode, offset);
  	    }
!           emit_move_insn (op0, value);
!           return value;
!        }
!   }
  
    /* Make sure we are playing with integral modes.  Pun with subregs
       if we aren't.  This must come after the entire register case above,

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299
--- End Message ---

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