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]

proposed patch for SH port


This is a patch I wrote while at Red Hat, and forgot to submit for some
unknown reason.  I no longer have access to the testcase.

This fixes an ICE in subreg_regno_offset.  subreg_regno_offset is called
for xregno=143 (an XD register) with ymode=SImode.  HARD_REGNO_NREGS returns
zero, and we get a divide-by-zero exception.

We got here from reload.  Reload calls find_equiv_reg to try to determine if
a register contains a particular value, const0_rtx.  Inside find_equiv_reg,
there are checks to see if FP registers holding a known CONST_DOUBLE value
have one half equivalent to the CONST_INT value we are looking for.  This
code does
                      && (valtry
                          = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
                      && (valueno = true_regnum (valtry)) >= 0)))
SET_DEST (pat) is (reg:DF 143 xd14).  operand_subword just returns the subreg
that was requested without checking to see if it is valid rtx.  Then we call
true_regnum, which calls subreg_regno_offset, which does the divide by zero.
The check for valid rtx happens later, where we check to see if we got the
right register number, or if the register is valid for the right class.  So
HARD_REGNO_NREGS must return a usable register count, even if passed invalid
rtx.

The testcase for this is unfortunately proprietary code, and I've had no luck
so far extracting a small example from the testcase I have, since whether we
reach here depends on complex interactions inside reload.  I haven't tried
looking in the GNATS database.

This fix seems pretty obviously correct to me, but I haven't done a testsuite
run to check for problems.
	
This problem was discovered with an sh64-elf toolchain using the -m5-compact
option.

2002-11-08  Jim Wilson  <wilson at redhat dot com>

	* config/sh/sh.h (HARD_REGNO_NREGS): Round up the XD register count.

Index: sh.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/sh/sh.h,v
retrieving revision 1.308.2.2
diff -p -r1.308.2.2 sh.h
*** sh.h	2002/10/13 22:00:35	1.308.2.2
--- sh.h	2002/11/08 01:00:46
*************** extern char sh_additional_register_names
*** 891,900 ****
  
  #define HARD_REGNO_NREGS(REGNO, MODE) \
     (XD_REGISTER_P (REGNO) \
!     ? (GET_MODE_SIZE (MODE) / (2 * UNITS_PER_WORD)) \
      : (TARGET_SHMEDIA && FP_REGISTER_P (REGNO)) \
      ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD/2 - 1) / (UNITS_PER_WORD/2)) \
!     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) \
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     We can allow any mode in any general register.  The special registers
--- 891,900 ----
  
  #define HARD_REGNO_NREGS(REGNO, MODE) \
     (XD_REGISTER_P (REGNO) \
!     ? ((GET_MODE_SIZE (MODE) + (2*UNITS_PER_WORD - 1)) / (2*UNITS_PER_WORD)) \
      : (TARGET_SHMEDIA && FP_REGISTER_P (REGNO)) \
      ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD/2 - 1) / (UNITS_PER_WORD/2)) \
!     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     We can allow any mode in any general register.  The special registers




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