Proposed fix for unrrecognizable insn ICE

Geoff Keating geoffk@geoffk.org
Tue May 1 19:03:00 GMT 2001


> From: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
> Date: Wed, 2 May 2001 00:26:09 +0200

> On Tuesday 01 May 2001 00:22, Geoff Keating wrote:
> > > cc: Geoff Keating <geoffk@geoffk.org>
> > > Date: Mon, 30 Apr 2001 18:17:27 -0400
> > > From: David Edelsohn <dje@watson.ibm.com>
> > >
> > > 	The concept of the patch seems okay, but I don't understand enough
> > > about the implications of this type of change to feel comfortable
> > > approving it myself.
> >
> > I think that the patch is OK, but:
> >
> > - Franz, could you reduce the testcase down into something suitable
> >   for the testsuite?
> 
> Uh-Oh, this is already the cutdown version :-), it was a _lot_ bigger before. 
> I tried to construct a simple artificial testcase, but somehow my function 
> wasn't inliined for no obvious reason :-/. Basically all you should need is 
> >32KB stack usage in the inlined function and the use of truncdfsi2 (or 
> another function in the MD that uses assign_stack_temp).

Ugh.  Oh well.

> > - Could you split the convert-to-function change out?  I can approve
> >   that part immediately, and it'll make it easier to deal with
> >   the functional change.
> 
> Done. I append both patches to be applied in sequence.

OK.  The convert-to-function patch is approved.

After thinking about it, I think the actual change is OK too.  So
let's try it, too, on the mainline for a week or so and then on the
branch if no-one complains.

> > - I'd really like to test the actual functional change some more.
> 
> Sure, though I would suspect any breakage would show up with reload problems? 
> I couldn't convince myself that the restrictiion to stack offsets is 
> necessary though. Can we delay all offsets until reload? How would this 
> affect code quality and size? Code size seems to be a looser anyway with 3.0 
> AFAICT...

It's much better to have non-stack offsets split.  In fact, it'd
probably be better on average to have stack offsets split, since
most of the time they won't be reduced down to anything smaller.

> >   You ran the testsuite, right?
> 
> Yes, no regression caused by my patch on the mainline, though it's currently 
> a bit fishy on both mainline and branch, caused by Jeffs patch. Maybe you 
> should configure the regression tester to loop over the tests with -fpic and 
> -fPIC, this would have caught Jeffs breakage.
> 
> Apropos branch, any reason why you don't apply your PPC patches to the branch 
> too? The fast-math fix and the CTR insn length fixes  are still missing.

I have this disk-space problem with testing the branch.  If you'd like
to test them and commit them, please do.

