public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jan Hubicka <jh@suse.cz>
To: Eric Botcazou <ebotcazou@libertysurf.fr>,
	gcc-patches@gcc.gnu.org, rth@redhat.com
Cc: Jan Hubicka <jh@suse.cz>, gcc@gcc.gnu.org
Subject: Make reload to avoid invalid subregs
Date: Sat, 12 Apr 2003 17:55:00 -0000	[thread overview]
Message-ID: <20030412145257.GF31150@kam.mff.cuni.cz> (raw)
In-Reply-To: <200304121554.30377.ebotcazou@libertysurf.fr>

Hi,
this patch should fix number of PRs related to invalid subregs
(like (subreg:SI (xmm) 4)) and reloads that often leads to silent
misscompilations.  New function subreg_representable_p is introduced
to verify all constraints under wich we would produce wrong code
and reload now deals with it.  Some code already did exist in reload to
cope with this but part of it was ifdeffed out by Dave and the other
part is still SUBREG_WORD centric.  I would like to remove it in
followup patch but would like to do so step by step.

Bootstrapped/regtested mainline on i386 and PPC
Ok for mainline/3.3/3.2?

Honza

Sat Apr 12 07:47:53 MST 2003  Jan Hubicka  <jh@suse.cz>
			      Eric Botcazou
	* emit-rtl.c (subreg_hard_regno): Check subreg_offset_representable_p
	* reload.c (reload_inner_reg_of_subreg): Likewise.
	(find_reloads): Likewise; remove #if 0 hunk we replace.
	* rtl.h (subreg_representable_p): Declare.
	* rtlanal.c (subreg_representable_p): New function.
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.303
diff -c -3 -p -r1.303 emit-rtl.c
*** emit-rtl.c	20 Nov 2002 21:52:58 -0000	1.303
--- emit-rtl.c	12 Apr 2003 14:46:26 -0000
*************** subreg_hard_regno (x, check_mode)
*** 925,931 ****
      abort ();
    if (check_mode && ! HARD_REGNO_MODE_OK (base_regno, GET_MODE (reg)))
      abort ();
! 
    /* Catch non-congruent offsets too.  */
    byte_offset = SUBREG_BYTE (x);
    if ((byte_offset % GET_MODE_SIZE (mode)) != 0)
--- 925,935 ----
      abort ();
    if (check_mode && ! HARD_REGNO_MODE_OK (base_regno, GET_MODE (reg)))
      abort ();
! #ifdef ENABLE_CHECKING
!   if (!subreg_offset_representable_p (REGNO (reg), GET_MODE (reg),
! 			  	      SUBREG_BYTE (x), mode))
!     abort ();
! #endif
    /* Catch non-congruent offsets too.  */
    byte_offset = SUBREG_BYTE (x);
    if ((byte_offset % GET_MODE_SIZE (mode)) != 0)
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.199.2.6
diff -c -3 -p -r1.199.2.6 reload.c
*** reload.c	26 Mar 2003 07:53:57 -0000	1.199.2.6
--- reload.c	12 Apr 2003 14:46:27 -0000
*************** reload_inner_reg_of_subreg (x, mode, out
*** 819,824 ****
--- 819,831 ----
        || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
      return 0;
  
+   if (!subreg_offset_representable_p
+ 	(REGNO (SUBREG_REG (x)),
+ 		GET_MODE (SUBREG_REG (x)),
+ 		SUBREG_BYTE (x),
+ 		GET_MODE (x)))
+     return 1;
+ 
    /* If INNER is not ok for MODE, then INNER will need reloading.  */
    if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
      return 1;
*************** find_reloads (insn, replace, ind_levels,
*** 2869,2874 ****
--- 2876,2887 ----
  	      if (GET_CODE (SUBREG_REG (operand)) == REG
  		  && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
  		{
+ 		  if (!subreg_offset_representable_p
+ 			(REGNO (SUBREG_REG (operand)),
+ 			 GET_MODE (SUBREG_REG (operand)),
+ 			 SUBREG_BYTE (operand),
+ 			 GET_MODE (operand)))
+ 		     force_reload = 1;
  		  offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
  						 GET_MODE (SUBREG_REG (operand)),
  						 SUBREG_BYTE (operand),
*************** find_reloads (insn, replace, ind_levels,
*** 2924,2949 ****
  			  )
  #endif
  		      )
- 		  /* This following hunk of code should no longer be
- 		     needed at all with SUBREG_BYTE.  If you need this
- 		     code back, please explain to me why so I can
- 		     fix the real problem.  -DaveM */
- #if 0
- 		  /* Subreg of a hard reg which can't handle the subreg's mode
- 		     or which would handle that mode in the wrong number of
- 		     registers for subregging to work.  */
- 		  || (GET_CODE (operand) == REG
- 		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
- 		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
- 			   && (GET_MODE_SIZE (GET_MODE (operand))
- 			       > UNITS_PER_WORD)
- 			   && ((GET_MODE_SIZE (GET_MODE (operand))
- 				/ UNITS_PER_WORD)
- 			       != HARD_REGNO_NREGS (REGNO (operand),
- 						    GET_MODE (operand))))
- 			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
- 						   operand_mode[i])))
- #endif
  		  )
  		force_reload = 1;
  	    }
--- 2937,2942 ----
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.375.2.4
diff -c -3 -p -r1.375.2.4 rtl.h
*** rtl.h	24 Mar 2003 17:59:36 -0000	1.375.2.4
--- rtl.h	12 Apr 2003 14:46:28 -0000
*************** extern unsigned int subreg_regno_offset 
*** 1033,1038 ****
--- 1033,1042 ----
  							 enum machine_mode, 
  							 unsigned int, 
  							 enum machine_mode));