> --------------Boundary-00=_LZGO9S4EE0KLEULK4XR5
> Content-Type: text/plain;
>   charset="iso-8859-1";
>   name="stack-offset-2.patch"
> Content-Transfer-Encoding: 8bit
> Content-Disposition: attachment; filename="stack-offset-2.patch"
> 
> 2000-05-01  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
> 
> 	* config/rs6000/rs6000.c (rs6000_legitimate_address): Allow any stack
> 	offsets if not REG_OK_STRICT.
> 
> --- gcc/config/rs6000/rs6000.c-1	Tue May  1 15:07:17 2001
> +++ gcc/config/rs6000/rs6000.c	Mon Apr 30 22:47:04 2001
> @@ -1570,6 +1570,13 @@ rs6000_legitimate_address (mode, x, reg_
>      return 1;
>    if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
>      return 1;
> +  /* If not REG_OK_STRICT (before reload) let pass any stack offset.  */
> +  if (! reg_ok_strict
> +      && GET_CODE (x) == PLUS
> +      && GET_CODE (XEXP (x, 0)) == REG
> +      && XEXP (x, 0) == virtual_stack_vars_rtx
> +      && GET_CODE (XEXP (x, 1)) == CONST_INT)
> +    return 1;
>    if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
>      return 1;
>    if (mode != TImode
> 
> --------------Boundary-00=_LZGO9S4EE0KLEULK4XR5
> Content-Type: text/plain;
>   charset="iso-8859-1";
>   name="stack-offset-1.patch"
> Content-Transfer-Encoding: 8bit
> Content-Disposition: attachment; filename="stack-offset-1.patch"
> 
> 2000-05-01  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
> 
> 	* config/rs6000/rs6000.h (REG_OK_STRICT_FLAG): New macro.
> 	(INT_REG_OK_FOR_INDEX_P): Likewise.
> 	(INT_REG_OK_FOR_BASE_P): Likewise.
> 	(REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P.
> 	(REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P.
> 	(LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and
> 	INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
> 	REG_OK_FOR_BASE_P. Take an additional parameter.
> 	(LEGITIMATE_INDEXED_ADDRESS_P): Likeewise.
> 	(LEGITIMATE_INDIRECT_ADDRESS_P): Likewise.
> 	(LEGITIMATE_LO_SUM_ADDRESS_P): Likewise.
> 	(GO_IF_LEGITIMATE_ADDRESS): Move code into new function
> 	rs6000_legitimate_address() and use it.
> 	* config/rs6000/rs6000.c: Update all callers.
> 	(rs6000_legitimate_address): New function.
> 
> 
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
> retrieving revision 1.167
> diff -u -p -r1.167 rs6000.c
> --- gcc/config/rs6000/rs6000.c	2001/02/09 03:15:56	1.167
> +++ gcc/config/rs6000/rs6000.c	2001/05/01 13:06:35
> @@ -1535,6 +1536,51 @@ rs6000_legitimize_address (x, oldx, mode
>    else
>      return NULL_RTX;
>  }
> +
> +/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
> +   that is a valid memory address for an instruction.
> +   The MODE argument is the machine mode for the MEM expression
> +   that wants to use this address.
> +
> +   On the RS/6000, there are four valid address: a SYMBOL_REF that
> +   refers to a constant pool entry of an address (or the sum of it
> +   plus a constant), a short (16-bit signed) constant plus a register,
> +   the sum of two registers, or a register indirect, possibly with an
> +   auto-increment.  For DFmode and DImode with an constant plus register,
> +   we must ensure that both words are addressable or PowerPC64 with offset
> +   word aligned.
> +
> +   For modes spanning multiple registers (DFmode in 32-bit GPRs,
> +   32-bit DImode, TImode), indexed addressing cannot be used because
> +   adjacent memory cells are accessed by adding word-sized offsets
> +   during assembly output.  */
> +int
> +rs6000_legitimate_address (mode, x, reg_ok_strict)
> +    enum machine_mode mode;
> +    rtx x;
> +    int reg_ok_strict;
> +{
> +  if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
> +    return 1;
> +  if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
> +      && TARGET_UPDATE
> +      && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
> +    return 1;
> +  if (LEGITIMATE_SMALL_DATA_P (mode, x))
> +    return 1;
> +  if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
> +    return 1;
> +  if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
> +    return 1;
> +  if (mode != TImode
> +      && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
> +      && (TARGET_POWERPC64 || mode != DImode)
> +      && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
> +    return 1;
> +  if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
> +    return 1;
> +  return 0;
> +}
>  
>  /* Emit a move from SOURCE to DEST in mode MODE.  */
>  void
> @@ -3080,14 +3126,14 @@ lmw_operation (op, mode)
>        || count != 32 - (int) dest_regno)
>      return 0;
>  
> -  if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr))
> +  if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
>      {
>        offset = 0;
>        base_regno = REGNO (src_addr);
>        if (base_regno == 0)
>  	return 0;
>      }
> -  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr))
> +  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
>      {
>        offset = INTVAL (XEXP (src_addr, 1));
>        base_regno = REGNO (XEXP (src_addr, 0));
> @@ -3110,12 +3156,12 @@ lmw_operation (op, mode)
>  	  || GET_MODE (SET_SRC (elt)) != SImode)
>  	return 0;
>        newaddr = XEXP (SET_SRC (elt), 0);
> -      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
> +      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
>  	{
>  	  newoffset = 0;
>  	  addr_reg = newaddr;
>  	}
> -      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
> +      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
>  	{
>  	  addr_reg = XEXP (newaddr, 0);
>  	  newoffset = INTVAL (XEXP (newaddr, 1));
> @@ -3158,14 +3204,14 @@ stmw_operation (op, mode)
>        || count != 32 - (int) src_regno)
>      return 0;
>  
> -  if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr))
> +  if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
>      {
>        offset = 0;
>        base_regno = REGNO (dest_addr);
>        if (base_regno == 0)
>  	return 0;
>      }
> -  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr))
> +  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
>      {
>        offset = INTVAL (XEXP (dest_addr, 1));
>        base_regno = REGNO (XEXP (dest_addr, 0));
> @@ -3188,12 +3234,12 @@ stmw_operation (op, mode)
>  	  || GET_MODE (SET_DEST (elt)) != SImode)
>  	return 0;
>        newaddr = XEXP (SET_DEST (elt), 0);
> -      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
> +      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
>  	{
>  	  newoffset = 0;
>  	  addr_reg = newaddr;
>  	}
> -      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
> +      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
>  	{
>  	  addr_reg = XEXP (newaddr, 0);
>  	  newoffset = INTVAL (XEXP (newaddr, 1));
> @@ -4250,7 +4297,7 @@ print_operand (file, x, code)
>  
>      case 'X':
>        if (GET_CODE (x) == MEM
> -	  && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
> +	  && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
>  	putc ('x', file);
>        return;
>  
> Index: gcc/config/rs6000/rs6000.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
> retrieving revision 1.105
> diff -u -p -r1.105 rs6000.h
> --- gcc/config/rs6000/rs6000.h	2001/02/08 20:30:16	1.105
> +++ gcc/config/rs6000/rs6000.h	2001/05/01 13:06:38
> @@ -1772,26 +1772,28 @@ typedef struct rs6000_args
>     After reload, it makes no difference, since pseudo regs have
>     been eliminated by then.  */
>  
> -#ifndef REG_OK_STRICT
> +#ifdef REG_OK_STRICT
> +# define REG_OK_STRICT_FLAG 1
> +#else
> +# define REG_OK_STRICT_FLAG 0
> +#endif
>  
>  /* Nonzero if X is a hard reg that can be used as an index
> -   or if it is a pseudo reg.  */
> -#define REG_OK_FOR_INDEX_P(X)			\
> -  (REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
> +   or if it is a pseudo reg in the non-strict case.  */
> +#define INT_REG_OK_FOR_INDEX_P(X, STRICT)			\
> +  ((! (STRICT)							\
> +    && (REGNO (X) <= 31						\
> +	|| REGNO (X) == ARG_POINTER_REGNUM			\
> +	|| REGNO (X) >= FIRST_PSEUDO_REGISTER))			\
> +   || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
>  
>  /* Nonzero if X is a hard reg that can be used as a base reg
> -   or if it is a pseudo reg.  */
> -#define REG_OK_FOR_BASE_P(X)					 \
> -  (REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X))
> -
> -#else
> -
> -/* Nonzero if X is a hard reg that can be used as an index.  */
> -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
> -/* Nonzero if X is a hard reg that can be used as a base reg.  */
> -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
> +   or if it is a pseudo reg in the non-strict case.  */
> +#define INT_REG_OK_FOR_BASE_P(X, STRICT)			\
> +  (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
>  
> -#endif
> +#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
> +#define REG_OK_FOR_BASE_P(X)  INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
>  
>  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
>     that is a valid memory address for an instruction.
> @@ -1828,68 +1830,51 @@ typedef struct rs6000_args
>     && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST)		\
>     && small_data_operand (X, MODE))
>  
> -#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET)				\
> +#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET)				\
>   (GET_CODE (X) == CONST_INT						\
>    && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
>  
> -#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X)		\
> - (GET_CODE (X) == PLUS					\
> -  && GET_CODE (XEXP (X, 0)) == REG			\
> -  && REG_OK_FOR_BASE_P (XEXP (X, 0))			\
> -  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)	\
> -  && (((MODE) != DFmode && (MODE) != DImode)		\
> -      || (TARGET_32BIT					\
> -	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
> -	  : ! (INTVAL (XEXP (X, 1)) & 3)))		\
> -  && ((MODE) != TImode					\
> -      || (TARGET_32BIT					\
> -	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
> -	  : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
> +#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT)		\
> + (GET_CODE (X) == PLUS						\
> +  && GET_CODE (XEXP (X, 0)) == REG				\
> +  && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
> +  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
> +  && (((MODE) != DFmode && (MODE) != DImode)			\
> +      || (TARGET_32BIT						\
> +	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
> +	  : ! (INTVAL (XEXP (X, 1)) & 3)))			\
> +  && ((MODE) != TImode						\
> +      || (TARGET_32BIT						\
> +	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) 	\
> +	  : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) 	\
>  	     && ! (INTVAL (XEXP (X, 1)) & 3)))))
>  
> -#define LEGITIMATE_INDEXED_ADDRESS_P(X)		\
> - (GET_CODE (X) == PLUS				\
> -  && GET_CODE (XEXP (X, 0)) == REG		\
> -  && GET_CODE (XEXP (X, 1)) == REG		\
> -  && ((REG_OK_FOR_BASE_P (XEXP (X, 0))		\
> -       && REG_OK_FOR_INDEX_P (XEXP (X, 1)))	\
> -      || (REG_OK_FOR_BASE_P (XEXP (X, 1))	\
> -	  && REG_OK_FOR_INDEX_P (XEXP (X, 0)))))
> -
> -#define LEGITIMATE_INDIRECT_ADDRESS_P(X)	\
> -  (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
> -
> -#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X)		\
> -  (TARGET_ELF						\
> -   && ! flag_pic && ! TARGET_TOC			\
> -   && (MODE) != DImode					\
> -   && (MODE) != TImode					\
> -   && (TARGET_HARD_FLOAT || (MODE) != DFmode)		\
> -   && GET_CODE (X) == LO_SUM				\
> -   && GET_CODE (XEXP (X, 0)) == REG			\
> -   && REG_OK_FOR_BASE_P (XEXP (X, 0))			\
> +#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT)			\
> + (GET_CODE (X) == PLUS						\
> +  && GET_CODE (XEXP (X, 0)) == REG				\
> +  && GET_CODE (XEXP (X, 1)) == REG				\
> +  && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
> +       && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)))	\
> +      || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT))		\
> +	  && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
> +
> +#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT)		\
> +  (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
> +
> +#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT)		\
> +  (TARGET_ELF							\
> +   && ! flag_pic && ! TARGET_TOC				\
> +   && (MODE) != DImode						\
> +   && (MODE) != TImode						\
> +   && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
> +   && GET_CODE (X) == LO_SUM					\
> +   && GET_CODE (XEXP (X, 0)) == REG				\
> +   && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
>     && CONSTANT_P (XEXP (X, 1)))
>  
> -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)		\
> -{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X))		\
> -    goto ADDR;						\
> -  if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
> -      && TARGET_UPDATE					\
> -      && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0)))	\
> -    goto ADDR;						\
> -  if (LEGITIMATE_SMALL_DATA_P (MODE, X))		\
> -    goto ADDR;						\
> -  if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X))		\
> -    goto ADDR;						\
> -  if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X))		\
> -    goto ADDR;						\
> -  if ((MODE) != TImode					\
> -      && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
> -      && (TARGET_POWERPC64 || (MODE) != DImode)		\
> -      && LEGITIMATE_INDEXED_ADDRESS_P (X))		\
> -    goto ADDR;						\
> -  if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X))		\
> -    goto ADDR;						\
> +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)			\
> +{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG))	\
> +    goto ADDR;							\
>  }
>  
>  /* Try machine-dependent ways of modifying an illegitimate address
> Index: gcc/config/rs6000/rs6000-protos.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
> retrieving revision 1.16
> diff -u -p -r1.16 rs6000-protos.h
> --- gcc/config/rs6000/rs6000-protos.h	2001/02/06 19:04:01	1.16
> +++ gcc/config/rs6000/rs6000-protos.h	2001/05/01 13:06:38
> @@ -107,6 +107,7 @@ extern struct rtx_def *create_TOC_refere
>  extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
>  extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
>  extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
> +extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
>  extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
>  extern rtx rs6000_return_addr PARAMS ((int, rtx));
>  extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
> 
> --------------Boundary-00=_LZGO9S4EE0KLEULK4XR5--
> 


-- 
- Geoffrey Keating <geoffk@geoffk.org>



More information about the Gcc-patches mailing list