+ extern bool subreg_representable_p 	PARAMS ((unsigned int, 
+ 							 enum machine_mode, 
+ 							 unsigned int, 
+ 							 enum machine_mode));
  extern unsigned int subreg_regno 	PARAMS ((rtx));
  
  /* 1 if RTX is a subreg containing a reg that is already known to be
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.140.4.2
diff -c -3 -p -r1.140.4.2 rtlanal.c
*** rtlanal.c	11 Feb 2003 20:47:56 -0000	1.140.4.2
--- rtlanal.c	12 Apr 2003 14:46:28 -0000
*************** subreg_regno_offset (xregno, xmode, offs
*** 3159,3164 ****
--- 3159,3225 ----
    return (y_offset / (mode_multiple / nregs_multiple)) * nregs_ymode;
  }
  
+ /* This function returns true when the offset is representable via
+    subreg_offset in the given regno.
+    xregno - A regno of an inner hard subreg_reg (or what will become one).
+    xmode  - The mode of xregno.
+    offset - The byte offset.
+    ymode  - The mode of a top level SUBREG (or what may become one).  */
+ bool
+ subreg_offset_representable_p (xregno, xmode, offset, ymode)
+      unsigned int xregno;
+      enum machine_mode xmode;
+      unsigned int offset;
+      enum machine_mode ymode;
+ {
+   int nregs_xmode, nregs_ymode;
+   int mode_multiple, nregs_multiple;
+   int y_offset;
+ 
+   if (xregno >= FIRST_PSEUDO_REGISTER)
+     abort ();
+ 
+   nregs_xmode = HARD_REGNO_NREGS (xregno, xmode);
+   nregs_ymode = HARD_REGNO_NREGS (xregno, ymode);
+ 
+   /* Lowpart subregs (including paradoxical) are always valid.  */
+   if (offset == subreg_lowpart_offset (ymode, xmode))
+     return true;
+ 
+ #ifdef ENABLE_CHECKING
+   /* This should always pass, otherwise we don't know how to verify the
+      constraint. 
+ 
+      These conditions may be relaxed but subreg_offset would need to be
+      redesigned.  */
+   if (GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)
+       || GET_MODE_SIZE (ymode) % nregs_ymode
+       || mode_for_size (GET_MODE_SIZE (ymode) / nregs_ymode,
+ 	      		MODE_INT, 0) == VOIDmode
+       || nregs_xmode % nregs_ymode)
+     abort ();
+ #endif
+ 
+   /* The XMODE value can be seen as an vector of NREGS_XMODE
+      values.  The subreg must represent an lowpart of given field.
+      Compute what field it is.  */
+   offset -= subreg_lowpart_offset (mode_for_size (GET_MODE_SIZE (ymode)
+ 			  			  / nregs_ymode,
+ 						  MODE_INT, 0), xmode);
+ 
+   /* size of ymode must not be greater than the size of xmode.  */
+   mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
+ 
+   y_offset = offset / GET_MODE_SIZE (ymode);
+   nregs_multiple =  nregs_xmode / nregs_ymode;
+ #ifdef ENABLE_CHECKING
+   if (offset % GET_MODE_SIZE (ymode)
+       || mode_multiple % nregs_multiple)
+     abort ();
+ #endif
+   return (!(y_offset % (mode_multiple / nregs_multiple)));
+ }
+ 
  /* Return the final regno that a subreg expression refers to.  */
  unsigned int
  subreg_regno (x)

  parent reply	other threads:[~2003-04-12 14:52 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-04-08 18:52 Reload bug Eric Botcazou
2003-04-08 23:16 ` Jan Hubicka
2003-04-09  0:44   ` Jan Hubicka
2003-04-09  7:00     ` Eric Botcazou
2003-04-09  3:00   ` Eric Botcazou
2003-04-09  9:49     ` Jan Hubicka
2003-04-09  8:57   ` Eric Botcazou
2003-04-09  9:45     ` Jan Hubicka
2003-04-09  9:50       ` Eric Botcazou
2003-04-09 14:52         ` Jan Hubicka
2003-04-09 18:10           ` Eric Botcazou
2003-04-09 19:15             ` Jan Hubicka
2003-04-10 14:25           ` Eric Botcazou
2003-04-10 16:31             ` Jan Hubicka
2003-04-10 16:35               ` Jan Hubicka
2003-04-10 20:21             ` Eric Botcazou
2003-04-10 20:43               ` Jan Hubicka
2003-04-11 14:44                 ` Eric Botcazou
2003-04-11 17:49                   ` Jan Hubicka
2003-04-11 18:09                   ` Jan Hubicka
2003-04-11 19:01                   ` Jan Hubicka
2003-04-11 19:07                   ` Jan Hubicka
2003-04-12 14:55                     ` Eric Botcazou
2003-04-12 17:45                       ` Jan Hubicka
2003-04-13 19:57                         ` Eric Botcazou
2003-04-13 20:04                           ` Jan Hubicka
2003-04-12 17:55                       ` Jan Hubicka [this message]
2003-04-17 22:32                         ` Make reload to avoid invalid subregs Richard Henderson
2003-04-10 20:51               ` Reload bug Dale Johannesen
2003-04-09  9:13 ` Eric Botcazou
2003-04-09 11:25   ` Jan Hubicka
2003-04-09 12:04     ` Eric Botcazou
2003-04-09 18:05       ` Jan Hubicka
2003-04-09 18:26         ` Eric Botcazou
2003-04-09 21:23         ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030412145257.GF31150@kam.mff.cuni.cz \
    --to=jh@suse.cz \
    --cc=ebotcazou@libertysurf.fr \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=rth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).